summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/android_builds.yml2
-rw-r--r--.github/workflows/godot_cpp_test.yml4
-rw-r--r--.github/workflows/ios_builds.yml2
-rw-r--r--.github/workflows/linux_builds.yml4
-rw-r--r--.github/workflows/macos_builds.yml2
-rw-r--r--.github/workflows/static_checks.yml2
-rw-r--r--.github/workflows/web_builds.yml6
-rw-r--r--.github/workflows/windows_builds.yml2
-rw-r--r--SConstruct2
-rw-r--r--core/debugger/engine_profiler.h4
-rw-r--r--core/extension/gdextension_interface.cpp1
-rw-r--r--core/extension/gdextension_interface.h2
-rw-r--r--core/extension/gdextension_manager.cpp2
-rw-r--r--core/input/godotcontrollerdb.txt3
-rw-r--r--core/input/input_builders.py1
-rw-r--r--core/io/packet_peer.h1
-rw-r--r--core/io/resource_format_binary.cpp1
-rw-r--r--core/io/resource_loader.cpp1
-rw-r--r--core/io/resource_loader.h1
-rw-r--r--core/io/resource_saver.h1
-rw-r--r--core/io/stream_peer.h1
-rw-r--r--core/math/a_star.h1
-rw-r--r--core/math/a_star_grid_2d.h1
-rw-r--r--core/object/make_virtuals.py2
-rw-r--r--core/object/script_instance.cpp (renamed from platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java)67
-rw-r--r--core/object/script_instance.h98
-rw-r--r--core/object/script_language.cpp36
-rw-r--r--core/object/script_language.h61
-rw-r--r--core/object/script_language_extension.h19
-rw-r--r--core/os/main_loop.h1
-rw-r--r--core/os/os.h4
-rw-r--r--core/string/translation.h1
-rw-r--r--core/string/ustring.cpp10
-rw-r--r--core/variant/variant_parser.cpp1
-rw-r--r--doc/classes/BaseMaterial3D.xml8
-rw-r--r--doc/classes/DisplayServer.xml2
-rw-r--r--doc/classes/EditorExportPlatform.xml8
-rw-r--r--doc/classes/EditorPlugin.xml5
-rw-r--r--doc/classes/EditorResourceTooltipPlugin.xml2
-rw-r--r--doc/classes/GraphEdit.xml18
-rw-r--r--doc/classes/GraphElement.xml69
-rw-r--r--doc/classes/GraphNode.xml251
-rw-r--r--doc/classes/Input.xml4
-rw-r--r--doc/classes/OS.xml10
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/Resource.xml16
-rw-r--r--doc/classes/SpringArm3D.xml2
-rw-r--r--doc/classes/TileMap.xml35
-rw-r--r--doc/classes/ViewportTexture.xml2
-rw-r--r--doc/translations/es.po11
-rw-r--r--doc/translations/fr.po12
-rw-r--r--doc/translations/zh_CN.po8719
-rw-r--r--drivers/gl_context/SCsub2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/scene.glsl9
-rw-r--r--drivers/gles3/storage/material_storage.cpp1
-rw-r--r--drivers/unix/ip_unix.cpp65
-rw-r--r--drivers/windows/dir_access_windows.cpp26
-rw-r--r--editor/action_map_editor.cpp31
-rw-r--r--editor/animation_bezier_editor.cpp51
-rw-r--r--editor/animation_track_editor.cpp185
-rw-r--r--editor/animation_track_editor_plugins.cpp31
-rw-r--r--editor/code_editor.cpp77
-rw-r--r--editor/connections_dialog.cpp63
-rw-r--r--editor/create_dialog.cpp17
-rw-r--r--editor/debugger/editor_debugger_node.cpp25
-rw-r--r--editor/debugger/editor_debugger_node.h1
-rw-r--r--editor/debugger/editor_debugger_tree.cpp8
-rw-r--r--editor/debugger/editor_performance_profiler.cpp7
-rw-r--r--editor/debugger/editor_profiler.cpp15
-rw-r--r--editor/debugger/editor_visual_profiler.cpp25
-rw-r--r--editor/debugger/script_editor_debugger.cpp69
-rw-r--r--editor/debugger/script_editor_debugger.h1
-rw-r--r--editor/dependency_editor.cpp12
-rw-r--r--editor/directory_create_dialog.cpp13
-rw-r--r--editor/editor_about.cpp7
-rw-r--r--editor/editor_asset_installer.cpp87
-rw-r--r--editor/editor_audio_buses.cpp19
-rw-r--r--editor/editor_autoload_settings.cpp15
-rw-r--r--editor/editor_build_profile.cpp3
-rw-r--r--editor/editor_command_palette.cpp9
-rw-r--r--editor/editor_feature_profile.cpp3
-rw-r--r--editor/editor_fonts.cpp81
-rw-r--r--editor/editor_help.cpp122
-rw-r--r--editor/editor_help.h15
-rw-r--r--editor/editor_help_search.cpp23
-rw-r--r--editor/editor_inspector.cpp136
-rw-r--r--editor/editor_log.cpp43
-rw-r--r--editor/editor_node.cpp325
-rw-r--r--editor/editor_node.h5
-rw-r--r--editor/editor_plugin_settings.cpp4
-rw-r--r--editor/editor_properties.cpp73
-rw-r--r--editor/editor_properties_array_dict.cpp35
-rw-r--r--editor/editor_properties_vector.cpp4
-rw-r--r--editor/editor_property_name_processor.cpp1
-rw-r--r--editor/editor_quick_open.cpp2
-rw-r--r--editor/editor_resource_picker.cpp41
-rw-r--r--editor/editor_resource_preview.cpp4
-rw-r--r--editor/editor_run_native.cpp2
-rw-r--r--editor/editor_script.cpp1
-rw-r--r--editor/editor_script.h2
-rw-r--r--editor/editor_sectioned_inspector.cpp5
-rw-r--r--editor/editor_settings_dialog.cpp33
-rw-r--r--editor/editor_string_names.cpp (renamed from modules/freetype/uwpdef.h)16
-rw-r--r--editor/editor_string_names.h (renamed from platform/uwp/export/export.h)33
-rw-r--r--editor/editor_themes.cpp530
-rw-r--r--editor/editor_translation_parser.h1
-rw-r--r--editor/editor_vcs_interface.h2
-rw-r--r--editor/event_listener_line_edit.cpp2
-rw-r--r--editor/export/editor_export_platform.cpp25
-rw-r--r--editor/export/editor_export_platform.h3
-rw-r--r--editor/export/export_template_manager.cpp15
-rw-r--r--editor/export/project_export.cpp21
-rw-r--r--editor/fbx_importer_manager.cpp5
-rw-r--r--editor/filesystem_dock.cpp177
-rw-r--r--editor/find_in_files.cpp13
-rw-r--r--editor/groups_editor.cpp23
-rw-r--r--editor/gui/editor_dir_dialog.cpp2
-rw-r--r--editor/gui/editor_file_dialog.cpp60
-rw-r--r--editor/gui/editor_object_selector.cpp5
-rw-r--r--editor/gui/editor_run_bar.cpp31
-rw-r--r--editor/gui/editor_scene_tabs.cpp7
-rw-r--r--editor/gui/editor_toaster.cpp41
-rw-r--r--editor/gui/editor_validation_panel.cpp7
-rw-r--r--editor/gui/editor_zoom_widget.cpp4
-rw-r--r--editor/gui/scene_tree_editor.cpp74
-rw-r--r--editor/history_dock.cpp3
-rw-r--r--editor/icons/GraphEdit.svg2
-rw-r--r--editor/icons/GraphElement.svg1
-rw-r--r--editor/icons/GraphNode.svg2
-rw-r--r--editor/icons/GuiCloseCustomizable.svg1
-rw-r--r--editor/import/audio_stream_import_settings.cpp57
-rw-r--r--editor/import/dynamic_font_import_settings.cpp23
-rw-r--r--editor/import/resource_importer_scene.cpp1
-rw-r--r--editor/import/scene_import_settings.cpp65
-rw-r--r--editor/import_dock.cpp5
-rw-r--r--editor/input_event_configuration_dialog.cpp19
-rw-r--r--editor/inspector_dock.cpp49
-rw-r--r--editor/localization_editor.cpp8
-rw-r--r--editor/node_dock.cpp4
-rw-r--r--editor/plugin_config_dialog.cpp1
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp17
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp31
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp37
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp37
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h5
-rw-r--r--editor/plugins/animation_library_editor.cpp27
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp26
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp47
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp21
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp25
-rw-r--r--editor/plugins/bone_map_editor_plugin.cpp20
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp179
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h16
-rw-r--r--editor/plugins/cast_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/control_editor_plugin.cpp70
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp35
-rw-r--r--editor/plugins/editor_preview_plugins.cpp1
-rw-r--r--editor/plugins/editor_resource_conversion_plugin.h1
-rw-r--r--editor/plugins/editor_resource_tooltip_plugins.h1
-rw-r--r--editor/plugins/font_config_plugin.cpp10
-rw-r--r--editor/plugins/gdextension_export_plugin.h9
-rw-r--r--editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/light_3d_gizmo_plugin.cpp6
-rw-r--r--editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp7
-rw-r--r--editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp2
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp2
-rw-r--r--editor/plugins/gradient_editor.cpp7
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp4
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.cpp10
-rw-r--r--editor/plugins/input_event_editor_plugin.cpp2
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp2
-rw-r--r--editor/plugins/material_editor_plugin.cpp10
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp4
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp7
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/navigation_link_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/navigation_obstacle_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp149
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/packed_scene_editor_plugin.cpp2
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.cpp1
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp18
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp14
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp36
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp8
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp47
-rw-r--r--editor/plugins/script_editor_plugin.h1
-rw-r--r--editor/plugins/script_text_editor.cpp35
-rw-r--r--editor/plugins/shader_editor_plugin.cpp7
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp13
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp29
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp10
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp67
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp6
-rw-r--r--editor/plugins/text_shader_editor.cpp22
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp5
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp19
-rw-r--r--editor/plugins/theme_editor_plugin.cpp211
-rw-r--r--editor/plugins/theme_editor_preview.cpp24
-rw-r--r--editor/plugins/theme_editor_preview.h1
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp4
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp79
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp60
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp29
-rw-r--r--editor/plugins/tiles/tile_set_editor.cpp12
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp6
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp2
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp79
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp558
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h22
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp75
-rw-r--r--editor/project_settings_editor.cpp13
-rw-r--r--editor/property_selector.cpp80
-rw-r--r--editor/register_editor_types.cpp4
-rw-r--r--editor/rename_dialog.cpp9
-rw-r--r--editor/scene_create_dialog.cpp17
-rw-r--r--editor/scene_tree_dock.cpp103
-rw-r--r--editor/script_create_dialog.cpp18
-rw-r--r--editor/shader_create_dialog.cpp8
-rw-r--r--editor/translations/editor/ar.po8
-rw-r--r--editor/translations/editor/ca.po25
-rw-r--r--editor/translations/editor/de.po72
-rw-r--r--editor/translations/editor/es.po64
-rw-r--r--editor/translations/editor/fa.po58
-rw-r--r--editor/translations/editor/fr.po187
-rw-r--r--editor/translations/editor/id.po284
-rw-r--r--editor/translations/editor/it.po148
-rw-r--r--editor/translations/editor/ko.po395
-rw-r--r--editor/translations/editor/pl.po59
-rw-r--r--editor/translations/editor/pt_BR.po435
-rw-r--r--editor/translations/editor/ru.po249
-rw-r--r--editor/translations/editor/sv.po194
-rw-r--r--editor/translations/editor/tr.po97
-rw-r--r--editor/translations/editor/vi.po29
-rw-r--r--editor/translations/editor/zh_CN.po65
-rw-r--r--editor/translations/properties/de.po27
-rw-r--r--editor/translations/properties/fr.po9
-rw-r--r--editor/translations/properties/id.po1052
-rw-r--r--editor/translations/properties/ko.po16
-rw-r--r--editor/translations/properties/pt_BR.po430
-rw-r--r--editor/translations/properties/ru.po187
-rw-r--r--editor/translations/properties/tr.po26
-rw-r--r--editor/translations/properties/zh_CN.po9
-rw-r--r--editor/window_wrapper.cpp9
-rw-r--r--main/main.cpp24
-rw-r--r--methods.py35
-rw-r--r--misc/dist/uwp_template/AppxManifest.xml32
-rw-r--r--misc/dist/uwp_template/Assets/SplashScreen.scale-100.pngbin10010 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.pngbin3124 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.pngbin8939 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.pngbin848 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.pngbin1168 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/StoreLogo.scale-100.pngbin883 -> 0 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.pngbin3471 -> 0 bytes
-rw-r--r--misc/extension_api_validation/4.1-stable.expected60
-rwxr-xr-xmisc/scripts/validate_extension_api.sh2
-rw-r--r--modules/freetype/SCsub6
-rw-r--r--modules/gdscript/gdscript_rpc_callable.cpp1
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp5
-rw-r--r--modules/gltf/gltf_document.cpp6
-rw-r--r--modules/gridmap/editor/grid_map_editor_plugin.cpp9
-rw-r--r--modules/mono/build_scripts/mono_configure.py4
-rw-r--r--modules/mono/config.py4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs19
-rw-r--r--modules/mono/editor/code_completion.cpp1
-rw-r--r--modules/mono/editor/hostfxr_resolver.cpp2
-rw-r--r--modules/mono/godotsharp_dirs.cpp2
-rw-r--r--modules/multiplayer/editor/editor_network_profiler.cpp23
-rw-r--r--modules/multiplayer/editor/replication_editor.cpp15
-rw-r--r--modules/multiplayer/scene_cache_interface.h1
-rw-r--r--modules/navigation/editor/navigation_mesh_editor_plugin.cpp5
-rw-r--r--modules/navigation/godot_navigation_server.h4
-rw-r--r--modules/openxr/doc_classes/OpenXRInterface.xml153
-rw-r--r--modules/openxr/editor/openxr_action_editor.cpp4
-rw-r--r--modules/openxr/editor/openxr_action_set_editor.cpp9
-rw-r--r--modules/openxr/editor/openxr_interaction_profile_editor.cpp5
-rw-r--r--modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp2
-rw-r--r--modules/openxr/extensions/openxr_hand_tracking_extension.cpp59
-rw-r--r--modules/openxr/extensions/openxr_hand_tracking_extension.h8
-rw-r--r--modules/openxr/openxr_api.cpp19
-rw-r--r--modules/openxr/openxr_interface.cpp139
-rw-r--r--modules/openxr/openxr_interface.h57
-rw-r--r--modules/openxr/scene/openxr_hand.cpp4
-rw-r--r--modules/openxr/scene/openxr_hand.h4
-rw-r--r--modules/text_server_adv/text_server_adv.cpp11
-rw-r--r--modules/text_server_fb/text_server_fb.cpp4
-rw-r--r--modules/webrtc/webrtc_data_channel_extension.h1
-rw-r--r--modules/webrtc/webrtc_peer_connection_extension.h1
-rw-r--r--modules/websocket/SCsub2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.kt13
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java131
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java31
-rw-r--r--platform/android/java_godot_wrapper.cpp20
-rw-r--r--platform/android/java_godot_wrapper.h4
-rw-r--r--platform/android/os_android.cpp42
-rw-r--r--platform/android/os_android.h6
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp27
-rw-r--r--platform/android/plugin/godot_plugin_jni.h1
-rw-r--r--platform/ios/export/export_plugin.cpp7
-rw-r--r--platform/ios/export/export_plugin.h10
-rw-r--r--platform/linuxbsd/export/export_plugin.cpp3
-rw-r--r--platform/macos/export/export_plugin.cpp3
-rw-r--r--platform/macos/godot_content_view.h2
-rw-r--r--platform/macos/godot_content_view.mm9
-rw-r--r--platform/uwp/README.md20
-rw-r--r--platform/uwp/SCsub20
-rw-r--r--platform/uwp/app_uwp.cpp560
-rw-r--r--platform/uwp/app_uwp.h115
-rw-r--r--platform/uwp/context_egl_uwp.cpp212
-rw-r--r--platform/uwp/detect.py216
-rw-r--r--platform/uwp/export/app_packager.cpp465
-rw-r--r--platform/uwp/export/app_packager.h149
-rw-r--r--platform/uwp/export/export.cpp56
-rw-r--r--platform/uwp/export/export_plugin.cpp525
-rw-r--r--platform/uwp/export/export_plugin.h450
-rw-r--r--platform/uwp/export/logo.svg1
-rw-r--r--platform/uwp/joypad_uwp.cpp174
-rw-r--r--platform/uwp/joypad_uwp.h81
-rw-r--r--platform/uwp/os_uwp.cpp845
-rw-r--r--platform/uwp/os_uwp.h256
-rw-r--r--platform/uwp/platform_config.h31
-rw-r--r--platform/web/detect.py5
-rw-r--r--platform/web/export/export_plugin.cpp3
-rw-r--r--platform/web/export/export_plugin.h3
-rw-r--r--platform/web/js/libs/library_godot_javascript_singleton.js4
-rw-r--r--platform/windows/export/export_plugin.cpp3
-rw-r--r--platform/windows/windows_terminal_logger.cpp4
-rw-r--r--scene/2d/tile_map.compat.inc10
-rw-r--r--scene/2d/tile_map.cpp2090
-rw-r--r--scene/2d/tile_map.h316
-rw-r--r--scene/3d/label_3d.cpp45
-rw-r--r--scene/animation/animation_tree.cpp8
-rw-r--r--scene/animation/animation_tree.h5
-rw-r--r--scene/gui/button.cpp6
-rw-r--r--scene/gui/code_edit.h1
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/control.cpp18
-rw-r--r--scene/gui/control.h6
-rw-r--r--scene/gui/graph_edit.cpp304
-rw-r--r--scene/gui/graph_edit.h18
-rw-r--r--scene/gui/graph_edit_arranger.cpp12
-rw-r--r--scene/gui/graph_element.cpp244
-rw-r--r--scene/gui/graph_element.h (renamed from platform/uwp/context_egl_uwp.h)81
-rw-r--r--scene/gui/graph_node.cpp1119
-rw-r--r--scene/gui/graph_node.h181
-rw-r--r--scene/gui/item_list.cpp7
-rw-r--r--scene/gui/line_edit.cpp6
-rw-r--r--scene/gui/rich_text_effect.h1
-rw-r--r--scene/gui/text_edit.cpp6
-rw-r--r--scene/gui/texture_rect.cpp6
-rw-r--r--scene/main/multiplayer_peer.h1
-rw-r--r--scene/main/node.cpp1
-rw-r--r--scene/main/window.cpp19
-rw-r--r--scene/main/window.h6
-rw-r--r--scene/property_utils.cpp1
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/animation.cpp24
-rw-r--r--scene/resources/font.cpp128
-rw-r--r--scene/resources/material.cpp5
-rw-r--r--scene/resources/material.h1
-rw-r--r--scene/resources/packed_scene.cpp72
-rw-r--r--scene/resources/packed_scene.h1
-rw-r--r--scene/resources/primitive_meshes.cpp30
-rw-r--r--scene/resources/resource_format_text.cpp1
-rw-r--r--scene/resources/shader.cpp6
-rw-r--r--scene/resources/shader_include.cpp6
-rw-r--r--scene/resources/style_box.h1
-rw-r--r--scene/resources/syntax_highlighter.h1
-rw-r--r--scene/resources/theme.cpp6
-rw-r--r--scene/resources/tile_set.h1
-rw-r--r--scene/resources/visual_shader.cpp8
-rw-r--r--scene/resources/visual_shader.h4
-rw-r--r--scene/theme/default_theme.cpp51
-rw-r--r--scene/theme/theme_db.cpp248
-rw-r--r--scene/theme/theme_db.h61
-rw-r--r--scene/theme/theme_owner.cpp193
-rw-r--r--scene/theme/theme_owner.h11
-rw-r--r--scu_builders.py1
-rw-r--r--servers/audio/audio_effect.h1
-rw-r--r--servers/audio/audio_stream.h1
-rw-r--r--servers/extensions/physics_server_2d_extension.h1
-rw-r--r--servers/physics_server_3d.h1
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp18
-rw-r--r--servers/rendering/renderer_rd/effects/debug_effects.cpp20
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp1
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp18
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp18
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl10
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl10
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp18
-rw-r--r--servers/rendering/rendering_device_binds.h2
-rw-r--r--servers/rendering/shader_preprocessor.h1
-rw-r--r--servers/rendering/shader_types.cpp1
-rw-r--r--servers/text/text_server_extension.h1
-rw-r--r--tests/core/string/test_string.h16
-rw-r--r--tests/core/variant/test_dictionary.h2
-rw-r--r--tests/scene/test_arraymesh.h2
-rw-r--r--tests/scene/test_code_edit.h38
-rw-r--r--tests/scene/test_viewport.h16
-rw-r--r--tests/scene/test_window.h6
-rw-r--r--tests/servers/rendering/test_shader_preprocessor.h4
-rw-r--r--tests/servers/test_text_server.h6
-rw-r--r--tests/test_main.cpp19
-rw-r--r--thirdparty/README.md72
-rw-r--r--thirdparty/fonts/JetBrainsMono_Regular.woff2bin69168 -> 92392 bytes
-rw-r--r--thirdparty/fonts/NotoNaskhArabicUI_Bold.woff2bin57612 -> 53860 bytes
-rw-r--r--thirdparty/fonts/NotoNaskhArabicUI_Regular.woff2bin57340 -> 53352 bytes
-rw-r--r--thirdparty/fonts/NotoSansBengaliUI_Bold.woff2bin44496 -> 47704 bytes
-rw-r--r--thirdparty/fonts/NotoSansBengaliUI_Regular.woff2bin43568 -> 47000 bytes
-rw-r--r--thirdparty/fonts/NotoSansDevanagariUI_Bold.woff2bin44084 -> 52216 bytes
-rw-r--r--thirdparty/fonts/NotoSansDevanagariUI_Regular.woff2bin43724 -> 51880 bytes
-rw-r--r--thirdparty/fonts/NotoSansGeorgian_Bold.woff2bin11660 -> 24032 bytes
-rw-r--r--thirdparty/fonts/NotoSansGeorgian_Regular.woff2bin11340 -> 23360 bytes
-rw-r--r--thirdparty/fonts/NotoSansHebrew_Bold.woff2bin6692 -> 6216 bytes
-rw-r--r--thirdparty/fonts/NotoSansHebrew_Regular.woff2bin6680 -> 6200 bytes
-rw-r--r--thirdparty/fonts/NotoSansMalayalamUI_Bold.woff2bin22736 -> 26968 bytes
-rw-r--r--thirdparty/fonts/NotoSansMalayalamUI_Regular.woff2bin23080 -> 26952 bytes
-rw-r--r--thirdparty/fonts/NotoSansOriyaUI_Bold.woff2bin36520 -> 0 bytes
-rw-r--r--thirdparty/fonts/NotoSansOriyaUI_Regular.woff2bin36020 -> 0 bytes
-rw-r--r--thirdparty/fonts/NotoSansOriya_Bold.woff2bin0 -> 37124 bytes
-rw-r--r--thirdparty/fonts/NotoSansOriya_Regular.woff2bin0 -> 36084 bytes
-rw-r--r--thirdparty/fonts/NotoSansSinhalaUI_Bold.woff2bin40128 -> 40952 bytes
-rw-r--r--thirdparty/fonts/NotoSansSinhalaUI_Regular.woff2bin40124 -> 40672 bytes
-rw-r--r--thirdparty/fonts/NotoSansTamilUI_Bold.woff2bin17400 -> 17848 bytes
-rw-r--r--thirdparty/fonts/NotoSansTamilUI_Regular.woff2bin17160 -> 17600 bytes
-rw-r--r--thirdparty/fonts/NotoSansTeluguUI_Bold.woff2bin37228 -> 46740 bytes
-rw-r--r--thirdparty/fonts/NotoSansTeluguUI_Regular.woff2bin36816 -> 44460 bytes
-rw-r--r--thirdparty/fonts/NotoSansThaiUI_Bold.woff2bin9420 -> 0 bytes
-rw-r--r--thirdparty/fonts/NotoSansThaiUI_Regular.woff2bin9468 -> 0 bytes
-rw-r--r--thirdparty/fonts/NotoSansThai_Bold.woff2bin0 -> 8948 bytes
-rw-r--r--thirdparty/fonts/NotoSansThai_Regular.woff2bin0 -> 9028 bytes
-rw-r--r--thirdparty/fonts/NotoSans_Bold.woff2bin115376 -> 146300 bytes
-rw-r--r--thirdparty/fonts/NotoSans_Regular.woff2bin117840 -> 148480 bytes
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh33
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh20
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh1
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh19
-rw-r--r--thirdparty/harfbuzz/src/graph/classdef-graph.hh2
-rw-r--r--thirdparty/harfbuzz/src/graph/coverage-graph.hh2
-rw-r--r--thirdparty/harfbuzz/src/graph/graph.hh215
-rw-r--r--thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh6
-rw-r--r--thirdparty/harfbuzz/src/graph/pairpos-graph.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-algs.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-bimap.hh1
-rw-r--r--thirdparty/harfbuzz/src/hb-bit-page.hh32
-rw-r--r--thirdparty/harfbuzz/src/hb-bit-set.hh16
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc6
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-config.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-kern.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-machinery.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-map.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-null.hh11
-rw-r--r--thirdparty/harfbuzz/src/hb-open-type.hh24
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff-common.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff1-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff2-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh52
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh387
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc40
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.h7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-map.cc22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.cc19
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh1893
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh164
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-common.hh105
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh42
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh53
-rw-r--r--thirdparty/harfbuzz/src/hb-priority-queue.hh27
-rw-r--r--thirdparty/harfbuzz/src/hb-sanitize.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff-common.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff1.cc10
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff1.hh37
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff2.hh37
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-input.cc1
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc52
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh24
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc27
-rw-r--r--thirdparty/harfbuzz/src/hb-subset.cc10
-rw-r--r--thirdparty/harfbuzz/src/hb-uniscribe.cc6
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h6
-rw-r--r--thirdparty/harfbuzz/src/hb.hh1
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aesni.h5
-rw-r--r--thirdparty/mbedtls/library/entropy_poll.c29
-rw-r--r--thirdparty/mbedtls/patches/1453.diff53
-rw-r--r--thirdparty/mbedtls/patches/aesni-no-arm-intrinsics.patch17
521 files changed, 21196 insertions, 12817 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml
index afc73a462f..ea97ef023d 100644
--- a/.github/workflows/android_builds.yml
+++ b/.github/workflows/android_builds.yml
@@ -18,7 +18,7 @@ jobs:
name: Template (target=template_release)
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Java 11
uses: actions/setup-java@v3
diff --git a/.github/workflows/godot_cpp_test.yml b/.github/workflows/godot_cpp_test.yml
index 5384197f37..dccc853550 100644
--- a/.github/workflows/godot_cpp_test.yml
+++ b/.github/workflows/godot_cpp_test.yml
@@ -18,14 +18,14 @@ jobs:
runs-on: "ubuntu-20.04"
name: "Build and test Godot CPP"
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup python and scons
uses: ./.github/actions/godot-deps
# Checkout godot-cpp
- name: Checkout godot-cpp
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: godotengine/godot-cpp
ref: ${{ env.GODOT_CPP_BRANCH }}
diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml
index 63ecabd957..6557120d87 100644
--- a/.github/workflows/ios_builds.yml
+++ b/.github/workflows/ios_builds.yml
@@ -18,7 +18,7 @@ jobs:
name: Template (target=template_release)
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index 01f2404866..fc0db1fbd6 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -85,7 +85,7 @@ jobs:
artifact: true
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
# Need newer mesa for lavapipe to work properly.
- name: Linux dependencies for tests
@@ -111,7 +111,7 @@ jobs:
uses: ./.github/actions/godot-deps
- name: Set up .NET Sdk
- uses: actions/setup-dotnet@v2
+ uses: actions/setup-dotnet@v3
if: ${{ matrix.build-mono }}
with:
dotnet-version: '6.0.x'
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index ae6f452bc2..1e39aceeb8 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -33,7 +33,7 @@ jobs:
sconsflags: debug_symbols=no
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index c096c63f9b..4b7f721a23 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 2
diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml
index 2ae238caa6..6de6eeaf2e 100644
--- a/.github/workflows/web_builds.yml
+++ b/.github/workflows/web_builds.yml
@@ -7,7 +7,7 @@ env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no
- EM_VERSION: 3.1.18
+ EM_VERSION: 3.1.45
EM_CACHE_FOLDER: "emsdk-cache"
concurrency:
@@ -16,11 +16,11 @@ concurrency:
jobs:
web-template:
- runs-on: "ubuntu-20.04"
+ runs-on: "ubuntu-22.04"
name: Template (target=template_release)
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v12
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index ab62dca5cb..14f2992848 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -38,7 +38,7 @@ jobs:
sconsflags: debug_symbols=no
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache
diff --git a/SConstruct b/SConstruct
index 7d4c8975e7..df750beae4 100644
--- a/SConstruct
+++ b/SConstruct
@@ -978,7 +978,7 @@ if selected_platform in platform_list:
print("Error: The `vsproj` option is only usable on Windows with Visual Studio.")
Exit(255)
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
- methods.generate_vs_project(env, GetOption("num_jobs"), env["vsproj_name"])
+ methods.generate_vs_project(env, ARGUMENTS, env["vsproj_name"])
methods.generate_cpp_hint_file("cpp.hint")
# Check for the existence of headers
diff --git a/core/debugger/engine_profiler.h b/core/debugger/engine_profiler.h
index f74481c84b..d3d0021e67 100644
--- a/core/debugger/engine_profiler.h
+++ b/core/debugger/engine_profiler.h
@@ -31,10 +31,8 @@
#ifndef ENGINE_PROFILER_H
#define ENGINE_PROFILER_H
-#include "core/object/ref_counted.h"
-
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
+#include "core/object/ref_counted.h"
class EngineProfiler : public RefCounted {
GDCLASS(EngineProfiler, RefCounted);
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index b6dfec33ed..a09b1f491e 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -1055,6 +1055,7 @@ static GDExtensionScriptInstancePtr gdextension_script_instance_create(const GDE
info_2->get_method_list_func = p_info->get_method_list_func;
info_2->free_method_list_func = p_info->free_method_list_func;
info_2->get_property_type_func = p_info->get_property_type_func;
+ info_2->validate_property_func = nullptr;
info_2->has_method_func = p_info->has_method_func;
info_2->call_func = p_info->call_func;
info_2->notification_func = nullptr;
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index 102220c0fc..4379e520b7 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -373,6 +373,7 @@ typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanc
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
+typedef GDExtensionBool (*GDExtensionScriptInstanceValidateProperty)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_property);
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
@@ -459,6 +460,7 @@ typedef struct {
GDExtensionScriptInstanceGetMethodList get_method_list_func;
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
+ GDExtensionScriptInstanceValidateProperty validate_property_func;
GDExtensionScriptInstanceHasMethod has_method_func;
diff --git a/core/extension/gdextension_manager.cpp b/core/extension/gdextension_manager.cpp
index 63e809bc7c..0f0e2fad41 100644
--- a/core/extension/gdextension_manager.cpp
+++ b/core/extension/gdextension_manager.cpp
@@ -143,6 +143,8 @@ void GDExtensionManager::load_extensions() {
ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, "Error loading extension: " + s);
}
}
+
+ OS::get_singleton()->load_platform_gdextensions();
}
GDExtensionManager *GDExtensionManager::get_singleton() {
diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt
index 7c51e20b4c..f5158bfabb 100644
--- a/core/input/godotcontrollerdb.txt
+++ b/core/input/godotcontrollerdb.txt
@@ -33,6 +33,3 @@ Linux20d6a713,Bensussen Deutsch & Associates Inc.(BDA) NSW Wired controller,a:b1
Linux054c05c4,Sony Computer Entertainment Wireless Controller,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web
Linux18d19400,18d1-9400-Google LLC Stadia Controller rev. A,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Web
Linux054c0268,054c-0268-Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,y:b2,x:b3,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web
-
-# UWP
-__UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:UWP,
diff --git a/core/input/input_builders.py b/core/input/input_builders.py
index 76e199e0ff..e98e2441e2 100644
--- a/core/input/input_builders.py
+++ b/core/input/input_builders.py
@@ -51,7 +51,6 @@ def make_default_controller_mappings(target, source, env):
"Android": "#if defined(__ANDROID__)",
"iOS": "#ifdef IOS_ENABLED",
"Web": "#ifdef WEB_ENABLED",
- "UWP": "#ifdef UWP_ENABLED",
}
g.write("const char* DefaultControllerMappings::mappings[] = {\n")
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index 7383ab84df..86ebe32cb6 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -37,7 +37,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class PacketPeer : public RefCounted {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 551d3268b8..ea97e5ecce 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -36,6 +36,7 @@
#include "core/io/image.h"
#include "core/io/marshalls.h"
#include "core/io/missing_resource.h"
+#include "core/object/script_language.h"
#include "core/version.h"
//#define print_bl(m_what) print_line(m_what)
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index df0253349c..c1a38f0af8 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/io/file_access.h"
#include "core/io/resource_importer.h"
+#include "core/object/script_language.h"
#include "core/os/condition_variable.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 2701caa3f4..0c7d6c0feb 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/object/worker_thread_pool.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 572742d129..4828df297a 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class ResourceFormatSaver : public RefCounted {
GDCLASS(ResourceFormatSaver, RefCounted);
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index ba11144e33..29cdb82615 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class StreamPeer : public RefCounted {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index fc4bb09f03..0758500c8a 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -33,7 +33,6 @@
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
#include "core/templates/oa_hash_map.h"
/**
diff --git a/core/math/a_star_grid_2d.h b/core/math/a_star_grid_2d.h
index dd5f9d0575..ecc9bb01f9 100644
--- a/core/math/a_star_grid_2d.h
+++ b/core/math/a_star_grid_2d.h
@@ -33,7 +33,6 @@
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
#include "core/templates/list.h"
#include "core/templates/local_vector.h"
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 5be9650b32..38682d6d92 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -160,6 +160,8 @@ def run(target, source, env):
#ifndef GDVIRTUAL_GEN_H
#define GDVIRTUAL_GEN_H
+#include "core/object/script_instance.h"
+
"""
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java b/core/object/script_instance.cpp
index 63999a8321..303b127db1 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java
+++ b/core/object/script_instance.cpp
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* GodotPluginInfoProvider.java */
+/* script_instance.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,45 +28,44 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-package org.godotengine.godot.plugin;
+#include "script_instance.h"
-import androidx.annotation.NonNull;
+#include "core/object/script_language.h"
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Provides the set of information expected from a Godot plugin.
- */
-public interface GodotPluginInfoProvider {
- /**
- * Returns the name of the plugin.
- */
- @NonNull
- String getPluginName();
+Variant ScriptInstance::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+ return callp(p_method, p_args, p_argcount, r_error);
+}
- /**
- * Returns the list of signals to be exposed to Godot.
- */
- @NonNull
- default Set<SignalInfo> getPluginSignals() {
- return Collections.emptySet();
+void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) {
+ List<PropertyInfo> pinfo;
+ get_property_list(&pinfo);
+ for (const PropertyInfo &E : pinfo) {
+ if (E.usage & PROPERTY_USAGE_STORAGE) {
+ Pair<StringName, Variant> p;
+ p.first = E.name;
+ if (get(p.first, p.second)) {
+ state.push_back(p);
+ }
+ }
}
+}
- /**
- * Returns the paths for the plugin's gdextension libraries (if any).
- *
- * The paths must be relative to the 'assets' directory and point to a '*.gdextension' file.
- */
- @NonNull
- default Set<String> getPluginGDExtensionLibrariesPaths() {
- return Collections.emptySet();
+void ScriptInstance::property_set_fallback(const StringName &, const Variant &, bool *r_valid) {
+ if (r_valid) {
+ *r_valid = false;
}
+}
- /**
- * This is invoked on the render thread when the plugin described by this instance has been
- * registered.
- */
- default void onPluginRegistered() {
+Variant ScriptInstance::property_get_fallback(const StringName &, bool *r_valid) {
+ if (r_valid) {
+ *r_valid = false;
}
+ return Variant();
+}
+
+const Variant ScriptInstance::get_rpc_config() const {
+ return get_script()->get_rpc_config();
+}
+
+ScriptInstance::~ScriptInstance() {
}
diff --git a/core/object/script_instance.h b/core/object/script_instance.h
new file mode 100644
index 0000000000..df978a25ea
--- /dev/null
+++ b/core/object/script_instance.h
@@ -0,0 +1,98 @@
+/**************************************************************************/
+/* script_instance.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef SCRIPT_INSTANCE_H
+#define SCRIPT_INSTANCE_H
+
+#include "core/object/ref_counted.h"
+
+class Script;
+class ScriptLanguage;
+
+class ScriptInstance {
+public:
+ virtual bool set(const StringName &p_name, const Variant &p_value) = 0;
+ virtual bool get(const StringName &p_name, Variant &r_ret) const = 0;
+ virtual void get_property_list(List<PropertyInfo> *p_properties) const = 0;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const = 0;
+ virtual void validate_property(PropertyInfo &p_property) const = 0;
+
+ virtual bool property_can_revert(const StringName &p_name) const = 0;
+ virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const = 0;
+
+ virtual Object *get_owner() { return nullptr; }
+ virtual void get_property_state(List<Pair<StringName, Variant>> &state);
+
+ virtual void get_method_list(List<MethodInfo> *p_list) const = 0;
+ virtual bool has_method(const StringName &p_method) const = 0;
+
+ virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0;
+
+ template <typename... VarArgs>
+ Variant call(const StringName &p_method, VarArgs... p_args) {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
+ Callable::CallError cerr;
+ return callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), cerr);
+ }
+
+ virtual Variant call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); // implement if language supports const functions
+ virtual void notification(int p_notification, bool p_reversed = false) = 0;
+ virtual String to_string(bool *r_valid) {
+ if (r_valid) {
+ *r_valid = false;
+ }
+ return String();
+ }
+
+ //this is used by script languages that keep a reference counter of their own
+ //you can make make Ref<> not die when it reaches zero, so deleting the reference
+ //depends entirely from the script
+
+ virtual void refcount_incremented() {}
+ virtual bool refcount_decremented() { return true; } //return true if it can die
+
+ virtual Ref<Script> get_script() const = 0;
+
+ virtual bool is_placeholder() const { return false; }
+
+ virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid);
+ virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid);
+
+ virtual const Variant get_rpc_config() const;
+
+ virtual ScriptLanguage *get_language() = 0;
+ virtual ~ScriptInstance();
+};
+
+#endif // SCRIPT_INSTANCE_H
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index a8b0e426ae..abf2b7b054 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -388,40 +388,6 @@ String ScriptServer::get_global_class_cache_file_path() {
////////////////////
-Variant ScriptInstance::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- return callp(p_method, p_args, p_argcount, r_error);
-}
-
-void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) {
- List<PropertyInfo> pinfo;
- get_property_list(&pinfo);
- for (const PropertyInfo &E : pinfo) {
- if (E.usage & PROPERTY_USAGE_STORAGE) {
- Pair<StringName, Variant> p;
- p.first = E.name;
- if (get(p.first, p.second)) {
- state.push_back(p);
- }
- }
- }
-}
-
-void ScriptInstance::property_set_fallback(const StringName &, const Variant &, bool *r_valid) {
- if (r_valid) {
- *r_valid = false;
- }
-}
-
-Variant ScriptInstance::property_get_fallback(const StringName &, bool *r_valid) {
- if (r_valid) {
- *r_valid = false;
- }
- return Variant();
-}
-
-ScriptInstance::~ScriptInstance() {
-}
-
ScriptCodeCompletionCache *ScriptCodeCompletionCache::singleton = nullptr;
ScriptCodeCompletionCache::ScriptCodeCompletionCache() {
singleton = this;
@@ -482,7 +448,6 @@ TypedArray<int> ScriptLanguage::CodeCompletionOption::get_option_characteristics
}
charac.push_back(matches.size());
charac.push_back((matches[0].first == 0) ? 0 : 1);
- charac.push_back(location);
const char32_t *target_char = &p_base[0];
int bad_case = 0;
for (const Pair<int, int> &match_segment : matches) {
@@ -494,6 +459,7 @@ TypedArray<int> ScriptLanguage::CodeCompletionOption::get_option_characteristics
}
}
charac.push_back(bad_case);
+ charac.push_back(location);
charac.push_back(matches[0].first);
last_matches = matches;
return charac;
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 3cac360b1a..e0c4d650dd 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -33,6 +33,7 @@
#include "core/doc_data.h"
#include "core/io/resource.h"
+#include "core/object/script_instance.h"
#include "core/templates/pair.h"
#include "core/templates/rb_map.h"
#include "core/templates/safe_refcount.h"
@@ -101,7 +102,6 @@ public:
static bool are_languages_finished() { return languages_finished.is_set(); }
};
-class ScriptInstance;
class PlaceHolderScriptInstance;
class Script : public Resource {
@@ -174,65 +174,6 @@ public:
Script() {}
};
-class ScriptInstance {
-public:
- virtual bool set(const StringName &p_name, const Variant &p_value) = 0;
- virtual bool get(const StringName &p_name, Variant &r_ret) const = 0;
- virtual void get_property_list(List<PropertyInfo> *p_properties) const = 0;
- virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const = 0;
- virtual void validate_property(PropertyInfo &p_property) const = 0;
-
- virtual bool property_can_revert(const StringName &p_name) const = 0;
- virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const = 0;
-
- virtual Object *get_owner() { return nullptr; }
- virtual void get_property_state(List<Pair<StringName, Variant>> &state);
-
- virtual void get_method_list(List<MethodInfo> *p_list) const = 0;
- virtual bool has_method(const StringName &p_method) const = 0;
-
- virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0;
-
- template <typename... VarArgs>
- Variant call(const StringName &p_method, VarArgs... p_args) {
- Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
- const Variant *argptrs[sizeof...(p_args) + 1];
- for (uint32_t i = 0; i < sizeof...(p_args); i++) {
- argptrs[i] = &args[i];
- }
- Callable::CallError cerr;
- return callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), cerr);
- }
-
- virtual Variant call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); // implement if language supports const functions
- virtual void notification(int p_notification, bool p_reversed = false) = 0;
- virtual String to_string(bool *r_valid) {
- if (r_valid) {
- *r_valid = false;
- }
- return String();
- }
-
- //this is used by script languages that keep a reference counter of their own
- //you can make make Ref<> not die when it reaches zero, so deleting the reference
- //depends entirely from the script
-
- virtual void refcount_incremented() {}
- virtual bool refcount_decremented() { return true; } //return true if it can die
-
- virtual Ref<Script> get_script() const = 0;
-
- virtual bool is_placeholder() const { return false; }
-
- virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid);
- virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid);
-
- virtual const Variant get_rpc_config() const { return get_script()->get_rpc_config(); }
-
- virtual ScriptLanguage *get_language() = 0;
- virtual ~ScriptInstance();
-};
-
class ScriptCodeCompletionCache {
static ScriptCodeCompletionCache *singleton;
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index bf5ad3c107..c7218d99a6 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -688,7 +688,24 @@ public:
return Variant::NIL;
}
virtual void validate_property(PropertyInfo &p_property) const override {
- // TODO
+ if (native_info->validate_property_func) {
+ GDExtensionPropertyInfo gdext_prop = {
+ (GDExtensionVariantType)p_property.type,
+ &p_property.name,
+ &p_property.class_name,
+ (uint32_t)p_property.hint,
+ &p_property.hint_string,
+ p_property.usage,
+ };
+ if (native_info->validate_property_func(instance, &gdext_prop)) {
+ p_property.type = (Variant::Type)gdext_prop.type;
+ p_property.name = *reinterpret_cast<StringName *>(gdext_prop.name);
+ p_property.class_name = *reinterpret_cast<StringName *>(gdext_prop.class_name);
+ p_property.hint = (PropertyHint)gdext_prop.hint;
+ p_property.hint_string = *reinterpret_cast<String *>(gdext_prop.hint_string);
+ p_property.usage = gdext_prop.usage;
+ }
+ }
}
virtual bool property_can_revert(const StringName &p_name) const override {
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index 90cad009b1..b45eb38aeb 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -34,7 +34,6 @@
#include "core/input/input_event.h"
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
class MainLoop : public Object {
GDCLASS(MainLoop, Object);
diff --git a/core/os/os.h b/core/os/os.h
index 965dc1f912..cc5ebe1bc8 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -328,6 +328,10 @@ public:
virtual PreferredTextureFormat get_preferred_texture_format() const;
+ // Load GDExtensions specific to this platform.
+ // This is invoked by the GDExtensionManager after loading GDExtensions specified by the project.
+ virtual void load_platform_gdextensions() const {}
+
OS();
virtual ~OS();
};
diff --git a/core/string/translation.h b/core/string/translation.h
index ca8b460312..3f9dbcc476 100644
--- a/core/string/translation.h
+++ b/core/string/translation.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class Translation : public Resource {
GDCLASS(Translation, Resource);
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 3f11459a1e..f6a17cf1a7 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1493,9 +1493,9 @@ String String::num(double p_num, int p_decimals) {
if (p_decimals < 0) {
p_decimals = 14;
- const double abs_num = ABS(p_num);
+ const double abs_num = Math::abs(p_num);
if (abs_num > 10) {
- // We want to align the digits to the above sane default, so we only
+ // We want to align the digits to the above reasonable default, so we only
// need to subtract log10 for numbers with a positive power of ten.
p_decimals -= (int)floor(log10(abs_num));
}
@@ -4890,8 +4890,8 @@ String String::sprintf(const Array &values, bool *error) const {
}
double value = values[value_index];
- bool is_negative = (value < 0);
- String str = String::num(ABS(value), min_decimals);
+ bool is_negative = signbit(value);
+ String str = String::num(Math::abs(value), min_decimals);
const bool is_finite = Math::is_finite(value);
// Pad decimals out.
@@ -4953,7 +4953,7 @@ String String::sprintf(const Array &values, bool *error) const {
String str = "(";
for (int i = 0; i < count; i++) {
double val = vec[i];
- String number_str = String::num(ABS(val), min_decimals);
+ String number_str = String::num(Math::abs(val), min_decimals);
const bool is_finite = Math::is_finite(val);
// Pad decimals out.
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index b7bdf1d97a..fea1622222 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -32,6 +32,7 @@
#include "core/input/input_event.h"
#include "core/io/resource_loader.h"
+#include "core/object/script_language.h"
#include "core/os/keyboard.h"
#include "core/string/string_buffer.h"
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 1cc2976c81..2246e30817 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -176,6 +176,9 @@
<member name="disable_ambient_light" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object receives no ambient light.
</member>
+ <member name="disable_fog" type="bool" setter="set_flag" getter="get_flag" default="false">
+ If [code]true[/code], the object will not be affected by fog (neither volumetric nor depth fog). This is useful for unshaded or transparent materials (e.g. particles), which without this setting will be affected even if fully transparent.
+ </member>
<member name="disable_receive_shadows" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object receives no shadow that would otherwise be cast onto it.
</member>
@@ -697,7 +700,10 @@
<constant name="FLAG_ALBEDO_TEXTURE_MSDF" value="20" enum="Flags">
Enables multichannel signed distance field rendering shader.
</constant>
- <constant name="FLAG_MAX" value="21" enum="Flags">
+ <constant name="FLAG_DISABLE_FOG" value="21" enum="Flags">
+ Disables receiving depth-based or volumetric fog.
+ </constant>
+ <constant name="FLAG_MAX" value="22" enum="Flags">
Represents the size of the [enum Flags] enum.
</constant>
<constant name="DIFFUSE_BURLEY" value="0" enum="DiffuseMode">
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index c2f81ba109..44b2d72ebe 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -190,7 +190,7 @@
<method name="get_swap_cancel_ok">
<return type="bool" />
<description>
- Returns [code]true[/code] if positions of [b]OK[/b] and [b]Cancel[/b] buttons are swapped in dialogs. This is enabled by default on Windows and UWP to follow interface conventions, and be toggled by changing [member ProjectSettings.gui/common/swap_cancel_ok].
+ Returns [code]true[/code] if positions of [b]OK[/b] and [b]Cancel[/b] buttons are swapped in dialogs. This is enabled by default on Windows to follow interface conventions, and be toggled by changing [member ProjectSettings.gui/common/swap_cancel_ok].
[b]Note:[/b] This doesn't affect native dialogs such as the ones spawned by [method DisplayServer.dialog_show].
</description>
</method>
diff --git a/doc/classes/EditorExportPlatform.xml b/doc/classes/EditorExportPlatform.xml
index ac921a0c80..6801ac672c 100644
--- a/doc/classes/EditorExportPlatform.xml
+++ b/doc/classes/EditorExportPlatform.xml
@@ -10,4 +10,12 @@
<tutorials>
<link title="$DOCS_URL/tutorials/platform/consoles.html">Console support in Godot</link>
</tutorials>
+ <methods>
+ <method name="get_os_name" qualifiers="const">
+ <return type="String" />
+ <description>
+ Returns the name of the export operating system handled by this [EditorExportPlatform] class, as a friendly string. Possible return values are [code]Windows[/code], [code]Linux[/code], [code]macOS[/code], [code]Android[/code], [code]iOS[/code], and [code]Web[/code].
+ </description>
+ </method>
+ </methods>
</class>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 08f8cf70e9..8aea15c087 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Plugins are used by the editor to extend functionality. The most common types of plugins are those which edit a given node or resource type, import plugins and export plugins. See also [EditorScript] to add functions to the editor.
+ [b]Note:[/b] Some names in this class contain "left" or "right" (e.g. [constant DOCK_SLOT_LEFT_UL]). These APIs assume left-to-right layout, and would be backwards when using right-to-left layout. These names are kept for compatibility reasons.
</description>
<tutorials>
<link title="Editor plugins documentation index">$DOCS_URL/tutorials/plugins/editor/index.html</link>
@@ -824,13 +825,13 @@
Dock slot, left side, bottom-right (in default layout includes FileSystem dock).
</constant>
<constant name="DOCK_SLOT_RIGHT_UL" value="4" enum="DockSlot">
- Dock slot, right side, upper-left (empty in default layout).
+ Dock slot, right side, upper-left (in default layout includes Inspector, Node, and History docks).
</constant>
<constant name="DOCK_SLOT_RIGHT_BL" value="5" enum="DockSlot">
Dock slot, right side, bottom-left (empty in default layout).
</constant>
<constant name="DOCK_SLOT_RIGHT_UR" value="6" enum="DockSlot">
- Dock slot, right side, upper-right (in default layout includes Inspector, Node and History docks).
+ Dock slot, right side, upper-right (empty in default layout).
</constant>
<constant name="DOCK_SLOT_RIGHT_BR" value="7" enum="DockSlot">
Dock slot, right side, bottom-right (empty in default layout).
diff --git a/doc/classes/EditorResourceTooltipPlugin.xml b/doc/classes/EditorResourceTooltipPlugin.xml
index 69c5f30f25..acfa881ab1 100644
--- a/doc/classes/EditorResourceTooltipPlugin.xml
+++ b/doc/classes/EditorResourceTooltipPlugin.xml
@@ -24,7 +24,7 @@
<param index="2" name="base" type="Control" />
<description>
Create and return a tooltip that will be displayed when the user hovers a resource under the given [param path] in filesystem dock.
- The [param metadata] dictionary is provided by preview generator (see method EditorResourcePreviewGenerator._generate]).
+ The [param metadata] dictionary is provided by preview generator (see [method EditorResourcePreviewGenerator._generate]).
[param base] is the base default tooltip, which is a [VBoxContainer] with a file name, type and size labels. If another plugin handled the same file type, [param base] will be output from the previous plugin. For best result, make sure the base tooltip is part of the returned [Control].
[b]Note:[/b] It's unadvised to use [method ResourceLoader.load], especially with heavy resources like models or textures, because it will make the editor unresponsive when creating the tooltip. You can use [method request_thumbnail] if you want to display a preview in your tooltip.
[b]Note:[/b] If you decide to discard the [param base], make sure to call [method Node.queue_free], because it's not freed automatically.
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 0aea0c5727..baa591fd66 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -26,12 +26,12 @@
<param index="2" name="mouse_position" type="Vector2" />
<description>
Returns whether the [param mouse_position] is in the input hot zone.
- By default, a hot zone is a [Rect2] positioned such that its center is at [param in_node].[method GraphNode.get_connection_input_position]([param in_port]) (For output's case, call [method GraphNode.get_connection_output_position] instead). The hot zone's width is twice the Theme Property [code]port_grab_distance_horizontal[/code], and its height is twice the [code]port_grab_distance_vertical[/code].
+ By default, a hot zone is a [Rect2] positioned such that its center is at [param in_node].[method GraphNode.get_input_port_position]([param in_port]) (For output's case, call [method GraphNode.get_output_port_position] instead). The hot zone's width is twice the Theme Property [code]port_grab_distance_horizontal[/code], and its height is twice the [code]port_grab_distance_vertical[/code].
Below is a sample code to help get started:
[codeblock]
func _is_in_input_hotzone(in_node, in_port, mouse_position):
var port_size: Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
- var port_pos: Vector2 = in_node.get_position() + in_node.get_connection_input_position(in_port) - port_size / 2
+ var port_pos: Vector2 = in_node.get_position() + in_node.get_input_port_position(in_port) - port_size / 2
var rect = Rect2(port_pos, port_size)
return rect.has_point(mouse_position)
@@ -49,7 +49,7 @@
[codeblock]
func _is_in_output_hotzone(in_node, in_port, mouse_position):
var port_size: Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
- var port_pos: Vector2 = in_node.get_position() + in_node.get_connection_output_position(in_port) - port_size / 2
+ var port_pos: Vector2 = in_node.get_position() + in_node.get_output_port_position(in_port) - port_size / 2
var rect = Rect2(port_pos, port_size)
return rect.has_point(mouse_position)
@@ -289,6 +289,12 @@
Emitted at the beginning of a GraphNode movement.
</description>
</signal>
+ <signal name="close_nodes_request">
+ <param index="0" name="nodes" type="StringName[]" />
+ <description>
+ Emitted when attempting to remove a GraphNode from the GraphEdit. Provides a list of node names to be removed (all selected nodes, excluding nodes without closing button).
+ </description>
+ </signal>
<signal name="connection_drag_ended">
<description>
Emitted at the end of a connection drag.
@@ -332,12 +338,6 @@
Emitted when the user presses [kbd]Ctrl + C[/kbd].
</description>
</signal>
- <signal name="delete_nodes_request">
- <param index="0" name="nodes" type="StringName[]" />
- <description>
- Emitted when a GraphNode is attempted to be removed from the GraphEdit. Provides a list of node names to be removed (all selected nodes, excluding nodes without closing button).
- </description>
- </signal>
<signal name="disconnection_request">
<param index="0" name="from_node" type="StringName" />
<param index="1" name="from_port" type="int" />
diff --git a/doc/classes/GraphElement.xml b/doc/classes/GraphElement.xml
new file mode 100644
index 0000000000..6c3b6b727a
--- /dev/null
+++ b/doc/classes/GraphElement.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GraphElement" inherits="Container" is_experimental="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ A container that represents a basic element that can be placed inside a [GraphEdit] control.
+ </brief_description>
+ <description>
+ [GraphElement] allows to create custom elements for a [GraphEdit] graph. By default such elements can be selected, resized, and repositioned, but they cannot be connected. For a graph element that allows for connections see [GraphNode].
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="draggable" type="bool" setter="set_draggable" getter="is_draggable" default="true">
+ If [code]true[/code], the user can drag the GraphElement.
+ </member>
+ <member name="position_offset" type="Vector2" setter="set_position_offset" getter="get_position_offset" default="Vector2(0, 0)">
+ The offset of the GraphElement, relative to the scroll offset of the [GraphEdit].
+ </member>
+ <member name="resizable" type="bool" setter="set_resizable" getter="is_resizable" default="false">
+ If [code]true[/code], the user can resize the GraphElement.
+ [b]Note:[/b] Dragging the handle will only emit the [signal resize_request] signal, the GraphElement needs to be resized manually.
+ </member>
+ <member name="selectable" type="bool" setter="set_selectable" getter="is_selectable" default="true">
+ If [code]true[/code], the user can select the GraphElement.
+ </member>
+ <member name="selected" type="bool" setter="set_selected" getter="is_selected" default="false">
+ If [code]true[/code], the GraphElement is selected.
+ </member>
+ </members>
+ <signals>
+ <signal name="close_request">
+ <description>
+ Emitted when closing the GraphElement is requested.
+ </description>
+ </signal>
+ <signal name="dragged">
+ <param index="0" name="from" type="Vector2" />
+ <param index="1" name="to" type="Vector2" />
+ <description>
+ Emitted when the GraphElement is dragged.
+ </description>
+ </signal>
+ <signal name="node_deselected">
+ <description>
+ Emitted when the GraphElement is deselected.
+ </description>
+ </signal>
+ <signal name="node_selected">
+ <description>
+ Emitted when the GraphElement is selected.
+ </description>
+ </signal>
+ <signal name="position_offset_changed">
+ <description>
+ Emitted when the GraphElement is moved.
+ </description>
+ </signal>
+ <signal name="raise_request">
+ <description>
+ Emitted when displaying the GraphElement over other ones is requested. Happens on focusing (clicking into) the GraphElement.
+ </description>
+ </signal>
+ <signal name="resize_request">
+ <param index="0" name="new_minsize" type="Vector2" />
+ <description>
+ Emitted when resizing the GraphElement is requested. Happens on dragging the resizer handle (see [member resizable]).
+ </description>
+ </signal>
+ </signals>
+</class>
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index d160141842..5d52ea17e2 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GraphNode" inherits="Container" is_experimental="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="GraphNode" inherits="GraphElement" is_experimental="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A container with connection ports, representing a node in a [GraphEdit].
</brief_description>
@@ -7,153 +7,154 @@
[GraphNode] allows to create nodes for a [GraphEdit] graph with customizable content based on its child controls. [GraphNode] is derived from [Container] and it is responsible for placing its children on screen. This works similar to [VBoxContainer]. Children, in turn, provide [GraphNode] with so-called slots, each of which can have a connection port on either side.
Each [GraphNode] slot is defined by its index and can provide the node with up to two ports: one on the left, and one on the right. By convention the left port is also referred to as the [b]input port[/b] and the right port is referred to as the [b]output port[/b]. Each port can be enabled and configured individually, using different type and color. The type is an arbitrary value that you can define using your own considerations. The parent [GraphEdit] will receive this information on each connect and disconnect request.
Slots can be configured in the Inspector dock once you add at least one child [Control]. The properties are grouped by each slot's index in the "Slot" section.
- [b]Note:[/b] While GraphNode is set up using slots and slot indices, connections are made between the ports which are enabled. Because of that, [GraphEdit] uses the port's index and not the slot's index. You can use [method get_connection_input_slot] and [method get_connection_output_slot] to get the slot index from the port index.
+ [b]Note:[/b] While GraphNode is set up using slots and slot indices, connections are made between the ports which are enabled. Because of that [GraphEdit] uses the port's index and not the slot's index. You can use [method get_input_port_slot] and [method get_output_port_slot] to get the slot index from the port index.
</description>
<tutorials>
</tutorials>
<methods>
+ <method name="_draw_port" qualifiers="virtual">
+ <return type="void" />
+ <param index="0" name="slot_index" type="int" />
+ <param index="1" name="position" type="Vector2i" />
+ <param index="2" name="left" type="bool" />
+ <param index="3" name="color" type="Color" />
+ <description>
+ </description>
+ </method>
<method name="clear_all_slots">
<return type="void" />
<description>
- Disables all input and output slots of the GraphNode.
+ Disables all slots of the GraphNode. This will remove all input/output ports from the GraphNode.
</description>
</method>
<method name="clear_slot">
<return type="void" />
<param index="0" name="slot_index" type="int" />
<description>
- Disables input and output slot whose index is [param slot_index].
+ Disables the slot with the given [param slot_index]. This will remove the corresponding input and output port from the GraphNode.
</description>
</method>
- <method name="get_connection_input_color">
+ <method name="get_input_port_color">
<return type="Color" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the [Color] of the input connection [param port].
+ Returns the [Color] of the input port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_input_count">
+ <method name="get_input_port_count">
<return type="int" />
<description>
- Returns the number of enabled input slots (connections) to the GraphNode.
+ Returns the number of slots with an enabled input port.
</description>
</method>
- <method name="get_connection_input_height">
- <return type="int" />
- <param index="0" name="port" type="int" />
- <description>
- Returns the height of the input connection [param port].
- </description>
- </method>
- <method name="get_connection_input_position">
+ <method name="get_input_port_position">
<return type="Vector2" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the position of the input connection [param port].
+ Returns the position of the input port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_input_slot">
+ <method name="get_input_port_slot">
<return type="int" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the corresponding slot index of the input connection [param port].
+ Returns the corresponding slot index of the input port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_input_type">
+ <method name="get_input_port_type">
<return type="int" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the type of the input connection [param port].
+ Returns the type of the input port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_output_color">
+ <method name="get_output_port_color">
<return type="Color" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the [Color] of the output connection [param port].
+ Returns the [Color] of the output port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_output_count">
+ <method name="get_output_port_count">
<return type="int" />
<description>
- Returns the number of enabled output slots (connections) of the GraphNode.
+ Returns the number of slots with an enabled output port.
</description>
</method>
- <method name="get_connection_output_height">
- <return type="int" />
- <param index="0" name="port" type="int" />
- <description>
- Returns the height of the output connection [param port].
- </description>
- </method>
- <method name="get_connection_output_position">
+ <method name="get_output_port_position">
<return type="Vector2" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the position of the output connection [param port].
+ Returns the position of the output port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_output_slot">
+ <method name="get_output_port_slot">
<return type="int" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the corresponding slot index of the output connection [param port].
+ Returns the corresponding slot index of the output port with the given [param port_idx].
</description>
</method>
- <method name="get_connection_output_type">
+ <method name="get_output_port_type">
<return type="int" />
- <param index="0" name="port" type="int" />
+ <param index="0" name="port_idx" type="int" />
<description>
- Returns the type of the output connection [param port].
+ Returns the type of the output port with the given [param port_idx].
</description>
</method>
<method name="get_slot_color_left" qualifiers="const">
<return type="Color" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns the left (input) [Color] of the slot [param slot_index].
+ Returns the left (input) [Color] of the slot with the given [param slot_index].
</description>
</method>
<method name="get_slot_color_right" qualifiers="const">
<return type="Color" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns the right (output) [Color] of the slot [param slot_index].
+ Returns the right (output) [Color] of the slot with the given [param slot_index].
</description>
</method>
<method name="get_slot_type_left" qualifiers="const">
<return type="int" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns the left (input) type of the slot [param slot_index].
+ Returns the left (input) type of the slot with the given [param slot_index].
</description>
</method>
<method name="get_slot_type_right" qualifiers="const">
<return type="int" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns the right (output) type of the slot [param slot_index].
+ Returns the right (output) type of the slot with the given [param slot_index].
+ </description>
+ </method>
+ <method name="get_titlebar_hbox">
+ <return type="HBoxContainer" />
+ <description>
+ Returns the [HBoxContainer] used for the title bar, only containing a [Label] for displaying the title by default. This can be used to add custom controls to the title bar such as option or close buttons.
</description>
</method>
<method name="is_slot_draw_stylebox" qualifiers="const">
<return type="bool" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns true if the background [StyleBox] of the slot [param slot_index] is drawn.
+ Returns true if the background [StyleBox] of the slot with the given [param slot_index] is drawn.
</description>
</method>
<method name="is_slot_enabled_left" qualifiers="const">
<return type="bool" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns [code]true[/code] if left (input) side of the slot [param slot_index] is enabled.
+ Returns [code]true[/code] if left (input) side of the slot with the given [param slot_index] is enabled.
</description>
</method>
<method name="is_slot_enabled_right" qualifiers="const">
<return type="bool" />
<param index="0" name="slot_index" type="int" />
<description>
- Returns [code]true[/code] if right (output) side of the slot [param slot_index] is enabled.
+ Returns [code]true[/code] if right (output) side of the slot with the given [param slot_index] is enabled.
</description>
</method>
<method name="set_slot">
@@ -169,7 +170,7 @@
<param index="8" name="custom_icon_right" type="Texture2D" default="null" />
<param index="9" name="draw_stylebox" type="bool" default="true" />
<description>
- Sets properties of the slot with the [param slot_index] index.
+ Sets properties of the slot with the given [param slot_index].
If [param enable_left_port]/[param enable_right_port] is [code]true[/code], a port will appear and the slot will be able to be connected from this side.
With [param type_left]/[param type_right] an arbitrary type can be assigned to each port. Two ports can be connected if they share the same type, or if the connection between their types is allowed in the parent [GraphEdit] (see [method GraphEdit.add_valid_connection_type]). Keep in mind that the [GraphEdit] has the final say in accepting the connection. Type compatibility simply allows the [signal GraphEdit.connection_request] signal to be emitted.
Ports can be further customized using [param color_left]/[param color_right] and [param custom_icon_left]/[param custom_icon_right]. The color parameter adds a tint to the icon. The custom icon can be used to override the default port dot.
@@ -183,7 +184,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="color" type="Color" />
<description>
- Sets the [Color] of the left (input) side of the slot [param slot_index] to [param color].
+ Sets the [Color] of the left (input) side of the slot with the given [param slot_index] to [param color].
</description>
</method>
<method name="set_slot_color_right">
@@ -191,7 +192,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="color" type="Color" />
<description>
- Sets the [Color] of the right (output) side of the slot [param slot_index] to [param color].
+ Sets the [Color] of the right (output) side of the slot with the given [param slot_index] to [param color].
</description>
</method>
<method name="set_slot_draw_stylebox">
@@ -199,7 +200,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="enable" type="bool" />
<description>
- Toggles the background [StyleBox] of the slot [param slot_index].
+ Toggles the background [StyleBox] of the slot with the given [param slot_index].
</description>
</method>
<method name="set_slot_enabled_left">
@@ -207,7 +208,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="enable" type="bool" />
<description>
- Toggles the left (input) side of the slot [param slot_index]. If [param enable] is [code]true[/code], a port will appear on the left side and the slot will be able to be connected from this side.
+ Toggles the left (input) side of the slot with the given [param slot_index]. If [param enable] is [code]true[/code], a port will appear on the left side and the slot will be able to be connected from this side.
</description>
</method>
<method name="set_slot_enabled_right">
@@ -215,7 +216,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="enable" type="bool" />
<description>
- Toggles the right (output) side of the slot [param slot_index]. If [param enable] is [code]true[/code], a port will appear on the right side and the slot will be able to be connected from this side.
+ Toggles the right (output) side of the slot with the given [param slot_index]. If [param enable] is [code]true[/code], a port will appear on the right side and the slot will be able to be connected from this side.
</description>
</method>
<method name="set_slot_type_left">
@@ -223,7 +224,7 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="type" type="int" />
<description>
- Sets the left (input) type of the slot [param slot_index] to [param type]. If the value is negative, all connections will be disallowed to be created via user inputs.
+ Sets the left (input) type of the slot with the given [param slot_index] to [param type]. If the value is negative, all connections will be disallowed to be created via user inputs.
</description>
</method>
<method name="set_slot_type_right">
@@ -231,156 +232,54 @@
<param index="0" name="slot_index" type="int" />
<param index="1" name="type" type="int" />
<description>
- Sets the right (output) type of the slot [param slot_index] to [param type]. If the value is negative, all connections will be disallowed to be created via user inputs.
+ Sets the right (output) type of the slot with the given [param slot_index] to [param type]. If the value is negative, all connections will be disallowed to be created via user inputs.
</description>
</method>
</methods>
<members>
- <member name="draggable" type="bool" setter="set_draggable" getter="is_draggable" default="true">
- If [code]true[/code], the user can drag the GraphNode.
- </member>
- <member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
- Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
- </member>
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="0" />
- <member name="overlay" type="int" setter="set_overlay" getter="get_overlay" enum="GraphNode.Overlay" default="0">
- Sets the overlay shown above the GraphNode. See [enum Overlay].
- </member>
- <member name="position_offset" type="Vector2" setter="set_position_offset" getter="get_position_offset" default="Vector2(0, 0)">
- The offset of the GraphNode, relative to the scroll offset of the [GraphEdit].
- [b]Note:[/b] You cannot use position offset directly, as [GraphEdit] is a [Container].
- </member>
- <member name="resizable" type="bool" setter="set_resizable" getter="is_resizable" default="false">
- If [code]true[/code], the user can resize the GraphNode.
- [b]Note:[/b] Dragging the handle will only emit the [signal resize_request] signal, the GraphNode needs to be resized manually.
- </member>
- <member name="selectable" type="bool" setter="set_selectable" getter="is_selectable" default="true">
- If [code]true[/code], the user can select the GraphNode.
- </member>
- <member name="selected" type="bool" setter="set_selected" getter="is_selected" default="false">
- If [code]true[/code], the GraphNode is selected.
- </member>
- <member name="show_close" type="bool" setter="set_show_close_button" getter="is_close_button_visible" default="false">
- If [code]true[/code], the close button will be visible.
- [b]Note:[/b] Pressing it will only emit the [signal close_request] signal, the GraphNode needs to be removed manually.
- </member>
- <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
- Base text writing direction.
- </member>
<member name="title" type="String" setter="set_title" getter="get_title" default="&quot;&quot;">
The text displayed in the GraphNode's title bar.
</member>
</members>
<signals>
- <signal name="close_request">
- <description>
- Emitted when the GraphNode is requested to be closed. Happens on clicking the close button (see [member show_close]).
- </description>
- </signal>
- <signal name="dragged">
- <param index="0" name="from" type="Vector2" />
- <param index="1" name="to" type="Vector2" />
- <description>
- Emitted when the GraphNode is dragged.
- </description>
- </signal>
- <signal name="node_deselected">
- <description>
- Emitted when the GraphNode is deselected.
- </description>
- </signal>
- <signal name="node_selected">
- <description>
- Emitted when the GraphNode is selected.
- </description>
- </signal>
- <signal name="position_offset_changed">
- <description>
- Emitted when the GraphNode is moved.
- </description>
- </signal>
- <signal name="raise_request">
- <description>
- Emitted when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode.
- </description>
- </signal>
- <signal name="resize_request">
- <param index="0" name="new_minsize" type="Vector2" />
- <description>
- Emitted when the GraphNode is requested to be resized. Happens on dragging the resizer handle (see [member resizable]).
- </description>
- </signal>
<signal name="slot_updated">
- <param index="0" name="idx" type="int" />
+ <param index="0" name="slot_index" type="int" />
<description>
Emitted when any GraphNode's slot is updated.
</description>
</signal>
</signals>
- <constants>
- <constant name="OVERLAY_DISABLED" value="0" enum="Overlay">
- No overlay is shown.
- </constant>
- <constant name="OVERLAY_BREAKPOINT" value="1" enum="Overlay">
- Show overlay set in the [theme_item breakpoint] theme property.
- </constant>
- <constant name="OVERLAY_POSITION" value="2" enum="Overlay">
- Show overlay set in the [theme_item position] theme property.
- </constant>
- </constants>
<theme_items>
- <theme_item name="close_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
- The color modulation applied to the close button icon.
- </theme_item>
<theme_item name="resizer_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
The color modulation applied to the resizer icon.
</theme_item>
- <theme_item name="title_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
- Color of the title text.
- </theme_item>
- <theme_item name="close_h_offset" data_type="constant" type="int" default="12">
- </theme_item>
- <theme_item name="close_offset" data_type="constant" type="int" default="22">
- The vertical offset of the close button.
- </theme_item>
- <theme_item name="port_offset" data_type="constant" type="int" default="0">
+ <theme_item name="port_h_offset" data_type="constant" type="int" default="0">
Horizontal offset for the ports.
</theme_item>
<theme_item name="separation" data_type="constant" type="int" default="2">
The vertical distance between ports.
</theme_item>
- <theme_item name="title_h_offset" data_type="constant" type="int" default="0">
- Horizontal offset of the title text.
- </theme_item>
- <theme_item name="title_offset" data_type="constant" type="int" default="26">
- Vertical offset of the title text.
- </theme_item>
- <theme_item name="title_font" data_type="font" type="Font">
- Font used for the title text.
- </theme_item>
- <theme_item name="close" data_type="icon" type="Texture2D">
- The icon for the close button, visible when [member show_close] is enabled.
- </theme_item>
<theme_item name="port" data_type="icon" type="Texture2D">
The icon used for representing ports.
</theme_item>
<theme_item name="resizer" data_type="icon" type="Texture2D">
- The icon used for resizer, visible when [member resizable] is enabled.
- </theme_item>
- <theme_item name="breakpoint" data_type="style" type="StyleBox">
- The background used when [member overlay] is set to [constant OVERLAY_BREAKPOINT].
+ The icon used for the resizer, visible when [member GraphElement.resizable] is enabled.
</theme_item>
- <theme_item name="frame" data_type="style" type="StyleBox">
- The default background for [GraphNode].
+ <theme_item name="panel" data_type="style" type="StyleBox">
+ The default background for the slot area of the [GraphNode].
</theme_item>
- <theme_item name="position" data_type="style" type="StyleBox">
- The background used when [member overlay] is set to [constant OVERLAY_POSITION].
- </theme_item>
- <theme_item name="selected_frame" data_type="style" type="StyleBox">
- The background used when the [GraphNode] is selected.
+ <theme_item name="panel_selected" data_type="style" type="StyleBox">
+ The [StyleBox] used for the slot area when selected.
</theme_item>
<theme_item name="slot" data_type="style" type="StyleBox">
The [StyleBox] used for each slot of the [GraphNode].
</theme_item>
+ <theme_item name="titlebar" data_type="style" type="StyleBox">
+ The [StyleBox] used for the title bar of the [GraphNode].
+ </theme_item>
+ <theme_item name="titlebar_selected" data_type="style" type="StyleBox">
+ The [StyleBox] used for the title bar of the [GraphNode] when it is selected.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index a8f0f19256..f39d8788ad 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -50,7 +50,7 @@
<description>
Returns the acceleration in m/s² of the device's accelerometer sensor, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
Note this method returns an empty [Vector3] when running from the editor even when your device has an accelerometer. You must export your project to a supported device to read values from the accelerometer.
- [b]Note:[/b] This method only works on iOS, Android, and UWP. On other platforms, it always returns [constant Vector3.ZERO].
+ [b]Note:[/b] This method only works on Android and iOS. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_action_raw_strength" qualifiers="const">
@@ -166,7 +166,7 @@
<return type="Vector3" />
<description>
Returns the magnetic field strength in micro-Tesla for all axes of the device's magnetometer sensor, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
- [b]Note:[/b] This method only works on Android, iOS and UWP. On other platforms, it always returns [constant Vector3.ZERO].
+ [b]Note:[/b] This method only works on Android and iOS. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_mouse_button_mask" qualifiers="const">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index d4a6b57c58..2efe47a012 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -298,7 +298,7 @@
<return type="String" />
<description>
Returns the name of the host OS.
- On Windows, this is [code]"Windows"[/code] or [code]"UWP"[/code] if exported on Universal Windows Platform.
+ On Windows, this is [code]"Windows"[/code].
On macOS, this is [code]"macOS"[/code].
On Linux-based operating systems, this is [code]"Linux"[/code].
On BSD-based operating systems, this is [code]"FreeBSD"[/code], [code]"NetBSD"[/code], [code]"OpenBSD"[/code], or [code]"BSD"[/code] as a fallback.
@@ -309,7 +309,7 @@
[codeblocks]
[gdscript]
match OS.get_name():
- "Windows", "UWP":
+ "Windows":
print("Windows")
"macOS":
print("macOS")
@@ -326,7 +326,6 @@
switch (OS.GetName())
{
case "Windows":
- case "UWP":
GD.Print("Windows");
break;
case "macOS":
@@ -370,7 +369,7 @@
<return type="String" />
<description>
Returns the name of the CPU model on the host machine (e.g. "Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz").
- [b]Note:[/b] This method is only implemented on Windows, macOS, Linux and iOS. On Android, Web and UWP, [method get_processor_name] returns an empty string.
+ [b]Note:[/b] This method is only implemented on Windows, macOS, Linux and iOS. On Android and Web, [method get_processor_name] returns an empty string.
</description>
</method>
<method name="get_restart_on_exit_arguments" qualifiers="const">
@@ -450,7 +449,7 @@
<description>
Returns a string that is unique to the device.
[b]Note:[/b] This string may change without notice if the user reinstalls/upgrades their operating system or changes their hardware. This means it should generally not be used to encrypt persistent data as the data saved before an unexpected ID change would become inaccessible. The returned string may also be falsified using external programs, so do not rely on the string returned by [method get_unique_id] for security purposes.
- [b]Note:[/b] Returns an empty string on Web and UWP, as this method isn't implemented on those platforms yet.
+ [b]Note:[/b] Returns an empty string on Web, as this method isn't implemented on this platform yet.
</description>
</method>
<method name="get_user_data_dir" qualifiers="const">
@@ -473,7 +472,6 @@
For Windows, the major and minor version are returned, as well as the build number. For example, the returned string can look like [code]10.0.9926[/code] for a build of Windows 10, and it can look like [code]6.1.7601[/code] for a build of Windows 7 SP1.
For rolling distributions, such as Arch Linux, an empty string is returned.
For macOS and iOS, the major and minor version are returned, as well as the patch number.
- For UWP, the device family version is returned.
For Android, the SDK version and the incremental build number are returned. If it's a custom ROM, it attempts to return its version instead.
[b]Note:[/b] This method is not supported on the web platform. It returns an empty string.
</description>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index d5495ff7dc..e8a440b76f 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -938,7 +938,7 @@
If [code]true[/code], snaps [Control] node vertices to the nearest pixel to ensure they remain crisp even when the camera moves or zooms.
</member>
<member name="gui/common/swap_cancel_ok" type="bool" setter="" getter="">
- If [code]true[/code], swaps [b]Cancel[/b] and [b]OK[/b] buttons in dialogs on Windows and UWP to follow interface conventions. [method DisplayServer.get_swap_cancel_ok] can be used to query whether buttons are swapped at run-time.
+ If [code]true[/code], swaps [b]Cancel[/b] and [b]OK[/b] buttons in dialogs on Windows to follow interface conventions. [method DisplayServer.get_swap_cancel_ok] can be used to query whether buttons are swapped at run-time.
[b]Note:[/b] This doesn't affect native dialogs such as the ones spawned by [method DisplayServer.dialog_show].
</member>
<member name="gui/common/text_edit_undo_stack_max_size" type="int" setter="" getter="" default="1024">
diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml
index 2a2239f660..be04ebd893 100644
--- a/doc/classes/Resource.xml
+++ b/doc/classes/Resource.xml
@@ -55,23 +55,11 @@
Returns the [RID] of this resource (or an empty RID). Many resources (such as [Texture2D], [Mesh], and so on) are high-level abstractions of resources stored in a specialized server ([DisplayServer], [RenderingServer], etc.), so this function will return the original [RID].
</description>
</method>
- <method name="setup_local_to_scene">
+ <method name="setup_local_to_scene" is_deprecated="true">
<return type="void" />
<description>
Emits the [signal setup_local_to_scene_requested] signal. If [member resource_local_to_scene] is set to [code]true[/code], this method is called from [method PackedScene.instantiate] by the newly duplicated resource within the scene instance.
For most resources, this method performs no logic of its own. Custom behavior can be defined by connecting [signal setup_local_to_scene_requested] from a script, [b]not[/b] by overriding this method.
- [b]Example:[/b] Assign a random value to [code]health[/code] for every duplicated Resource from an instantiated scene, excluding the original.
- [codeblock]
- extends Resource
-
- var health = 0
-
- func _init():
- setup_local_to_scene_requested.connect(randomize_health)
-
- func randomize_health():
- health = randi_range(10, 40)
- [/codeblock]
</description>
</method>
<method name="take_over_path">
@@ -104,7 +92,7 @@
</signal>
<signal name="setup_local_to_scene_requested">
<description>
- Emitted when [method setup_local_to_scene] is called, usually by a newly duplicated resource with [member resource_local_to_scene] set to [code]true[/code]. Custom behavior can be defined by connecting this signal.
+ Emitted by the newly duplicated resource with [member resource_local_to_scene] set to [code]true[/code], when the scene is instantiated. Custom behavior can be defined by connecting this signal.
</description>
</signal>
</signals>
diff --git a/doc/classes/SpringArm3D.xml b/doc/classes/SpringArm3D.xml
index 6e12d9a613..99389fb78d 100644
--- a/doc/classes/SpringArm3D.xml
+++ b/doc/classes/SpringArm3D.xml
@@ -4,7 +4,7 @@
A 3D raycast that dynamically moves its children near the collision point.
</brief_description>
<description>
- [SpringArm3D] casts a ray or a shape along its Z axis and moves all its direct children to the collision point, with an optional margin. This is useful for 3rd person cameras that move closer to the player when inside a tight space (you may need to exclude the player's collider from the [SpringArm3D]'s collision check.
+ [SpringArm3D] casts a ray or a shape along its Z axis and moves all its direct children to the collision point, with an optional margin. This is useful for 3rd person cameras that move closer to the player when inside a tight space (you may need to exclude the player's collider from the [SpringArm3D]'s collision check).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 3eac11792f..d699121557 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -5,6 +5,8 @@
</brief_description>
<description>
Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles which are used to create grid-based maps. A TileMap may have several layers, layouting tiles on top of each other.
+ For performance reasons, all TileMap updates are batched at the end of a frame. Notably, this means that scene tiles from a [TileSetScenesCollectionSource] may be initialized after their parent.
+ To force an update earlier on, call [method update_internals].
</description>
<tutorials>
<link title="Using Tilemaps">$DOCS_URL/tutorials/2d/using_tilemaps.html</link>
@@ -25,7 +27,7 @@
Called with a TileData object about to be used internally by the TileMap, allowing its modification at runtime.
This method is only called if [method _use_tile_data_runtime_update] is implemented and returns [code]true[/code] for the given tile [param coords] and [param layer].
[b]Warning:[/b] The [param tile_data] object's sub-resources are the same as the one in the TileSet. Modifying them might impact the whole TileSet. Instead, make sure to duplicate those resources.
- [b]Note:[/b] If the properties of [param tile_data] object should change over time, use [method force_update] to trigger a TileMap update.
+ [b]Note:[/b] If the properties of [param tile_data] object should change over time, use [method notify_runtime_tile_data_update] to notify the TileMap it needs an update.
</description>
</method>
<method name="_use_tile_data_runtime_update" qualifiers="virtual">
@@ -35,6 +37,7 @@
<description>
Should return [code]true[/code] if the tile at coordinates [param coords] on layer [param layer] requires a runtime update.
[b]Warning:[/b] Make sure this function only return [code]true[/code] when needed. Any tile processed at runtime without a need for it will imply a significant performance penalty.
+ [b]Note:[/b] If the result of this function should changed, use [method notify_runtime_tile_data_update] to notify the TileMap it needs an update.
</description>
</method>
<method name="add_layer">
@@ -73,13 +76,11 @@
Clears cells that do not exist in the tileset.
</description>
</method>
- <method name="force_update">
+ <method name="force_update" is_deprecated="true">
<return type="void" />
<param index="0" name="layer" type="int" default="-1" />
<description>
- Triggers an update of the TileMap. If [param layer] is provided and is positive, only updates the given layer.
- [b]Note:[/b] The TileMap node updates automatically when one of its properties is modified. A manual update is only needed if runtime modifications (implemented in [method _tile_data_runtime_update]) need to be applied.
- [b]Warning:[/b] Updating the TileMap is computationally expensive and may impact performance. Try to limit the number of updates and the tiles they impact (by placing frequently updated tiles in a dedicated layer for example).
+ [i]Deprecated.[/i] See [method notify_runtime_tile_data_update] and [method update_internals].
</description>
</method>
<method name="get_cell_alternative_tile" qualifiers="const">
@@ -301,6 +302,16 @@
Moves the layer at index [param layer] to the given position [param to_position] in the array.
</description>
</method>
+ <method name="notify_runtime_tile_data_update">
+ <return type="void" />
+ <param index="0" name="layer" type="int" default="-1" />
+ <description>
+ Notifies the TileMap node that calls to [method _use_tile_data_runtime_update] or [method _tile_data_runtime_update] will lead to different results. This will thus trigger a TileMap update.
+ If [param layer] is provided, only notifies changes for the given layer. Providing the [param layer] argument (when applicable) is usually preferred for performance reasons.
+ [b]Warning:[/b] Updating the TileMap is computationally expensive and may impact performance. Try to limit the number of calls to this function to avoid unnecessary update.
+ [b]Note:[/b] This does not trigger a direct update of the TileMap, the update will be done at the end of the frame as usual (unless you call [method update_internals]).
+ </description>
+ </method>
<method name="remove_layer">
<return type="void" />
<param index="0" name="layer" type="int" />
@@ -437,11 +448,16 @@
If [param layer] is negative, the layers are accessed from the last one.
</description>
</method>
+ <method name="update_internals">
+ <return type="void" />
+ <description>
+ Triggers a direct update of the TileMap. Usually, calling this function is not needed, as TileMap node updates automatically when one of its properties or cells is modified.
+ However, for performance reasons, those updates are batched and delayed to the end of the frame. Calling this function will force the TileMap to update right away instead.
+ [b]Warning:[/b] Updating the TileMap is computationally expensive and may impact performance. Try to limit the number of updates and how many tiles they impact.
+ </description>
+ </method>
</methods>
<members>
- <member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16">
- The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size.
- </member>
<member name="collision_animatable" type="bool" setter="set_collision_animatable" getter="is_collision_animatable" default="false">
If enabled, the TileMap will see its collisions synced to the physics tick and change its collision type from static to kinematic. This is required to create TileMap-based moving platform.
[b]Note:[/b] Enabling [member collision_animatable] may have a small performance impact, only do it if the TileMap is moving and has colliding tiles.
@@ -452,6 +468,9 @@
<member name="navigation_visibility_mode" type="int" setter="set_navigation_visibility_mode" getter="get_navigation_visibility_mode" enum="TileMap.VisibilityMode" default="0">
Show or hide the TileMap's navigation meshes. If set to [constant VISIBILITY_MODE_DEFAULT], this depends on the show navigation debug settings.
</member>
+ <member name="rendering_quadrant_size" type="int" setter="set_rendering_quadrant_size" getter="get_rendering_quadrant_size" default="16">
+ The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size.
+ </member>
<member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset">
The assigned [TileSet].
</member>
diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml
index ede9688ea8..e12933d64b 100644
--- a/doc/classes/ViewportTexture.xml
+++ b/doc/classes/ViewportTexture.xml
@@ -6,7 +6,7 @@
<description>
Provides the content of a [Viewport] as a dynamic [Texture2D]. This can be used to mix controls, 2D game objects, and 3D game objects in the same scene.
To create a [ViewportTexture] in code, use the [method Viewport.get_texture] method on the target viewport.
- [b]Note:[/b] When local to scene, this texture uses [method Resource.setup_local_to_scene] to set the proxy texture and flags in the local viewport. Local to scene [ViewportTexture]s will return incorrect data until the scene root is ready (see [signal Node.ready]).
+ [b]Note:[/b] A [ViewportTexture] is always local to its scene (see [member Resource.resource_local_to_scene]). If the scene root is not ready, it may return incorrect data (see [signal Node.ready]).
</description>
<tutorials>
<link title="GUI in 3D Demo">https://godotengine.org/asset-library/asset/127</link>
diff --git a/doc/translations/es.po b/doc/translations/es.po
index 77f120ac45..2ebf84d64d 100644
--- a/doc/translations/es.po
+++ b/doc/translations/es.po
@@ -14433,9 +14433,9 @@ msgstr ""
msgid ""
"The amount of restitution once the limits are surpassed. The lower, the more "
-"velocityenergy gets lost."
+"velocity-energy gets lost."
msgstr ""
-"La cantidad de la restitución una vez que se superen los límites. Cuanto más "
+"El monto de la restitución una vez que se superen los límites. Cuanto más "
"bajo, más energía de velocidad se pierde."
msgid "The amount of damping once the slider limits are surpassed."
@@ -17473,13 +17473,6 @@ msgstr ""
"upper_distance]."
msgid ""
-"The amount of restitution once the limits are surpassed. The lower, the more "
-"velocity-energy gets lost."
-msgstr ""
-"El monto de la restitución una vez que se superen los límites. Cuanto más "
-"bajo, más energía de velocidad se pierde."
-
-msgid ""
"Increasing this value will improve the resulting simulation, but can affect "
"performance. Use with care."
msgstr ""
diff --git a/doc/translations/fr.po b/doc/translations/fr.po
index cfcb9c8968..a07195f505 100644
--- a/doc/translations/fr.po
+++ b/doc/translations/fr.po
@@ -4201,9 +4201,6 @@ msgstr ""
"Si [code]true[/code], la lecture commence dès que le AudioStreamPlayer3D est "
"ajouté à la scène."
-msgid "Sets the absolute maximum of the soundlevel, in decibels."
-msgstr "Définit le maximum absolu du niveau sonore, en décibels."
-
msgid "The [AudioStream] resource to be played."
msgstr "La ressource [AudioStream] à jouer."
@@ -19639,15 +19636,6 @@ msgstr ""
"(c'est-à-dire toujours positif)."
msgid ""
-"Returns the angle to the given vector, in radians.\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to.png]Illustration of the returned angle.[/url]"
-msgstr ""
-"Retourne l'angle au vecteur donné, en radians.\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to.png]Illustration de l'angle retourné.[/url]"
-
-msgid ""
"Returns the aspect ratio of this vector, the ratio of [member x] to [member "
"y]."
msgstr "Retourne le ratio de ce vecteur, soit [member x] divisé par [member y]."
diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po
index 8aa591854e..e267d1ceb2 100644
--- a/doc/translations/zh_CN.po
+++ b/doc/translations/zh_CN.po
@@ -79,11 +79,12 @@
# Zae Chao <zaevi@live.com>, 2023.
# SamBillon <sambillon1234+hosted.weblate@gmail.com>, 2023.
# ZhuQiLi <552084128@qq.com>, 2023.
+# HIM049 <HIM_049@163.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2023-08-17 11:10+0000\n"
+"PO-Revision-Date: 2023-09-08 09:58+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot-class-reference/zh_Hans/>\n"
@@ -92,7 +93,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Description"
msgstr "描述"
@@ -1285,10 +1286,10 @@ msgid ""
"depth. Just like the next group ends the previous group, so do the subsequent "
"subgroups."
msgstr ""
-"为接下来的导出属性定义一个新的子分组。这有助于组织检查器面板中的属性。子分组的"
-"工作方式与分组类似,只是它们依赖于一个父级分组。请参阅 [annotation "
+"为接下来的导出属性定义一个新的子分组。有助于组织检查器面板中的属性。子分组的工"
+"作方式与分组类似,只是它们依赖于一个父级分组。见 [annotation "
"@export_group]。\n"
-"另请参见 [constant PROPERTY_USAGE_SUBGROUP]。\n"
+"另见 [constant PROPERTY_USAGE_SUBGROUP]。\n"
"[codeblock]\n"
"@export_group(\"Racer Properties\")\n"
"@export var nickname = \"Nick\"\n"
@@ -1323,10 +1324,10 @@ msgstr ""
"[codeblock]\n"
"@icon(\"res://path/to/class/icon.svg\")\n"
"[/codeblock]\n"
-"[b]注意:[/b] 只有脚本可以有一个自定义的图标。不支持内部类。\n"
-"[b]注意:[/b] 由于注解描述了它们的主题,[code]@icon[/code] 注解必须放在类定义"
-"和继承之前。\n"
-"[b]注意:[/b] 不同于其他注解,[code]@icon[/code] 注解的参数必须是一个字符串 "
+"[b]注意:[/b]只有脚本可以有一个自定义的图标。不支持内部类。\n"
+"[b]注意:[/b]由于注解描述了它们的主题,[code]@icon[/code] 注解必须放在类定义和"
+"继承之前。\n"
+"[b]注意:[/b]不同于其他注解,[code]@icon[/code] 注解的参数必须是一个字符串 "
"(不支持常量表达式)。"
msgid ""
@@ -1426,7 +1427,7 @@ msgid ""
"default values."
msgstr ""
"使具有静态变量的脚本在所有引用丢失之后不会持久化。当该脚本再次加载时,这些静态"
-"变量将恢复为它们的默认值。"
+"变量将恢复为默认值。"
msgid ""
"Mark the current script as a tool script, allowing it to be loaded and "
@@ -1540,9 +1541,9 @@ msgstr ""
"var f = abs(Vector3i(-7, -8, -9))\n"
"# f=(7, 8, 9)\n"
"[/codeblock]\n"
-"[b]注意:[/b] 为了更好的类型安全,请使用 [method absf]、[method absi]、"
-"[method Vector2.abs]、[method Vector2i.abs]、[method Vector3.abs]、[method "
-"Vector3i.abs]、[method Vector4.abs] 或 [method Vector4i.abs]。"
+"[b]注意:[/b]为了更好的类型安全,请使用 [method absf]、[method absi]、[method "
+"Vector2.abs]、[method Vector2i.abs]、[method Vector3.abs]、[method Vector3i."
+"abs]、[method Vector4.abs] 或 [method Vector4i.abs]。"
msgid ""
"Returns the absolute value of float parameter [param x] (i.e. positive "
@@ -1893,41 +1894,6 @@ msgstr ""
"[/codeblock]"
msgid ""
-"Returns an \"eased\" value of [param x] based on an easing function defined "
-"with [param curve]. This easing function is based on an exponent. The [param "
-"curve] can be any floating-point number, with specific values leading to the "
-"following behaviors:\n"
-"[codeblock]\n"
-"- Lower than -1.0 (exclusive): Ease in-out\n"
-"- 1.0: Linear\n"
-"- Between -1.0 and 0.0 (exclusive): Ease out-in\n"
-"- 0.0: Constant\n"
-"- Between 0.0 to 1.0 (exclusive): Ease out\n"
-"- 1.0: Linear\n"
-"- Greater than 1.0 (exclusive): Ease in\n"
-"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
-"See also [method smoothstep]. If you need to perform more advanced "
-"transitions, use [method Tween.interpolate_value]."
-msgstr ""
-"基于用 [param curve] 定义的缓动函数返回 [param x] 的“缓动后”的值。该缓动函数是"
-"基于指数的。[param curve] 可以是任意浮点数,具体数值会导致以下行为:\n"
-"[codeblock]\n"
-"- 低于 -1.0(开区间):缓入缓出\n"
-"- -1.0:线性\n"
-"- 在 -1.0 和 0.0 之间(开区间):缓出缓入\n"
-"- 0.0:恒定\n"
-"- 在 0.0 到 1.0 之间(开区间):缓出\n"
-"- 1.0:线性\n"
-"- 大于 1.0(开区间):缓入\n"
-"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"ease_cheatsheet.png]ease() 曲线值速查表[/url]\n"
-"另请参阅 [method smoothstep]。如果你需要执行更高级的过渡,请使用 [method "
-"Tween.interpolate_value]。"
-
-msgid ""
"Returns a human-readable name for the given [enum Error] code.\n"
"[codeblock]\n"
"print(OK) # Prints 0\n"
@@ -2250,7 +2216,7 @@ msgstr ""
"code]。当 [param a] 和 [param b] 为引用类型时,如果它们的引用对象相同,那么返"
"回 [code]true[/code]。\n"
"[codeblock]\n"
-"# Vector2 is a value type\n"
+"# Vector2 是值类型\n"
"var vec2_a = Vector2(0, 0)\n"
"var vec2_b = Vector2(0, 0)\n"
"var vec2_c = Vector2(1, 1)\n"
@@ -2258,7 +2224,7 @@ msgstr ""
"is_same(vec2_a, vec2_b) # true\n"
"is_same(vec2_a, vec2_c) # false\n"
"\n"
-"# Array is a reference type\n"
+"# Array 是引用类型\n"
"var arr_a = []\n"
"var arr_b = []\n"
"is_same(arr_a, arr_a) # true\n"
@@ -3303,51 +3269,6 @@ msgstr ""
"[/codeblock]"
msgid ""
-"Returns the result of smoothly interpolating the value of [param x] between "
-"[code]0[/code] and [code]1[/code], based on the where [param x] lies with "
-"respect to the edges [param from] and [param to].\n"
-"The return value is [code]0[/code] if [code]x <= from[/code], and [code]1[/"
-"code] if [code]x >= to[/code]. If [param x] lies between [param from] and "
-"[param to], the returned value follows an S-shaped curve that maps [param x] "
-"between [code]0[/code] and [code]1[/code].\n"
-"This S-shaped curve is the cubic Hermite interpolator, given by [code]f(y) = "
-"3*y^2 - 2*y^3[/code] where [code]y = (x-from) / (to-from)[/code].\n"
-"[codeblock]\n"
-"smoothstep(0, 2, -5.0) # Returns 0.0\n"
-"smoothstep(0, 2, 0.5) # Returns 0.15625\n"
-"smoothstep(0, 2, 1.0) # Returns 0.5\n"
-"smoothstep(0, 2, 2.0) # Returns 1.0\n"
-"[/codeblock]\n"
-"Compared to [method ease] with a curve value of [code]-1.6521[/code], [method "
-"smoothstep] returns the smoothest possible curve with no sudden changes in "
-"the derivative. If you need to perform more advanced transitions, use [Tween] "
-"or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
-"-1.6521) return values[/url]"
-msgstr ""
-"返回 [param x] 在 [code]0[/code] 和 [code]1[/code] 之间平滑插值的结果,基于 "
-"[param x] 相对于边 [param from] 和 [param to] 的位置。\n"
-"如果 [code]x <= from[/code],则返回值为 [code]0[/code];如果 [code]x >= to[/"
-"code],则返回值为 [code]1[/code]。如果 [param x] 位于 [param from] 和 [param "
-"to] 之间,则返回值遵循一条将 [param x] 映射到 [code]0[/code] 和 [code]1[/"
-"code] 之间的 S 形曲线。\n"
-"这条 S 形曲线是三次 Hermite 插值器,由 [code]f(y) = 3*y^2 - 2*y^3[/code] 给"
-"出,其中 [code]y = (x-from) / (to-from)[/code]。\n"
-"[codeblock]\n"
-"smoothstep(0, 2, -5.0) # 返回 0.0\n"
-"smoothstep(0, 2, 0.5) # 返回 0.15625\n"
-"smoothstep(0, 2, 1.0) # 返回 0.5\n"
-"smoothstep(0, 2, 2.0) # 返回 1.0\n"
-"[/codeblock]\n"
-"与曲线值为 [code]-1.6521[/code] 的 [method ease] 相比,[method smoothstep] 返"
-"回最平滑的曲线,导数没有突然变化。如果您需要执行更高级的过渡,请使用 [Tween] "
-"或 [AnimationPlayer]。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"smoothstep_ease_comparison.png]smoothstep() 与 ease(x, -1.6521) 返回值的比较[/"
-"url]"
-
-msgid ""
"Returns the multiple of [param step] that is the closest to [param x]. This "
"can also be used to round a floating point number to an arbitrary number of "
"decimals.\n"
@@ -5830,7 +5751,7 @@ msgid "Represents the size of the [enum Variant.Operator] enum."
msgstr "代表 [enum Variant.Operator] 枚举的大小。"
msgid "A 3D axis-aligned bounding box."
-msgstr "3D 轴对齐包围盒。"
+msgstr "3D 轴对齐边界框。"
msgid ""
"[AABB] consists of a position, a size, and several utility functions. It is "
@@ -6096,7 +6017,7 @@ msgstr ""
"建的按钮。[param action] 将在按钮被按下时传递给 [signal custom_action] 信"
"号。\n"
"如果 [param right] 为 [code]true[/code],按钮会被放置在所有同级按钮的右侧。\n"
-"您可以使用 [method remove_button] 方法从对话框中移除使用该方法创建的按钮。"
+"可以使用 [method remove_button] 方法从对话框中移除使用该方法创建的按钮。"
msgid ""
"Adds a button with label [param name] and a cancel action to the dialog and "
@@ -6758,7 +6679,7 @@ msgid ""
msgstr ""
"将 [Texture2D] 分配给给定的帧。帧 ID 从 0 开始,因此第一帧的 ID 为 0,动画的最"
"后一帧的 ID 为 [member frames] - 1。\n"
-"您可以定义最多 [constant MAX_FRAMES] 个纹理,但要记住,只有 0 到 [member "
+"最多可以定义 [constant MAX_FRAMES] 个纹理,但要记住,只有 0 到 [member "
"frames] - 1 的帧会成为动画的一部分。"
msgid ""
@@ -6775,8 +6696,8 @@ msgid ""
"the animation to take new frames into account. The maximum number of frames "
"is [constant MAX_FRAMES]."
msgstr ""
-"动画中要使用的帧数。虽然您可以使用 [method set_frame_texture] 独立创建帧,但是"
-"您需要为动画设置此值以考虑新帧。最大帧数为 [constant MAX_FRAMES]。"
+"动画中要使用的帧数。虽然你可以使用 [method set_frame_texture] 独立创建帧,但是"
+"你需要为动画设置这个值,才能考虑到新帧。最大帧数为 [constant MAX_FRAMES]。"
msgid ""
"If [code]true[/code], the animation will only play once and will not loop "
@@ -7711,6 +7632,26 @@ msgid ""
"[AnimationNodeBlendTree]."
msgstr "在 [AnimationNodeBlendTree] 中将三个动画中的两个动画相加。"
+msgid ""
+"A resource to add to an [AnimationNodeBlendTree]. Blends two animations out "
+"of three additively out of three based on the amount value.\n"
+"This animation node has three inputs:\n"
+"- The base animation to add to\n"
+"- A \"-add\" animation to blend with when the blend amount is negative\n"
+"- A \"+add\" animation to blend with when the blend amount is positive\n"
+"If the absolute value of the amount is greater than [code]1.0[/code], the "
+"animation connected to \"in\" port is blended with the amplified animation "
+"connected to \"-add\"/\"+add\" port."
+msgstr ""
+"可添加到 [AnimationNodeBlendTree] 的资源。根据取值将三个动画中的两个进行加法混"
+"合。\n"
+"这个动画节点有三个输入:\n"
+"- 加法混合的基础动画\n"
+"- 混合取值为负时进行混合的“-add”动画\n"
+"- 混合取值为正时进行混合的“+add”动画\n"
+"如果取值的绝对值大于 [code]1.0[/code],则与“in”端口相连的动画相混合的是放大后"
+"的与“-add”/“+add”端口相连的动画。"
+
msgid "An input animation for an [AnimationNodeBlendTree]."
msgstr "[AnimationNodeBlendTree] 的输入动画。"
@@ -7759,6 +7700,28 @@ msgid ""
msgstr "在 [AnimationNodeBlendTree] 中将三个动画中的两个进行线性混合。"
msgid ""
+"A resource to add to an [AnimationNodeBlendTree]. Blends two animations out "
+"of three linearly out of three based on the amount value.\n"
+"This animation node has three inputs:\n"
+"- The base animation to blend with\n"
+"- A \"-blend\" animation to blend with when the blend amount is negative "
+"value\n"
+"- A \"+blend\" animation to blend with when the blend amount is positive "
+"value\n"
+"In general, the blend value should be in the [code][-1.0, 1.0][/code] range. "
+"Values outside of this range can blend amplified animations, however, "
+"[AnimationNodeAdd3] works better for this purpose."
+msgstr ""
+"可添加到 [AnimationNodeBlendTree] 的资源。根据取值将三个动画中的两个进行线性混"
+"合。\n"
+"这个动画节点有三个输入:\n"
+"- 加法混合的基础动画\n"
+"- 混合取值为负时进行混合的“-blend”动画\n"
+"- 混合取值为正时进行混合的“+blend”动画\n"
+"一般而言,混合值应该在 [code][-1.0, 1.0][/code] 的范围内。在此范围外的取值能够"
+"混合放大后的动画,然而这种场合使用 [AnimationNodeAdd3] 更合适。"
+
+msgid ""
"A set of [AnimationRootNode]s placed on a virtual axis, crossfading between "
"the two adjacent ones. Used by [AnimationTree]."
msgstr ""
@@ -7785,9 +7748,9 @@ msgid ""
"using the [param at_index] argument. If you use the default value for [param "
"at_index], the point is inserted at the end of the blend points array."
msgstr ""
-"在虚拟轴上 [param pos] 设定的给定位置,添加一个新点代表 [param node]。您可以使"
-"用 [param at_index] 参数在特定的索引处插入新点。如果您使用 [param at_index] 的"
-"默认值,该点会被插入到混合点数组的末尾。"
+"在虚拟轴上 [param pos] 设定的给定位置添加一个代表 [param node] 的新点。你可以"
+"使用 [param at_index] 参数将其插入到特定的索引处。如果使用 [param at_index] 的"
+"默认值,这个点会被插入到混合点数组的末尾。"
msgid "Returns the number of points on the blend axis."
msgstr "返回混合轴上的点的数量。"
@@ -7843,6 +7806,11 @@ msgid "The interpolation between animations is linear."
msgstr "动画之间的插值是线性的。"
msgid ""
+"The blend space plays the animation of the animation node which blending "
+"position is closest to. Useful for frame-by-frame 2D animations."
+msgstr "混合空间播放混合位置最接近的动画节点的动画。可用于逐帧的 2D 动画。"
+
+msgid ""
"Similar to [constant BLEND_MODE_DISCRETE], but starts the new animation at "
"the last animation's playback position."
msgstr ""
@@ -7857,14 +7825,34 @@ msgstr ""
"[AnimationTree] 使用。"
msgid ""
+"A resource used by [AnimationNodeBlendTree].\n"
+"[AnimationNodeBlendSpace1D] represents a virtual 2D space on which "
+"[AnimationRootNode]s are placed. Outputs the linear blend of the three "
+"adjacent animations using a [Vector2] weight. Adjacent in this context means "
+"the three [AnimationRootNode]s making up the triangle that contains the "
+"current value.\n"
+"You can add vertices to the blend space with [method add_blend_point] and "
+"automatically triangulate it by setting [member auto_triangles] to "
+"[code]true[/code]. Otherwise, use [method add_triangle] and [method "
+"remove_triangle] to triangulate the blend space by hand."
+msgstr ""
+"[AnimationNodeBlendTree] 使用的资源。\n"
+"[AnimationNodeBlendSpace1D] 代表放置 [AnimationRootNode] 的虚拟 2D 空间。输出"
+"的是使用 [Vector2] 权重对相邻的三个动画进行线性混合的结果。此处的“相邻”指的是"
+"构成包含当前值的三角形的三个 [AnimationRootNode]。\n"
+"你可以使用 [method add_blend_point] 向混合空间中添加顶点,将 [member "
+"auto_triangles] 设为 [code]true[/code] 可以将其自动三角形化。否则,请使用 "
+"[method add_triangle] 和 [method remove_triangle] 手动对混合空间进行三角形化。"
+
+msgid ""
"Adds a new point that represents a [param node] at the position set by [param "
"pos]. You can insert it at a specific index using the [param at_index] "
"argument. If you use the default value for [param at_index], the point is "
"inserted at the end of the blend points array."
msgstr ""
-"在 [param pos] 设定的位置添加一个代表 [param node] 的新点。您可以使用 [param "
-"at_index] 参数将它插入到特定的索引中。如果您使用 [param at_index] 的默认值,这"
-"个点会被插入到混合点数组的末尾。"
+"在 [param pos] 设定的位置添加一个代表 [param node] 的新点。你可以使用 [param "
+"at_index] 参数将其插入到特定的索引中。如果使用 [param at_index] 的默认值,这个"
+"点会被插入到混合点数组的末尾。"
msgid ""
"Creates a new triangle using three points [param x], [param y], and [param "
@@ -7939,12 +7927,47 @@ msgstr ""
"用于复杂动画的许多类型 [AnimationNode] 的子树。由 [AnimationTree] 使用。"
msgid ""
+"This animation node may contain a sub-tree of any other type animation nodes, "
+"such as [AnimationNodeTransition], [AnimationNodeBlend2], "
+"[AnimationNodeBlend3], [AnimationNodeOneShot], etc. This is one of the most "
+"commonly used animation node roots.\n"
+"An [AnimationNodeOutput] node named [code]output[/code] is created by default."
+msgstr ""
+"这个动画节点可以包含任何其他类型动画节点的子树,例如 "
+"[AnimationNodeTransition]、[AnimationNodeBlend2]、[AnimationNodeBlend3]、"
+"[AnimationNodeOneShot] 等。这是最常用的动画节点根之一。\n"
+"默认会创建一个名为 [code]output[/code] 的 [AnimationNodeOutput] 节点。"
+
+msgid ""
+"Adds an [AnimationNode] at the given [param position]. The [param name] is "
+"used to identify the created sub animation node later."
+msgstr ""
+"在给定的位置 [param position] 添加一个 [AnimationNode]。[param name] 用于后续"
+"识别该创建的子动画节点。"
+
+msgid ""
"Connects the output of an [AnimationNode] as input for another "
"[AnimationNode], at the input port specified by [param input_index]."
msgstr ""
"连接一个 [AnimationNode] 的输出作为另一个 [AnimationNode] 的输入,连接在 "
"[param input_index] 指定的输入端口。"
+msgid "Disconnects the animation node connected to the specified input."
+msgstr "断开连接到指定输入端的动画节点。"
+
+msgid "Returns the sub animation node with the specified [param name]."
+msgstr "返回名称为 [param name] 的子动画节点。"
+
+msgid ""
+"Returns the position of the sub animation node with the specified [param "
+"name]."
+msgstr "返回名称为 [param name] 的子动画节点的位置。"
+
+msgid ""
+"Returns [code]true[/code] if a sub animation node with specified [param name] "
+"exists."
+msgstr "如果存在名称为 [param name] 的动画子节点,则返回 [code]true[/code]。"
+
msgid "Removes a sub animation node."
msgstr "移除一个子动画节点。"
@@ -7982,6 +8005,126 @@ msgid "Plays an animation once in an [AnimationNodeBlendTree]."
msgstr "在 [AnimationNodeBlendTree] 中播放一次动画。"
msgid ""
+"A resource to add to an [AnimationNodeBlendTree]. This animation node will "
+"execute a sub-animation and return once it finishes. Blend times for fading "
+"in and out can be customized, as well as filters.\n"
+"After setting the request and changing the animation playback, the one-shot "
+"node automatically clears the request on the next process frame by setting "
+"its [code]request[/code] value to [constant ONE_SHOT_REQUEST_NONE].\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# Play child animation connected to \"shot\" port.\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FIRE)\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FIRE\n"
+"\n"
+"# Abort child animation connected to \"shot\" port.\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_ABORT)\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_ABORT\n"
+"\n"
+"# Abort child animation with fading out connected to \"shot\" port.\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FADE_OUT)\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FADE_OUT\n"
+"\n"
+"# Get current state (read-only).\n"
+"animation_tree.get(\"parameters/OneShot/active\")\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/OneShot/active\"]\n"
+"\n"
+"# Get current internal state (read-only).\n"
+"animation_tree.get(\"parameters/OneShot/internal_active\")\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/OneShot/internal_active\"]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// Play child animation connected to \"shot\" port.\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.Fire);\n"
+"\n"
+"// Abort child animation connected to \"shot\" port.\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.Abort);\n"
+"\n"
+"// Abort child animation with fading out connected to \"shot\" port.\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.FadeOut);\n"
+"\n"
+"// Get current state (read-only).\n"
+"animationTree.Get(\"parameters/OneShot/active\");\n"
+"\n"
+"// Get current internal state (read-only).\n"
+"animationTree.Get(\"parameters/OneShot/internal_active\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"添加到 [AnimationNodeBlendTree] 的资源。这个动画节点将执行子动画并在完成后返"
+"回。可以自定义淡入和淡出的混合时间以及过滤器。\n"
+"在设置请求并更改动画播放后,一次性节点会在下一个处理帧中通过将其 "
+"[code]request[/code] 值设置为 [constant ONE_SHOT_REQUEST_NONE] 来自动清除请"
+"求。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# 播放连接到 “shot” 端口的子动画。\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FIRE)\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FIRE\n"
+"\n"
+"# 中止连接到 “shot” 端口的子动画。\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_ABORT)\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FADE_OUT\n"
+"\n"
+"# 使用淡出的方法中止连接到 “shot”端口的子动画。\n"
+"animation_tree.set(\"parameters/OneShot/request\", AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FADE_OUT)\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/OneShot/request\"] = AnimationNodeOneShot."
+"ONE_SHOT_REQUEST_FADE_OUT\n"
+"\n"
+"# 获取当前状态(只读)。\n"
+"animation_tree.get(\"parameters/OneShot/active\"))\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/OneShot/active\"]\n"
+"\n"
+"# 获取当前内部状态(只读)。\n"
+"animation_tree.get(\"parameters/OneShot/internal_active\")\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/OneShot/internal_active\"]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// 播放连接到 “shot” 端口的子动画。\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.Fire);\n"
+"\n"
+"// 中止连接到 “shot” 端口的子动画。\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.Abort);\n"
+"\n"
+"// 使用淡出的方法中止连接到 “shot”端口的子动画。\n"
+"animationTree.Set(\"parameters/OneShot/request\", (int)AnimationNodeOneShot."
+"OneShotRequest.FadeOut);\n"
+"\n"
+"// 获取当前状态(只读)。\n"
+"animationTree.Get(\"parameters/OneShot/active\");\n"
+"\n"
+"// 获取当前内部状态(只读)。\n"
+"animationTree.Get(\"parameters/OneShot/internal_active\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
+msgid ""
"If [code]true[/code], the sub-animation will restart automatically after "
"finishing.\n"
"In other words, to start auto restarting, the animation must be played once "
@@ -8061,6 +8204,41 @@ msgid ""
msgstr "带有多个 [AnimationRootNode] 的状态机,用于 [AnimationTree]。"
msgid ""
+"Contains multiple [AnimationRootNode]s representing animation states, "
+"connected in a graph. State transitions can be configured to happen "
+"automatically or via code, using a shortest-path algorithm. Retrieve the "
+"[AnimationNodeStateMachinePlayback] object from the [AnimationTree] node to "
+"control it programmatically.\n"
+"[b]Example:[/b]\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var state_machine = $AnimationTree.get(\"parameters/playback\")\n"
+"state_machine.travel(\"some_state\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var stateMachine = GetNode<AnimationTree>(\"AnimationTree\").Get(\"parameters/"
+"playback\") as AnimationNodeStateMachinePlayback;\n"
+"stateMachine.Travel(\"some_state\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"包含表示动画状态的多个 [AnimationRootNode],以图的形式连接。可以使用最短路径算"
+"法,将节点过渡配置为自动发生或通过代码发生。要以编程的方式控制过渡,请从 "
+"[AnimationTree] 节点获取 [AnimationNodeStateMachinePlayback] 对象。\n"
+"[b]示例:[/b]\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var state_machine = $AnimationTree.get(\"parameters/playback\")\n"
+"state_machine.travel(\"some_state\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var stateMachine = GetNode<AnimationTree>(\"AnimationTree\").Get(\"parameters/"
+"playback\") as AnimationNodeStateMachinePlayback;\n"
+"stateMachine.Travel(\"some_state\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
+msgid ""
"Adds a new animation node to the graph. The [param position] is used for "
"display in the editor."
msgstr "向图中添加一个新的动画节点。[param position] 用于在编辑器中显示。"
@@ -8400,6 +8578,34 @@ msgstr ""
"如果 [member advance_condition] 和 [member advance_expression] 检查为真,则自"
"动使用该过渡(如果已分配)。"
+msgid ""
+"Blends two animations subtractively inside of an [AnimationNodeBlendTree]."
+msgstr "在 [AnimationNodeBlendTree] 中对两个动画进行减法混合。"
+
+msgid ""
+"A resource to add to an [AnimationNodeBlendTree]. Blends two animations "
+"subtractively based on the amount value.\n"
+"This animation node is usually used for pre-calculation to cancel out any "
+"extra poses from the animation for the \"add\" animation source in "
+"[AnimationNodeAdd2] or [AnimationNodeAdd3].\n"
+"In general, the blend value should be in the [code][0.0, 1.0][/code] range, "
+"but values outside of this range can be used for amplified or inverted "
+"animations.\n"
+"[b]Note:[/b] This calculation is different from using a negative value in "
+"[AnimationNodeAdd2], since the transformation matrices do not satisfy the "
+"commutative law. [AnimationNodeSub2] multiplies the transformation matrix of "
+"the inverted animation from the left side, while negative [AnimationNodeAdd2] "
+"multiplies it from the right side."
+msgstr ""
+"要添加到 [AnimationNodeBlendTree] 的资源。根据数量值以减法方式混合两个动画。\n"
+"该动画节点通常用于预先计算,从 [AnimationNodeAdd2] 或 [AnimationNodeAdd3] "
+"的“添加”动画源的动画中抵消额外的姿势。\n"
+"一般而言,混合值应在 [code][0.0, 1.0][/code] 范围内,但超出该范围的值可用于放"
+"大或反转动画。\n"
+"[b]注意:[/b]因为变换矩阵不满足交换律,这个计算不同于在 [AnimationNodeAdd2] 中"
+"使用负值。[AnimationNodeSub2] 从左侧乘以反转动画的变换矩阵,而负的 "
+"[AnimationNodeAdd2] 则是从右侧相乘。"
+
msgid "AnimationTree"
msgstr "AnimationTree"
@@ -8428,10 +8634,141 @@ msgstr ""
msgid "A time-seeking animation node used in [AnimationTree]."
msgstr "对时间进行检索的动画节点,在 [AnimationTree] 中使用。"
+msgid ""
+"This animation node can be used to cause a seek command to happen to any sub-"
+"children of the animation graph. Use to play an [Animation] from the start or "
+"a certain playback position inside the [AnimationNodeBlendTree].\n"
+"After setting the time and changing the animation playback, the time seek "
+"node automatically goes into sleep mode on the next process frame by setting "
+"its [code]seek_request[/code] value to [code]-1.0[/code].\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# Play child animation from the start.\n"
+"animation_tree.set(\"parameters/TimeSeek/seek_request\", 0.0)\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/TimeSeek/seek_request\"] = 0.0\n"
+"\n"
+"# Play child animation from 12 second timestamp.\n"
+"animation_tree.set(\"parameters/TimeSeek/seek_request\", 12.0)\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/TimeSeek/seek_request\"] = 12.0\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// Play child animation from the start.\n"
+"animationTree.Set(\"parameters/TimeSeek/seek_request\", 0.0);\n"
+"\n"
+"// Play child animation from 12 second timestamp.\n"
+"animationTree.Set(\"parameters/TimeSeek/seek_request\", 12.0);\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"这个动画节点可用于使检索命令发生在动画图的任何次级子节点上。用于从 "
+"[AnimationNodeBlendTree] 的开头或某个特定播放位置开始播放 [Animation]。\n"
+"设置时间并更改动画播放后,时间检索节点会在下一个处理帧中将其 "
+"[code]seek_request[/code] 值设置为 [code]-1.0[/code],自动进入睡眠模式。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# 从开始处播放子动画。\n"
+"animation_tree.set(\"parameters/TimeSeek/seek_request\", 0.0)\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/TimeSeek/seek_request\"] = 0.0\n"
+"\n"
+"# 从 12 秒的时间戳开始播放子动画。\n"
+"animation_tree.set(\"parameters/TimeSeek/seek_request\", 12.0)\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/TimeSeek/seek_request\"] = 12.0\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// 从开始处播放子动画。\n"
+"animationTree.Set(\"parameters/TimeSeek/seek_request\", 0.0);\n"
+"\n"
+"// 从 12 秒的时间戳开始播放子动画。\n"
+"animationTree.Set(\"parameters/TimeSeek/seek_request\", 12.0);\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid "A transition within an [AnimationTree] connecting two [AnimationNode]s."
msgstr "[AnimationTree] 中连接两个 [AnimationNode] 的过渡。"
msgid ""
+"Simple state machine for cases which don't require a more advanced "
+"[AnimationNodeStateMachine]. Animations can be connected to the inputs and "
+"transition times can be specified.\n"
+"After setting the request and changing the animation playback, the transition "
+"node automatically clears the request on the next process frame by setting "
+"its [code]transition_request[/code] value to empty.\n"
+"[b]Note:[/b] When using a cross-fade, [code]current_state[/code] and "
+"[code]current_index[/code] change to the next state immediately after the "
+"cross-fade begins.\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# Play child animation connected to \"state_2\" port.\n"
+"animation_tree.set(\"parameters/Transition/transition_request\", "
+"\"state_2\")\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/Transition/transition_request\"] = \"state_2\"\n"
+"\n"
+"# Get current state name (read-only).\n"
+"animation_tree.get(\"parameters/Transition/current_state\")\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/Transition/current_state\"]\n"
+"\n"
+"# Get current state index (read-only).\n"
+"animation_tree.get(\"parameters/Transition/current_index\")\n"
+"# Alternative syntax (same result as above).\n"
+"animation_tree[\"parameters/Transition/current_index\"]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// Play child animation connected to \"state_2\" port.\n"
+"animationTree.Set(\"parameters/Transition/transition_request\", "
+"\"state_2\");\n"
+"\n"
+"// Get current state name (read-only).\n"
+"animationTree.Get(\"parameters/Transition/current_state\");\n"
+"\n"
+"// Get current state index (read-only).\n"
+"animationTree.Get(\"parameters/Transition/current_index\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"适用于不需要更高级 [AnimationNodeStateMachine] 的情况的简单状态机。可以将动画"
+"连接到输入,还可以指定过渡时间。\n"
+"设置请求并更改动画播放后,过渡节点会在下一个处理帧中通过将其 "
+"[code]transition_request[/code] 值设置为空,来自动清除请求。\n"
+"[b]注意:[/b]使用交叉淡入淡出时,[code]current_state[/code] 和 "
+"[code]current_index[/code] 在交叉淡入淡出开始后立即更改为下一个状态。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# 播放连接到 “state_2” 端口的子动画。\n"
+"animation_tree.set(\"parameters/Transition/transition_request\", "
+"\"state_2\")\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/Transition/transition_request\"] = \"state_2\"\n"
+"\n"
+"# 获取当前状态名称(只读)。\n"
+"animation_tree.get(\"parameters/Transition/current_state\")\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/Transition/current_state\"]\n"
+"\n"
+"# 获取当前状态索引(只读)。\n"
+"animation_tree.get(\"parameters/Transition/current_index\"))\n"
+"# 替代语法(与上述结果相同)。\n"
+"animation_tree[\"parameters/Transition/current_index\"]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// 播放连接到 “state_2” 端口的子动画。\n"
+"animationTree.Set(\"parameters/Transition/transition_request\", "
+"\"state_2\");\n"
+"\n"
+"// 获取当前状态名称(只读)。\n"
+"animationTree.Get(\"parameters/Transition/current_state\");\n"
+"\n"
+"// 获取当前状态索引(只读)。\n"
+"animationTree.Get(\"parameters/Transition/current_index\");\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
+msgid ""
"Returns whether the animation restarts when the animation transitions from "
"the other animation."
msgstr "返回当动画从另一个动画过渡时,该动画是否重新开始。"
@@ -8473,6 +8810,30 @@ msgstr "连接到输入的每个动画之间的交叉渐变时间(秒)。"
msgid "A node used for animation playback."
msgstr "用于播放动画的节点。"
+msgid ""
+"An animation player is used for general-purpose playback of animations. It "
+"contains a dictionary of [AnimationLibrary] resources and custom blend times "
+"between animation transitions.\n"
+"Some methods and properties use a single key to reference an animation "
+"directly. These keys are formatted as the key for the library, followed by a "
+"forward slash, then the key for the animation within the library, for example "
+"[code]\"movement/run\"[/code]. If the library's key is an empty string (known "
+"as the default library), the forward slash is omitted, being the same key "
+"used by the library.\n"
+"[AnimationPlayer] is better-suited than [Tween] for more complex animations, "
+"for example ones with non-trivial timings. It can also be used over [Tween] "
+"if the animation track editor is more convenient than doing it in code.\n"
+"Updating the target properties of animations occurs at the process frame."
+msgstr ""
+"动画播放器用于动画的通用播放。它包含 [AnimationLibrary] 资源的字典和动画过渡之"
+"间的自定义混合时间。\n"
+"某些方法和属性使用单个键直接引用动画。这些键的格式为动画库的键,后跟正斜杠,然"
+"后是动画库内动画的键,例如 [code]\"movement/run\"[/code]。如果动画库的键为空字"
+"符串(称为默认库),则省略正斜杠,与动画库使用相同的键。\n"
+"[AnimationPlayer] 比 [Tween] 更适合用于复杂动画,例如不规则计时的动画。如果用"
+"动画轨道编辑器比用代码实现更方便,也可以优先于 [Tween] 使用。\n"
+"更新动画的目标属性是在处理帧中进行的。"
+
msgid "A virtual function for processing after key getting during playback."
msgstr "一个用于播放期间键获取之后的处理的虚函数。"
@@ -8519,6 +8880,17 @@ msgstr ""
"返回包含 [param animation] 的 [AnimationLibrary] 的键;如果找不到,则返回一个"
"空的 [StringName]。"
+msgid ""
+"Returns the first [AnimationLibrary] with key [param name] or [code]null[/"
+"code] if not found.\n"
+"To get the [AnimationPlayer]'s global animation library, use "
+"[code]get_animation_library(\"\")[/code]."
+msgstr ""
+"返回第一个键为 [param name] 的 [AnimationLibrary],如果没有找到则返回 "
+"[code]null[/code]。\n"
+"要获得 [AnimationPlayer] 的全局动画库,请使用 "
+"[code]get_animation_library(\"\")[/code]。"
+
msgid "Returns the list of stored library keys."
msgstr "返回存储库的键名列表。"
@@ -8560,6 +8932,36 @@ msgstr ""
"另见 [method stop]。"
msgid ""
+"Plays the animation with key [param name]. Custom blend times and speed can "
+"be set.\n"
+"The [param from_end] option only affects when switching to a new animation "
+"track, or if the same track but at the start or end. It does not affect "
+"resuming playback that was paused in the middle of an animation. If [param "
+"custom_speed] is negative and [param from_end] is [code]true[/code], the "
+"animation will play backwards (which is equivalent to calling [method "
+"play_backwards]).\n"
+"The [AnimationPlayer] keeps track of its current or last played animation "
+"with [member assigned_animation]. If this method is called with that same "
+"animation [param name], or with no [param name] parameter, the assigned "
+"animation will resume playing if it was paused.\n"
+"[b]Note:[/b] The animation will be updated the next time the "
+"[AnimationPlayer] is processed. If other variables are updated at the same "
+"time this is called, they may be updated too early. To perform the update "
+"immediately, call [code]advance(0)[/code]."
+msgstr ""
+"播放键名为 [param name] 的动画。可以设置自定义混合时间和速度。\n"
+"[param from_end] 选项仅在切换到新的动画轨道,或在相同轨道的开始或结束时生效。"
+"它不影响在动画被中途暂停时恢复播放。如果 [param custom_speed] 为负,且 [param "
+"from_end] 为 [code]true[/code],则动画将向后播放(相当于调用 [method "
+"play_backwards])。\n"
+"[AnimationPlayer] 使用 [member assigned_animation] 跟踪其当前或上次播放的动"
+"画。如果使用相同的动画 [param name] 或没有 [param name] 参数调用此方法,则分配"
+"的动画将在暂停时恢复播放。\n"
+"[b]注意:[/b]动画将在下次处理 [AnimationPlayer] 时更新。如果在调用该方法的同时"
+"更新了其他变量,则它们可能更新得太早。要立即执行更新,请调用 [code]advance(0)"
+"[/code]。"
+
+msgid ""
"Queues an animation for playback once the current one is done.\n"
"[b]Note:[/b] If a looped animation is currently playing, the queued animation "
"will never play unless the looped animation is stopped somehow."
@@ -8793,6 +9195,22 @@ msgstr ""
"合)、[AnimationNodeBlendSpace1D](能够在[b]两个[/b] [AnimationNode] 之间进行线"
"性混合)等。"
+msgid "A node used for advanced animation transitions in an [AnimationPlayer]."
+msgstr "用于 [AnimationPlayer] 中高级动画过渡的节点。"
+
+msgid ""
+"A node used for advanced animation transitions in an [AnimationPlayer].\n"
+"[b]Note:[/b] When linked with an [AnimationPlayer], several properties and "
+"methods of the corresponding [AnimationPlayer] will not function as expected. "
+"Playback and transitions should be handled using only the [AnimationTree] and "
+"its constituent [AnimationNode](s). The [AnimationPlayer] node should be used "
+"solely for adding, deleting, and editing animations."
+msgstr ""
+"用于 [AnimationPlayer] 中高级动画过渡的节点。\n"
+"[b]注意:[/b]与 [AnimationPlayer] 连接时,该 [AnimationPlayer] 的部分属性和方"
+"法将不会像预期的那样发挥作用。播放和过渡应该只使用 [AnimationTree] 和组成它的 "
+"[AnimationNode] 来处理。[AnimationPlayer] 节点应仅用于添加、删除和编辑动画。"
+
msgid "Manually advance the animations by the specified time (in seconds)."
msgstr "手动将动画前进指定的时间(单位为秒)。"
@@ -8855,7 +9273,7 @@ msgstr ""
" move_and_slide()\n"
"[/gdscript]\n"
"[/codeblocks]\n"
-"通过将其与 [method get_root_motion_position_accumulator] 结合使用,您可以更正"
+"通过将其与 [method get_root_motion_position_accumulator] 结合使用,你可以更正"
"确地应用根运动位置来考虑节点的旋转。\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -10722,35 +11140,6 @@ msgid "Returns the number of elements in the array."
msgstr "返回数组中元素的个数。"
msgid ""
-"Returns the slice of the [Array], from [param begin] (inclusive) to [param "
-"end] (exclusive), as a new [Array].\n"
-"The absolute value of [param begin] and [param end] will be clamped to the "
-"array size, so the default value for [param end] makes it slice to the size "
-"of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for "
-"[code]arr.slice(1, arr.size())[/code]).\n"
-"If either [param begin] or [param end] are negative, they will be relative to "
-"the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for "
-"[code]arr.slice(0, arr.size() - 2)[/code]).\n"
-"If specified, [param step] is the relative index between source elements. It "
-"can be negative, then [param begin] must be higher than [param end]. For "
-"example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3]"
-"[/code].\n"
-"If [param deep] is true, each element will be copied by value rather than by "
-"reference."
-msgstr ""
-"返回该 [Array] 的切片,是从 [param begin](含)到 [param end](不含)的全新 "
-"[Array]。\n"
-"[param begin] 和 [param end] 的绝对值会按数组大小进行限制,所以 [param end] 的"
-"默认值会切到数组大小为止(即 [code]arr.slice(1)[/code] 是 [code]arr.slice(1, "
-"arr.size())[/code] 的简写)。\n"
-"如果 [param begin] 或 [param end] 为负,则表示相对于数组的末尾(即 [code]arr."
-"slice(0, -2)[/code] 是 [code]arr.slice(0, arr.size() - 2)[/code] 的简写)。\n"
-"如果指定了 [param step],则会用作原始元素的索引间距。这个参数可以为负,此时 "
-"[param begin] 必须大于 [param end]。例如,[code][0, 1, 2, 3, 4, 5].slice(5, "
-"1, -2)[/code] 会返回 [code][5, 3][/code]。\n"
-"如果 [param deep] 为 true,则每个元素都会按值复制,而不是按引用复制。"
-
-msgid ""
"Sorts the array.\n"
"[b]Note:[/b] The sorting algorithm used is not [url=https://en.wikipedia.org/"
"wiki/Sorting_algorithm#Stability]stable[/url]. This means that values "
@@ -10847,7 +11236,7 @@ msgstr ""
"[b]注意:[/b]排序所使用的算法并不[url=https://zh.wikipedia.org/wiki/"
"%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95#%E7%A9%A9%E5%AE%9A%E6%80%A7]稳定[/url]。"
"也就是说,使用 [method sort_custom] 时相等的值之间的顺序可能会改变。\n"
-"[b]注意:[/b]您不能随机化返回值,因为堆排序算法期望确定的结果。随机化返回值将"
+"[b]注意:[/b]你不能随机化返回值,因为堆排序算法期望确定的结果。随机化返回值将"
"导致意外行为。\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -11667,7 +12056,7 @@ msgid ""
msgstr ""
"返回一个数组,其中包含 AStar2D 在给定点之间找到的路径中的点。数组从路径的起点"
"到终点进行排序。\n"
-"[b]注意:[/b] 该方法不是线程安全的。如果从 [Thread] 调用,它将返回一个空的 "
+"[b]注意:[/b]该方法不是线程安全的。如果从 [Thread] 调用,它将返回一个空的 "
"[PackedVector2Array] 并打印一条错误消息。"
msgid "Returns the position of the point associated with the given [param id]."
@@ -11715,6 +12104,115 @@ msgstr ""
"段路程的总成本时,[param weight_scale] 要乘以 [method _compute_cost] 的结果。"
msgid ""
+"An implementation of A* for finding the shortest path between two vertices on "
+"a connected graph in 3D space."
+msgstr "A* 的一种实现,用于寻找 3D 空间中连接图中的两个顶点之间的最短路径。"
+
+msgid ""
+"A* (A star) is a computer algorithm used in pathfinding and graph traversal, "
+"the process of plotting short paths among vertices (points), passing through "
+"a given set of edges (segments). It enjoys widespread use due to its "
+"performance and accuracy. Godot's A* implementation uses points in 3D space "
+"and Euclidean distances by default.\n"
+"You must add points manually with [method add_point] and create segments "
+"manually with [method connect_points]. Once done, you can test if there is a "
+"path between two points with the [method are_points_connected] function, get "
+"a path containing indices by [method get_id_path], or one containing actual "
+"coordinates with [method get_point_path].\n"
+"It is also possible to use non-Euclidean distances. To do so, create a class "
+"that extends [code]AStar3D[/code] and override methods [method _compute_cost] "
+"and [method _estimate_cost]. Both take two indices and return a length, as is "
+"shown in the following example.\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"class MyAStar:\n"
+" extends AStar3D\n"
+"\n"
+" func _compute_cost(u, v):\n"
+" return abs(u - v)\n"
+"\n"
+" func _estimate_cost(u, v):\n"
+" return min(0, abs(u - v) - 1)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public partial class MyAStar : AStar3D\n"
+"{\n"
+" public override float _ComputeCost(long fromId, long toId)\n"
+" {\n"
+" return Mathf.Abs((int)(fromId - toId));\n"
+" }\n"
+"\n"
+" public override float _EstimateCost(long fromId, long toId)\n"
+" {\n"
+" return Mathf.Min(0, Mathf.Abs((int)(fromId - toId)) - 1);\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[method _estimate_cost] should return a lower bound of the distance, i.e. "
+"[code]_estimate_cost(u, v) <= _compute_cost(u, v)[/code]. This serves as a "
+"hint to the algorithm because the custom [code]_compute_cost[/code] might be "
+"computation-heavy. If this is not the case, make [method _estimate_cost] "
+"return the same value as [method _compute_cost] to provide the algorithm with "
+"the most accurate information.\n"
+"If the default [method _estimate_cost] and [method _compute_cost] methods are "
+"used, or if the supplied [method _estimate_cost] method returns a lower bound "
+"of the cost, then the paths returned by A* will be the lowest-cost paths. "
+"Here, the cost of a path equals the sum of the [method _compute_cost] results "
+"of all segments in the path multiplied by the [code]weight_scale[/code]s of "
+"the endpoints of the respective segments. If the default methods are used and "
+"the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], "
+"then this equals the sum of Euclidean distances of all segments in the path."
+msgstr ""
+"A*(A 星)是一种计算机算法,用于寻路和图遍历,是通过一组给定的边(线段),在顶"
+"点(点)之间绘制短路径的过程。由于其性能和准确性,它被广泛使用。Godot 的 A* 实"
+"现默认使用 3D 空间中的点和欧几里得距离。\n"
+"你需要使用 [method add_point] 手动添加点,并使用 [method connect_points] 手动"
+"创建线段。完成后,可以使用 [method are_points_connected] 函数,测试两点之间是"
+"否存在路径,通过 [method get_id_path] 获取包含索引的路径,或使用 [method "
+"get_point_path] 获取包含实际坐标的路径。\n"
+"也可以使用非欧几里得距离。为此,创建一个扩展 [code]AStar3D[/code] 的类,并覆盖"
+"方法 [method _compute_cost] 和 [method _estimate_cost]。两者都接受两个索引并返"
+"回一个长度,如以下示例所示。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"class MyAStar:\n"
+" extends AStar3D\n"
+"\n"
+" func _compute_cost(u, v):\n"
+" return abs(u - v)\n"
+"\n"
+" func _estimate_cost(u, v):\n"
+" return min(0, abs(u - v) - 1)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public partial class MyAStar : AStar3D\n"
+"{\n"
+" public override float _ComputeCost(long fromId, long toId)\n"
+" {\n"
+" return Mathf.Abs((int)(fromId - toId));\n"
+" }\n"
+"\n"
+" public override float _EstimateCost(long fromId, long toId)\n"
+" {\n"
+" return Mathf.Min(0, Mathf.Abs((int)(fromId - toId)) - 1);\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[method _estimate_cost] 应该返回距离的下限,即 [code]_estimate_cost(u, v) <= "
+"_compute_cost(u, v)[/code]。这可以作为算法的提示,因为自定义 "
+"[code]_compute_cost[/code] 可能计算量很大。如果不是这种情况,请使 [method "
+"_estimate_cost] 返回与 [method _compute_cost] 相同的值,以便为算法提供最准确的"
+"信息。\n"
+"如果使用默认的 [method _estimate_cost] 和 [method _compute_cost] 方法,或者如"
+"果提供的 [method _estimate_cost] 方法返回成本的下限,则 A* 返回的路径将是成本"
+"最低的路径。这里,路径的代价等于路径中所有段的 [method _compute_cost] 结果乘以"
+"各个段端点的权重 [code]weight_scale[/code] 之和。如果使用默认方法,并且所有点"
+"的 [code]weight_scale[/code] 设置为 [code]1.0[/code],则这等于路径中所有段的欧"
+"几里得距离之和。"
+
+msgid ""
"Called when computing the cost between two connected points.\n"
"Note that this function is hidden in the default [code]AStar3D[/code] class."
msgstr ""
@@ -12009,8 +12507,8 @@ msgid ""
"adding a known large number of points at once, such as points on a grid. New "
"capacity must be greater or equals to old capacity."
msgstr ""
-"该函数为 [param num_nodes] 个点内部预留空间。如果您一次添加了大量已知数量的"
-"点,例如网格上的点,则此函数很有用。新的容量必须大于或等于旧的容量。"
+"该函数为 [param num_nodes] 个点内部预留空间。如果一次添加了大量已知数量的点,"
+"例如网格上的点,则此函数很有用。新的容量必须大于或等于旧的容量。"
msgid ""
"An implementation of A* for finding the shortest path between two points on a "
@@ -12118,7 +12616,7 @@ msgid ""
msgstr ""
"返回一个数组,其中包含 AStarGrid2D 在给定点之间找到的路径上的点。数组从路径的"
"起点到终点排序。\n"
-"[b]注意:[/b]该方法不是线程安全的。如果从 [Thread] 中调用它,它将返回一个空的 "
+"[b]注意:[/b]该方法不是线程安全的。如果从 [Thread] 中调用它,它将返回一个空的 "
"[PackedVector3Array] 并打印一个错误消息。"
msgid ""
@@ -12210,7 +12708,7 @@ msgid ""
"scaling in pathfinding."
msgstr ""
"启用或禁用跳跃,以跳过中间点并加快搜索算法的速度。\n"
-"[b]注意:[/b] 目前,打开它会在寻路过程中忽略权重缩放。"
+"[b]注意:[/b]目前,打开它会在寻路过程中忽略权重缩放。"
msgid ""
"The offset of the grid which will be applied to calculate the resulting point "
@@ -12221,6 +12719,13 @@ msgstr ""
"发生变化,需要在查找下一条路径之前调用 [method update]。"
msgid ""
+"The region of grid cells available for pathfinding. If changed, [method "
+"update] needs to be called before finding the next path."
+msgstr ""
+"栅格上用来寻路的区域。如果发生变化,需要在查找下一条路径之前调用 [method "
+"update]。"
+
+msgid ""
"The size of the grid (number of cells of size [member cell_size] on each "
"axis). If changed, [method update] needs to be called before finding the next "
"path.\n"
@@ -12751,9 +13256,9 @@ msgid ""
"Use it to create a custom equalizer if [AudioEffectEQ6], [AudioEffectEQ10] or "
"[AudioEffectEQ21] don't fit your needs."
msgstr ""
-"音频均衡器的基础类。让你可以控制频率。\n"
-"如果 [AudioEffectEQ6]、[AudioEffectEQ10] 或 [AudioEffectEQ21] 不符合您的需求,"
-"请使用它来创建一个自定义均衡器。"
+"音频均衡器的基类。让你可以控制频率。\n"
+"如果 [AudioEffectEQ6]、[AudioEffectEQ10] 或 [AudioEffectEQ21] 不符合你的需求,"
+"请用它来创建自定义均衡器。"
msgid ""
"AudioEffectEQ gives you control over frequencies. Use it to compensate for "
@@ -12816,8 +13321,8 @@ msgid ""
"frequencies from 22 Hz to 22000 Hz.\n"
"Each frequency can be modulated between -60/+24 dB."
msgstr ""
-"向音频总线添加一个 21 频段均衡器音频效果。使您可以控制从 22 Hz 到 22000 Hz 的"
-"频率。\n"
+"向音频总线添加一个 21 频段均衡器音频效果。可以控制从 22 Hz 到 22000 Hz 的频"
+"率。\n"
"每个频率都可以在 -60/+24 dB 之间进行调制。"
msgid ""
@@ -12874,7 +13379,7 @@ msgid ""
"frequencies from 32 Hz to 10000 Hz.\n"
"Each frequency can be modulated between -60/+24 dB."
msgstr ""
-"向音频总线添加一个 6 频段均衡器音频效果。使您可以控制从 32 Hz 到 10000 Hz 的频"
+"向音频总线添加一个 6 频段均衡器音频效果。可以控制从 32 Hz 到 10000 Hz 的频"
"率。\n"
"每个频率都可以在 -60/+24 dB 之间进行调制。"
@@ -13307,8 +13812,8 @@ msgid ""
msgstr ""
"如果使用 [method make_current] 将监听器设为当前,则返回 [code]true[/code],否"
"则返回 [code]false[/code]。\n"
-"[b]注意:[/b] 场景树中标记为“当前”的 AudioListener3D 可能不止一个,但只会使用"
-"最后被设置为当前的那个。"
+"[b]注意:[/b]场景树中标记为“当前”的 AudioListener3D 可能不止一个,但只会使用最"
+"后被设置为当前的那个。"
msgid "Enables the listener. This will override the current camera's listener."
msgstr "启用该监听器。将覆盖当前相机的监听器。"
@@ -13357,6 +13862,13 @@ msgid ""
"indices (and optionally channel)."
msgstr "返回分配给给定总线和效果索引(以及可选的通道)的[AudioEffectInstance]。"
+msgid ""
+"Returns the index of the bus with the name [param bus_name]. Returns "
+"[code]-1[/code] if no bus with the specified name exist."
+msgstr ""
+"返回名称为 [param bus_name] 的总线的索引。如果不存在指定名称的总线,则返回 "
+"[code]-1[/code]。"
+
msgid "Returns the name of the bus with the index [param bus_idx]."
msgstr "返回索引为 [param bus_idx] 的总线的名称。"
@@ -13760,7 +14272,7 @@ msgid ""
"[/codeblocks]"
msgstr ""
"包含以字节为单位的音频数据。\n"
-"您可以使用下面的代码片段,加载文件而无需事先导入它。请记住,此代码段将整个文件"
+"你可以使用下面的代码片段,加载文件而无需事先导入它。请记住,此代码段将整个文件"
"加载到内存中,对于大文件(数百兆字节或更多)可能并不理想。\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -13948,7 +14460,7 @@ msgid ""
"If [code]true[/code], the playback is paused. You can resume it by setting "
"[code]stream_paused[/code] to [code]false[/code]."
msgstr ""
-"如果为 [code]true[/code],则暂停播放。您可以通过将 [code]stream_paused[/code] "
+"如果为 [code]true[/code],则暂停播放。你可以通过将 [code]stream_paused[/code] "
"设置为 [code]false[/code] 来恢复播放。"
msgid "Volume of sound, in dB."
@@ -14147,9 +14659,6 @@ msgstr ""
"听者在 [member emission_angle_degrees] 之外且 [member emission_angle_enabled] "
"被设置时使用的衰减系数,单位是分贝。"
-msgid "Sets the absolute maximum of the soundlevel, in decibels."
-msgstr "设置声级的绝对最大值,以分贝为单位。"
-
msgid ""
"The distance past which the sound can no longer be heard at all. Only has an "
"effect if set to a value greater than [code]0.0[/code]. [member max_distance] "
@@ -14526,8 +15035,8 @@ msgid ""
"\"draw\" signal. The visual state of the button is defined by the [enum "
"DrawMode] enum."
msgstr ""
-"返回用于绘制按钮的视觉状态。当您通过覆盖 _draw() 或连接到“draw”信号来实现您自"
-"己的绘制代码时,这很有用。按钮的视觉状态由 [enum DrawMode] 枚举定义。"
+"返回用于绘制按钮的视觉状态。主要可以通过覆盖 _draw() 或连接到“draw”信号来实现"
+"你自己的绘制代码。按钮的视觉状态由 [enum DrawMode] 枚举定义。"
msgid ""
"Returns [code]true[/code] if the mouse has entered the button and has not "
@@ -14889,9 +15398,9 @@ msgid ""
"stored metallic in the red channel, roughness in the blue, and ambient "
"occlusion in the green you could reduce the number of textures you use."
msgstr ""
-"指定 [member ao_texture] 的通道,其中存储环境遮挡信息。当您在一个纹理中存储多"
-"个效果的信息时,这很有用。例如,如果您将金属效果存储在R通道中,将粗糙度存储在B"
-"通道中,将环境遮挡存储在G通道中,就可以减少您使用的纹理数量。"
+"指定 [member ao_texture] 的通道,其中存储环境遮挡信息。可以用来在一个纹理中存"
+"储多个效果的信息。例如,如果你将金属效果存储在 R 通道中,将粗糙度存储在 B 通道"
+"中,将环境遮挡存储在 G 通道中,就可以减少你使用的纹理数量。"
msgid ""
"The color used by the backlight effect. Represents the light passing through "
@@ -16662,10 +17171,42 @@ msgstr "将位图中指定位置的元素设置为指定值。"
msgid "Sets a rectangular portion of the bitmap to the specified value."
msgstr "将位图的矩形部分设置为指定值。"
+msgid "A joint used with [Skeleton2D] to control and animate other nodes."
+msgstr "与 [Skeleton2D] 一起使用的关节,能够控制并动画其他节点。"
+
+msgid ""
+"A hierarchy of [Bone2D]s can be bound to a [Skeleton2D] to control and "
+"animate other [Node2D] nodes.\n"
+"You can use [Bone2D] and [Skeleton2D] nodes to animate 2D meshes created with "
+"the [Polygon2D] UV editor.\n"
+"Each bone has a [member rest] transform that you can reset to with [method "
+"apply_rest]. These rest poses are relative to the bone's parent.\n"
+"If in the editor, you can set the rest pose of an entire skeleton using a "
+"menu option, from the code, you need to iterate over the bones to set their "
+"individual rest poses."
+msgstr ""
+"[Bone2D] 层级结构可以绑定到 [Skeleton2D] 上,控制并动画其他 [Node2D] 节点。\n"
+"你可以使用 [Bone2D] 和 [Skeleton2D] 节点对使用 [Polygon2D] UV 编辑器创建的 2D "
+"网格进行动画。\n"
+"每个骨骼都有一个 [member rest] 变换,你可以用 [method apply_rest] 来重置到这个"
+"变换。这些放松姿势是相对于骨骼的父节点而言的。\n"
+"如果在编辑器中,你可以使用菜单选项设置整个骨架的放松姿势,从代码中,你需要遍历"
+"骨骼来设置它们各自的放松姿势。"
+
msgid "Stores the node's current transforms in [member rest]."
msgstr "将节点当前的变换存储在 [member rest] 中。"
msgid ""
+"Returns whether this [Bone2D] is going to autocalculate its length and bone "
+"angle using its first [Bone2D] child node, if one exists. If there are no "
+"[Bone2D] children, then it cannot autocalculate these values and will print a "
+"warning."
+msgstr ""
+"如果该 [Bone2D] 存在骨骼子节点,则返回是否要使用第一个 [Bone2D] 子节点自动计算"
+"其长度和骨骼角度。如果没有 [Bone2D] 子节点,则无法自动计算这些值,会打印一条警"
+"告。"
+
+msgid ""
"Returns the angle of the bone in the [Bone2D].\n"
"[b]Note:[/b] This is different from the [Bone2D]'s rotation. The bone's angle "
"is the rotation of the bone shown by the gizmo, which is unaffected by the "
@@ -16718,7 +17259,7 @@ msgid ""
"Rest transform of the bone. You can reset the node's transforms to this value "
"using [method apply_rest]."
msgstr ""
-"骨骼的放松变换。您可以使用 [method apply_rest] 将节点的变换重置为这个值。"
+"骨骼的放松变换。你可以使用 [method apply_rest] 将节点的变换重置为这个值。"
msgid ""
"А node that dynamically copies or overrides the 3D transform of a bone in its "
@@ -16762,6 +17303,16 @@ msgstr ""
"设置该 BoneAttachment3D 节点到其应使用的外部骨架的 [NodePath]。请参阅 [method "
"set_use_external_skeleton] 以启用外部 [Skeleton3D] 节点。"
+msgid ""
+"Sets whether the BoneAttachment3D node will use an external [Skeleton3D] node "
+"rather than attempting to use its parent node as the [Skeleton3D]. When set "
+"to [code]true[/code], the BoneAttachment3D node will use the external "
+"[Skeleton3D] node set in [method set_external_skeleton]."
+msgstr ""
+"设置该 BoneAttachment3D 节点是否将使用外部 [Skeleton3D] 节点,而不是尝试使用其"
+"父节点作为 [Skeleton3D]。当设置为 [code]true[/code] 时,BoneAttachment3D 节点"
+"将使用 [method set_external_skeleton] 中设置的外部 [Skeleton3D] 节点。"
+
msgid "The index of the attached bone."
msgstr "所附着骨骼的索引。"
@@ -17193,6 +17744,13 @@ msgstr ""
"当此属性被启用时,过大而无法容纳按钮的文本会被剪掉,当被禁用时,按钮将始终有足"
"够的宽度来容纳文本。"
+msgid ""
+"When enabled, the button's icon will expand/shrink to fit the button's size "
+"while keeping its aspect. See also [theme_item icon_max_width]."
+msgstr ""
+"启用后,将在保持按钮图标长宽比的前提下对该图标进行扩展/收缩,从而适应按钮的大"
+"小。另见 [theme_item icon_max_width]。"
+
msgid "Flat buttons don't display decoration."
msgstr "平面按钮不显示装饰。"
@@ -17207,6 +17765,16 @@ msgstr ""
"[StyleBox] 的 [code]content_margin_*[/code] 属性。"
msgid ""
+"Specifies if the icon should be aligned horizontally to the left, right, or "
+"center of a button. Uses the same [enum HorizontalAlignment] constants as the "
+"text alignment. If centered horizontally and vertically, text will draw on "
+"top of the icon."
+msgstr ""
+"指定图标在按钮上水平对齐的方式应该为左对齐、右对齐还是居中对齐。请使用与文本对"
+"齐相同的 [enum HorizontalAlignment] 常量。如果水平居中并且垂直居中,则文本将被"
+"绘制在图标之上。"
+
+msgid ""
"Language code used for line-breaking and text shaping algorithms, if left "
"empty current locale is used instead."
msgstr "语言代码,用于断行和文本塑形算法,如果留空则使用当前区域设置。"
@@ -17225,6 +17793,16 @@ msgstr ""
"设置文本超出节点的边界矩形时的裁剪行为。有关所有模式的描述,请参阅 [enum "
"TextServer.OverrunBehavior]。"
+msgid ""
+"Specifies if the icon should be aligned vertically to the top, bottom, or "
+"center of a button. Uses the same [enum VerticalAlignment] constants as the "
+"text alignment. If centered horizontally and vertically, text will draw on "
+"top of the icon."
+msgstr ""
+"指定图标在按钮上垂直对齐的方式应该为顶端对齐、底部对齐还是居中对齐。请使用与文"
+"本对齐相同的 [enum VerticalAlignment] 常量。如果水平居中并且垂直居中,则文本将"
+"被绘制在图标之上。"
+
msgid "Default text [Color] of the [Button]."
msgstr "该 [Button] 的默认文本 [Color]。"
@@ -18081,16 +18659,16 @@ msgid ""
"[member SystemFont.multichannel_signed_distance_field] can be enabled in the "
"inspector."
msgstr ""
-"相机的缩放。 设置为 [code]Vector(2, 2)[/code]的缩放值会使通过视口看到的尺寸翻"
+"相机的缩放。 设置为 [code]Vector(2, 2)[/code] 的缩放值会使通过视口看到的尺寸翻"
"倍。设置为 [code]Vector(0.5, 0.5)[/code]的缩放值会使会使通过视口看到的尺寸减"
"半。\n"
-"[b]注意:[/b] [member FontFile.oversampling] [i]不会[/i] 考虑 [Camera2D]的缩放"
-"值。这意味着放大/缩小将导致位图字体和光栅化(非MSDF)动态字体看起来模糊或像素"
+"[b]注意:[/b][member FontFile.oversampling] [i]不会[/i]考虑 [Camera2D] 的缩放"
+"值。这意味着放大/缩小将导致位图字体和光栅化(非 MSDF)动态字体看起来模糊或像素"
"化,除非字体是[CanvasLayer]的一部分从而使其忽略相机缩放。为了确保文本无论如何"
-"缩放都保持清晰,您可以通过启用 [member ProjectSettings.gui/theme/"
+"缩放都保持清晰,你可以通过启用 [member ProjectSettings.gui/theme/"
"default_font_multichannel_signed_distance_field] (仅适用于默认项目字体)来启"
-"用MSDF字体渲染,或在自定义字体的动态字体导入选项中启用[b]多通道带符号距离场[/"
-"b]。对于系统字体,可以在检查器中启用[member SystemFont."
+"用 MSDF 字体渲染,或在自定义字体的动态字体导入选项中启用[b]多通道带符号距离场"
+"[/b]。对于系统字体,可以在检查器中启用 [member SystemFont."
"multichannel_signed_distance_field] 。"
msgid ""
@@ -18107,14 +18685,14 @@ msgid ""
"The camera updates during physics frames (see [constant Node."
"NOTIFICATION_INTERNAL_PHYSICS_PROCESS])."
msgstr ""
-"相机在物理帧期间更新(请参阅 [constant Node.NOTIFICATION_INTERVAL "
-"_PHYSICS_PROCESS])。"
+"相机在物理帧期间更新(见 [constant Node."
+"NOTIFICATION_INTERNAL_PHYSICS_PROCESS])。"
msgid ""
"The camera updates during process frames (see [constant Node."
"NOTIFICATION_INTERNAL_PROCESS])."
msgstr ""
-"相机在进程帧期间更新(请参阅 [constant Node.NOTIFICATION_INTERNAL_PROCESS])。"
+"相机在进程帧期间更新(见 [constant Node.NOTIFICATION_INTERNAL_PROCESS])。"
msgid "Camera node, displays from a point of view."
msgstr "相机节点,会从某个角度进行显示。"
@@ -18142,6 +18720,12 @@ msgstr ""
"如果这是当前相机,则将其从当前相机中移除。如果 [param enable_next] 为 "
"[code]true[/code],则请求使下一个相机(如果有)成为当前相机。"
+msgid ""
+"Returns the projection matrix that this camera uses to render to its "
+"associated viewport. The camera must be part of the scene tree to function."
+msgstr ""
+"返回该相机用于渲染至关联视口的投影矩阵。相机必须是场景树的一部分才能正常工作。"
+
msgid "Returns the camera's RID from the [RenderingServer]."
msgstr "从 [RenderingServer] 返回该相机的 RID。"
@@ -18179,30 +18763,6 @@ msgstr ""
"位置。"
msgid ""
-"Returns [code]true[/code] if the given position is behind the camera (the "
-"blue part of the linked diagram). [url=https://raw.githubusercontent.com/"
-"godotengine/godot-docs/master/img/camera3d_position_frustum.png]See this "
-"diagram[/url] for an overview of position query methods.\n"
-"[b]Note:[/b] A position which returns [code]false[/code] may still be outside "
-"the camera's field of view."
-msgstr ""
-"如果给定位置在相机后面(链接图的蓝色部分),则返回 [code]true[/code]。"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"camera3d_position_frustum.png]查看此图[/url]以了解位置查询方法的概述。\n"
-"[b]注意:[/b]返回 [code]false[/code] 的位置可能仍然在相机的视野之外。"
-
-msgid ""
-"Returns [code]true[/code] if the given position is inside the camera's "
-"frustum (the green part of the linked diagram). [url=https://raw."
-"githubusercontent.com/godotengine/godot-docs/master/img/"
-"camera3d_position_frustum.png]See this diagram[/url] for an overview of "
-"position query methods."
-msgstr ""
-"如果给定位置在相机的视锥(链接图的绿色部分)内,则返回 [code]true[/code]。"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"camera3d_position_frustum.png]查看此图[/url]以了解位置查询方法的概述。"
-
-msgid ""
"Makes this camera the current camera for the [Viewport] (see class "
"description). If the camera node is outside the scene tree, it will attempt "
"to become current once it's added."
@@ -18333,7 +18893,7 @@ msgstr ""
"剔除掩码,描述该相机渲染了哪些 [member VisualInstance3D.layers]。默认情况下,"
"20 个用户可见层全都被渲染。\n"
"[b]注意:[/b]由于 [member cull_mask] 允许总共存储 32 个层,因此另外 12 个层仅"
-"供引擎内部使用,不会在编辑器中公开。使用脚本设置 [member cull_mask] 允许您切换"
+"供引擎内部使用,不会在编辑器中公开。使用脚本设置 [member cull_mask] 允许你切换"
"那些保留层,这对编辑器插件很有用。\n"
"要使用脚本更轻松地调整 [member cull_mask],请使用 [method "
"get_cull_mask_value] 和 [method set_cull_mask_value]。\n"
@@ -18816,7 +19376,7 @@ msgstr ""
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
"device."
-msgstr "通过相机源,您可以访问连接到设备的单个物理相机。"
+msgstr "通过相机源,你可以访问连接到设备的单个物理相机。"
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
@@ -20005,7 +20565,7 @@ msgid ""
msgstr ""
"[GPUParticles2D] 或 [CPUParticles2D] 指定给 [Texture2D] 的精灵表中拥有的列"
"数。\n"
-"[b]注意:[/b] 该属性只有在 [member particles_animation] 为 [code]true[/code] "
+"[b]注意:[/b]该属性只有在 [member particles_animation] 为 [code]true[/code] "
"时,才会在编辑器中被使用和可见。"
msgid ""
@@ -20014,7 +20574,7 @@ msgid ""
"particles_animation] is [code]true[/code]."
msgstr ""
"如果为 [code]true[/code],粒子动画将循环播放。\n"
-"[b]注意:[/b] 该属性只有在 [member particles_animation]为 [code]true[/code] "
+"[b]注意:[/b]该属性只有在 [member particles_animation]为 [code]true[/code] "
"时,才会在编辑器中被使用和可见。"
msgid ""
@@ -20025,7 +20585,7 @@ msgid ""
msgstr ""
"[GPUParticles2D] 或 [CPUParticles2D] 指定给 [Texture2D] 的精灵表中拥有的行"
"数。\n"
-"[b]注意:[/b] 该属性只有在 [member particles_animation] 为 [code]true[/code] "
+"[b]注意:[/b]该属性只有在 [member particles_animation] 为 [code]true[/code] "
"时,才会在编辑器中被使用和可见。"
msgid ""
@@ -20104,7 +20664,7 @@ msgstr ""
"z_index] 是多少,这一顺序都成立。\n"
"[CanvasLayer] 可以隐藏,也可以跟随视口。因此常用于血条等 HUD(位于 [code]1[/"
"code] 或更高的图层上)和背景(位于 [code]-1[/code] 或更低的图层上)。\n"
-"[b]注意:[/b]嵌入式 [Windows] 位于 [code]1024[/code] 图层。位于 [code]1025[/"
+"[b]注意:[/b]嵌入式 [Window] 位于 [code]1024[/code] 图层。位于 [code]1025[/"
"code] 或更高图层的 [CanvasItem] 会显示在嵌入式窗口之上。\n"
"[b]注意:[/b]每个 [CanvasLayer] 都是在一个特定的 [Viewport] 中绘制的,不能在多"
"个 [Viewport] 之间共享,见 [member custom_viewport]。使用多个 [Viewport] 时,"
@@ -21460,7 +22020,7 @@ msgid ""
"Override this method to define how the selected entry should be inserted. If "
"[param replace] is true, any existing text should be replaced."
msgstr ""
-"重写此方法以定义所选条目应如何插入。如果 [param replace] 为真,任何现有的文本"
+"覆盖此方法以定义所选条目应如何插入。如果 [param replace] 为真,任何现有的文本"
"都应该被替换。"
msgid ""
@@ -21489,6 +22049,20 @@ msgstr ""
"开始和结束键都必须是符号。只有开始键必须是唯一的。"
msgid ""
+"Submits an item to the queue of potential candidates for the autocomplete "
+"menu. Call [method update_code_completion_options] to update the list.\n"
+"[param location] indicates location of the option relative to the location of "
+"the code completion query. See [enum CodeEdit.CodeCompletionLocation] for how "
+"to set this value.\n"
+"[b]Note:[/b] This list will replace all current candidates."
+msgstr ""
+"向自动补全菜单的潜在候选队列提交条目。请调用 [method "
+"update_code_completion_options] 来更新列表。\n"
+"[param location] 指示的是该选项相对于代码补全请求位置的位置。这个值如何设置见 "
+"[enum CodeEdit.CodeCompletionLocation]。\n"
+"[b]注意:[/b]这个列表将替换所有当前候选。"
+
+msgid ""
"Adds a comment delimiter.\n"
"Both the start and end keys must be symbols. Only the start key has to be "
"unique.\n"
@@ -21745,7 +22319,7 @@ msgid ""
msgstr ""
"提交所有用 [method add_code_completion_option] 添加的补全选项。如果 [param "
"force] 是 [code]true[/code],将尝试强制弹出自动补全菜单 。\n"
-"[b]注意:[/b] 这将取代所有当前的候补选项。"
+"[b]注意:[/b]这将取代所有当前的候补选项。"
msgid "Sets whether brace pairs should be autocompleted."
msgstr "设置括号对是否应自动补全。"
@@ -22195,6 +22769,21 @@ msgid "Abstract base class for 2D physics objects."
msgstr "2D 物理对象的抽象基类。"
msgid ""
+"Abstract base class for 2D physics objects. [CollisionObject2D] can hold any "
+"number of [Shape2D]s for collision. Each shape must be assigned to a [i]shape "
+"owner[/i]. Shape owners are not nodes and do not appear in the editor, but "
+"are accessible through code using the [code]shape_owner_*[/code] methods.\n"
+"[b]Note:[/b] Only collisions between objects within the same canvas "
+"([Viewport] canvas or [CanvasLayer]) are supported. The behavior of "
+"collisions between objects in different canvases is undefined."
+msgstr ""
+"2D 物理对象的抽象基类。[CollisionObject2D] 能够容纳任意数量的 [Shape2D] 用作碰"
+"撞形状。每个形状必须分配给一个[i]形状所有者[/i]。形状所有者不是节点,也不会出"
+"现在编辑器中,但可以通过代码使用 [code]shape_owner_*[/code] 方法访问。\n"
+"[b]注意:[/b]仅支持相同画布中不同对象的碰撞([Viewport] 画布或 "
+"[CanvasLayer])。不同画布中的对象之间的碰撞行为是未定义的。"
+
+msgid ""
"Accepts unhandled [InputEvent]s. [param shape_idx] is the child index of the "
"clicked [Shape2D]. Connect to the [code]input_event[/code] signal to easily "
"pick up these events.\n"
@@ -22517,6 +23106,21 @@ msgid "Abstract base class for 3D physics objects."
msgstr "3D 物理对象的抽象基类。"
msgid ""
+"Abstract base class for 3D physics objects. [CollisionObject3D] can hold any "
+"number of [Shape3D]s for collision. Each shape must be assigned to a [i]shape "
+"owner[/i]. Shape owners are not nodes and do not appear in the editor, but "
+"are accessible through code using the [code]shape_owner_*[/code] methods.\n"
+"[b]Warning:[/b] With a non-uniform scale, this node will likely not behave as "
+"expected. It is advised to keep its scale the same on all axes and adjust its "
+"collision shape(s) instead."
+msgstr ""
+"3D 物理对象的抽象基类。[CollisionObject3D] 能够容纳任意数量的 [Shape3D] 用作碰"
+"撞形状。每个形状必须分配给一个[i]形状所有者[/i]。形状所有者不是节点,也不会出"
+"现在编辑器中,但可以通过代码使用 [code]shape_owner_*[/code] 方法访问。\n"
+"[b]警告:[/b]如果使用非均匀缩放,则该节点可能无法按预期工作。建议让所有轴上的"
+"缩放保持一致,可以用对碰撞形状的调整来代替非均匀缩放。"
+
+msgid ""
"Receives unhandled [InputEvent]s. [param position] is the location in world "
"space of the mouse pointer on the surface of the shape with index [param "
"shape_idx] and [param normal] is the normal vector of the surface at that "
@@ -22875,42 +23479,6 @@ msgstr "禁用的碰撞形状对世界没有任何影响。"
msgid "A color represented in RGBA format."
msgstr "以 RGBA 格式表示的颜色。"
-msgid ""
-"A color represented in RGBA format by a red ([member r]), green ([member g]), "
-"blue ([member b]), and alpha ([member a]) component. Each component is a 16-"
-"bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/"
-"code]. Some properties (such as [member CanvasItem.modulate]) may support "
-"values greater than [code]1.0[/code], for overbright or HDR (High Dynamic "
-"Range) colors.\n"
-"Colors can be created in various ways: By the various [Color] constructors, "
-"by static methods such as [method from_hsv], and by using a name from the set "
-"of standardized colors based on [url=https://en.wikipedia.org/wiki/"
-"X11_color_names]X11 color names[/url] with the addition of [constant "
-"TRANSPARENT]. GDScript also provides [method @GDScript.Color8], which uses "
-"integers from [code]0[/code] to [code]255[/code] and doesn't support "
-"overbright colors.\n"
-"[b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/"
-"code] if it is equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). "
-"Otherwise, a Color will always evaluate to [code]true[/code].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"color_constants.png]Color constants cheatsheet[/url]"
-msgstr ""
-"由红([member r])、绿([member g])、蓝([member b])和 alpha([member a])分"
-"量表示的 RGBA 格式的颜色。每个分量都是一个 16 位浮点值,通常介于 [code]0.0[/"
-"code] 到 [code]1.0[/code] 之间。某些属性(例如 [member CanvasItem.modulate])"
-"可能支持大于 [code]1.0[/code] 的值,用于表示过亮或 HDR(High Dynamic Range,高"
-"动态范围)颜色。\n"
-"创建颜色的方法有很多:可以使用 [Color] 的各种构造函数,[method from_hsv] 等静"
-"态方法,以及使用基于 [url=https://en.wikipedia.org/wiki/X11_color_names]X11 颜"
-"色名称[/url]的标准化颜色集外加 [constant TRANSPARENT]。GDScript 还提供了 "
-"[method @GDScript.Color8],使用的是 [code]0[/code] 到 [code]255[/code] 之间的"
-"整数,但不支持过亮的颜色。\n"
-"[b]注意:[/b]在布尔上下文中,等于 [code]Color(0, 0, 0, 1)[/code](不透明的黑"
-"色)的 Color 将被评估为 [code]false[/code]。否则,Color 将始终被评估为 "
-"[code]true[/code]。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"color_constants.png]Color 常量速查表[/url]"
-
msgid "2D GD Paint Demo"
msgstr "2D GD 画图演示"
@@ -23034,7 +23602,7 @@ msgid ""
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
-"返回将该颜色混合到给定颜色上所产生的新颜色。在绘画程序中,您可以将其想象为在该"
+"返回将该颜色混合到给定颜色上所产生的新颜色。在绘画程序中,你可以将其想象为在该"
"颜色(包括 alpha)上绘制的 [param over] 颜色。\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -24184,6 +24752,19 @@ msgid "A widget that provides an interface for selecting or modifying a color."
msgstr "提供用于选择或修改颜色的界面的小工具。"
msgid ""
+"A widget that provides an interface for selecting or modifying a color. It "
+"can optionally provide functionalities like a color sampler (eyedropper), "
+"color modes, and presets.\n"
+"[b]Note:[/b] This control is the color picker widget itself. You can use a "
+"[ColorPickerButton] instead if you need a button that brings up a "
+"[ColorPicker] in a popup."
+msgstr ""
+"提供用于选择或修改颜色的界面的小工具。还可以提供取色器(吸管)、颜色模式、预设"
+"等功能。\n"
+"[b]注意:[/b]这个控件就是取色器本身。如果你需要一个能够弹出 [ColorPicker] 窗口"
+"的按钮,可以改用 [ColorPickerButton]。"
+
+msgid ""
"Adds the given color to a list of color presets. The presets are displayed in "
"the color picker and the user will be able to select them.\n"
"[b]Note:[/b] The presets list is only for [i]this[/i] color picker."
@@ -24383,6 +24964,22 @@ msgid "A button that brings up a [ColorPicker] when pressed."
msgstr "点击后会显示 [ColorPicker] 的按钮。"
msgid ""
+"Encapsulates a [ColorPicker], making it accessible by pressing a button. "
+"Pressing the button will toggle the [ColorPicker]'s visibility.\n"
+"See also [BaseButton] which contains common properties and methods associated "
+"with this node.\n"
+"[b]Note:[/b] By default, the button may not be wide enough for the color "
+"preview swatch to be visible. Make sure to set [member Control."
+"custom_minimum_size] to a big enough value to give the button enough space."
+msgstr ""
+"封装一个 [ColorPicker],按下按钮即可访问该控件。按下按钮会切换 [ColorPicker] "
+"的可见性。\n"
+"另见 [BaseButton],其中包含与该节点关联的通用属性和方法。\n"
+"[b]注意:[/b]默认情况下,按钮的宽度可能不足以使颜色预览色板可见。确保将 "
+"[member Control.custom_minimum_size] 设置为足够大的值,以便为按钮提供足够的空"
+"间。"
+
+msgid ""
"Returns the [ColorPicker] that this node toggles.\n"
"[b]Warning:[/b] This is a required internal node, removing and freeing it may "
"cause a crash. If you wish to hide it or any of its children, use their "
@@ -24739,22 +25336,22 @@ msgid ""
"decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s "
"documentation for instructions."
msgstr ""
-"一个2D折线形状,用于物理运算。当处于 [code]BUILD_SEGMENTS[/code] 模式下时在"
+"一种 2D 折线形状,用于物理运算。当处于 [code]BUILD_SEGMENTS[/code] 模式下时在"
"[CollisionPolygon2D]内部使用。\n"
-"相互连接线段的集合,[ConcavePolygonShape2D]是最自由的可配置的单个2D形状。它能"
-"用于形成任何性质的多边形,甚至是不包围区域的形状。然而,[ConvexPolygonShape2D]"
-"是 [i]空心的(hollow)[/i]即使相互连接的线段确实形成了一个区域,这往往使得不适合"
-"物理运算或检测。\n"
-"[b]注意:[/b] 当用于碰撞时,[ConcavePolygonShape2D]预期是与静态(static)的 "
-"[CollisionShape2D]节点一起工作(例如 [StaticBody2D])。对于[CharacterBody2D]或"
-"[RigidBody2D],在静态模式以外的模式下可能表现不符预期。\n"
-"[b]警告:[/b] 物理物体快速移动时,体积小的物体将有机会穿过这个形状。发生的原因"
+"相互连接线段的集合,[ConcavePolygonShape2D] 是最自由的可配置的单个 2D 形状。它"
+"能用于形成任何性质的多边形,甚至是不包围区域的形状。然而,"
+"[ConvexPolygonShape2D]是 [i]空心的[/i],即使相互连接的线段确实形成了一个区域,"
+"这往往使得不适合物理运算或检测。\n"
+"[b]注意:[/b]当用于碰撞时,[ConcavePolygonShape2D] 预期是与静态的 "
+"[CollisionShape2D]节点一起工作(例如 [StaticBody2D])。对于 [CharacterBody2D] "
+"或 [RigidBody2D],在静态模式以外的模式下可能表现不符预期。\n"
+"[b]警告:[/b]物理物体快速移动时,体积小的物体将有机会穿过这个形状。发生的原因"
"为在某一帧物理物体可能在形状的“外部”,而下一帧它有可能直接在形状的“内部”。"
-"[ConcavePolygonShape2D]是空心的,因此它不会检测到碰撞。\n"
-"[b]性能:[/b]由于它的复杂性, [ConcavePolygonShape2D]是检测碰撞最慢的2D碰撞形"
-"状。它的使用一般仅限于关卡几何体(level geometry)。如果折线是闭合的,"
-"[CollisionPolygon2D]的 [code]BUILD_SOLIDS[/code]模式可以被使用,它会将多边形分"
-"解成凸多边形;相关说明请参阅 [ConvexPolygonShape2D] 文档。"
+"[ConcavePolygonShape2D] 是空心的,因此它不会检测到碰撞。\n"
+"[b]性能:[/b]由于它的复杂性, [ConcavePolygonShape2D] 是检测碰撞最慢的2D碰撞形"
+"状。它的使用一般仅限于关卡几何体。如果折线是闭合的,可以使用 "
+"[CollisionPolygon2D] 的 [code]BUILD_SOLIDS[/code] 模式,它会将多边形分解成凸多"
+"边形;相关说明请参阅 [ConvexPolygonShape2D] 文档。"
msgid ""
"The array of points that make up the [ConcavePolygonShape2D]'s line segments. "
@@ -24769,6 +25366,49 @@ msgid "A 3D trimesh shape used for physics collision."
msgstr "用于物理碰撞的 3D 三角网格形状。"
msgid ""
+"A 3D trimesh shape, intended for use in physics. Usually used to provide a "
+"shape for a [CollisionShape3D].\n"
+"Being just a collection of interconnected triangles, [ConcavePolygonShape3D] "
+"is the most freely configurable single 3D shape. It can be used to form "
+"polyhedra of any nature, or even shapes that don't enclose a volume. However, "
+"[ConvexPolygonShape3D] is [i]hollow[/i] even if the interconnected triangles "
+"do enclose a volume, which often makes it unsuitable for physics or "
+"detection.\n"
+"[b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to "
+"work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely "
+"not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than "
+"Static.\n"
+"[b]Warning:[/b] Physics bodies that are small have a chance to clip through "
+"this shape when moving fast. This happens because on one frame, the physics "
+"body may be on the \"outside\" of the shape, and on the next frame it may be "
+"\"inside\" it. [ConcavePolygonShape3D] is hollow, so it won't detect a "
+"collision.\n"
+"[b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the "
+"slowest 3D collision shape to check collisions against. Its use should "
+"generally be limited to level geometry. For convex geometry, "
+"[ConvexPolygonShape3D] should be used. For dynamic physics bodies that need "
+"concave collision, several [ConvexPolygonShape3D]s can be used to represent "
+"its collision by using convex decomposition; see [ConvexPolygonShape3D]'s "
+"documentation for instructions."
+msgstr ""
+"一种用于物理模拟的三维三角网格形状。通常用于为 [CollisionShape3D] 提供形状。\n"
+"作为一组相互连接的三角形, [ConcavePolygonShape3D] 是最自由配置的单一三维形状"
+"之一。它可以用于形成任何性质的多面体,甚至是不封闭体积的形状。然而,即使相互连"
+"接的三角形封闭了一个体积, [ConvexPolygonShape3D] 仍然是[i]中空[/i]的,这常常"
+"使其不适用于物理模拟或碰撞检测。\n"
+"[b]注意:[/b]当用于碰撞计算时, [ConcavePolygonShape3D] 旨在与静态的 "
+"[CollisionShape3D] 节点一起使用,如 [StaticBody3D] 。并且可能不适用于处于除静"
+"态外的其他模式下的 [CharacterBody3D] 或 [RigidBody3D] 。\n"
+"[b]警告:[/b]当移动速度较快时,较小的物体有可能穿过该形状。这是因为在一帧中,"
+"物理体可能在形状的“外部”,而在下一帧中可能在其“内部”。 "
+"[ConcavePolygonShape3D] 是中空的,因此不会检测到碰撞。\n"
+"[b]性能:[/b]由于其复杂性, [ConcavePolygonShape3D] 是用于检测三维碰撞的形状中"
+"最慢的。它的使用通常应限制在关卡几何体上。对于凸几何体,应使用 "
+"[ConvexPolygonShape3D] 。对于需要凹碰撞的动态物体,可以使用多个 "
+"[ConvexPolygonShape3D] 通过凸分解来表示其碰撞;请参阅 [ConvexPolygonShape3D] "
+"的文档以获取指示。"
+
+msgid ""
"Returns the faces of the trimesh shape as an array of vertices. The array (of "
"length divisible by three) is naturally divided into triples; each triple of "
"vertices defines a triangle."
@@ -24796,6 +25436,19 @@ msgid ""
"ball-and-socket joint."
msgstr "以模拟球窝关节的方式连接两个 3D 物理物体的物理关节。"
+msgid ""
+"A physics joint that connects two 3D physics bodies in a way that simulates a "
+"ball-and-socket joint. The twist axis is initiated as the X axis of the "
+"[ConeTwistJoint3D]. Once the physics bodies swing, the twist axis is "
+"calculated as the middle of the X axes of the joint in the local space of the "
+"two physics bodies. Useful for limbs like shoulders and hips, lamps hanging "
+"off a ceiling, etc."
+msgstr ""
+"以模拟球窝关节的方式连接两个 3D 物理物体的物理关节。扭转轴被初始化为 "
+"[ConeTwistJoint3D] 的 X 轴。一旦物理体摆动,扭转轴将被计算为两个物理体局部空间"
+"中关节的 X 轴的中间值。可用作肩膀、臀部等肢体,也可以用作从天花板荡下的灯之类"
+"的对象。"
+
msgid "Returns the value of the specified parameter."
msgstr "返回指定参数的值。"
@@ -25165,6 +25818,36 @@ msgstr ""
"递 [code]null[/code] 值就会移除指定的键,如果键被移除后,小节最终是空的,就会"
"移除小节。"
+msgid "A dialog used for confirmation of actions."
+msgstr "用于确认动作的对话框。"
+
+msgid ""
+"A dialog used for confirmation of actions. This window is similar to "
+"[AcceptDialog], but pressing its Cancel button can have a different outcome "
+"from pressing the OK button. The order of the two buttons varies depending on "
+"the host OS.\n"
+"To get cancel action, you can use:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"get_cancel_button().pressed.connect(self.canceled)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"GetCancelButton().Pressed += Canceled;\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"用于确认动作的对话框。这个窗口类似于 [AcceptDialog],但按下“取消”按钮和按下“确"
+"定”按钮的效果是不同的。这两个按钮的顺序取决于主机操作系统。\n"
+"要获得取消操作,你可以使用:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"get_cancel_button().pressed.connect(self.canceled)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"GetCancelButton().Pressed += Canceled;\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid ""
"Returns the cancel button.\n"
"[b]Warning:[/b] This is a required internal node, removing and freeing it may "
@@ -25465,7 +26148,7 @@ msgstr ""
"func _get_drag_data(position):\n"
" var mydata = make_data() # This is your custom method generating the drag "
"data.\n"
-" set_drag_preview(make_preview(mydata)) # 这是您生成拖动数据预览的自定义方"
+" set_drag_preview(make_preview(mydata)) # 这是你生成拖动数据预览的自定义方"
"法。\n"
" return mydata\n"
"[/gdscript]\n"
@@ -25474,7 +26157,7 @@ msgstr ""
"{\n"
" var myData = MakeData(); // This is your custom method generating the "
"drag data.\n"
-" SetDragPreview(MakePreview(myData)); // 这是您生成拖动数据预览的自定义方"
+" SetDragPreview(MakePreview(myData)); // 这是你生成拖动数据预览的自定义方"
"法。\n"
" return myData;\n"
"}\n"
@@ -25495,12 +26178,24 @@ msgstr ""
"由用户实现的虚方法。返回此控件的最小大小。替代 [member custom_minimum_size],"
"以用于通过代码控制最小尺寸。实际的最小尺寸将是这两者的最大值(分别在每个轴"
"上)。\n"
-"如果未重写,则默认为 [constant Vector2.ZERO]。\n"
+"如果未覆盖,则默认为 [constant Vector2.ZERO]。\n"
"[b]注意:[/b]当脚本被附加到已经覆盖其最小大小的 [Control] 节点(例如 [Label]、"
"[Button]、[PanelContainer] 等)时,该方法将不会被调用。它只能用于最基本的 GUI "
"节点,如 [Control]、[Container]、[Panel] 等。"
msgid ""
+"Virtual method to be implemented by the user. Returns the tooltip text for "
+"the position [param at_position] in control's local coordinates, which will "
+"typically appear when the cursor is resting over this control. See [method "
+"get_tooltip].\n"
+"[b]Note:[/b] If this method returns an empty [String], no tooltip is "
+"displayed."
+msgstr ""
+"用户实现的虚方法。返回位于控件局部坐标系中 [param at_position] 位置的工具提示"
+"文本,工具提示一般会在鼠标停留在该控件上时显示。见 [method get_tooltip]。\n"
+"[b]注意:[/b]如果返回的是空 [String],则不会显示工具提示。"
+
+msgid ""
"Virtual method to be implemented by the user. Use this method to process and "
"accept inputs on UI elements. See [method accept_event].\n"
"[b]Example usage for clicking a control:[/b]\n"
@@ -25640,13 +26335,13 @@ msgstr ""
"由用户实现的虚方法。返回一个 [Control] 节点,该节点取代默认节点以用作工具提"
"示。[param for_text] 包含 [member tooltip_text] 属性的内容。\n"
"返回的节点必须是 [Control] 类型或 Control 派生类型。它可以有任何类型的子节点。"
-"当工具提示消失时它会被释放,因此请确保您始终提供一个新实例(如果您想使用场景树"
-"中预先存在的节点,您可以复制它并传递复制的实例)。当返回 [code]null[/code] 或"
+"当工具提示消失时它会被释放,因此请确保你始终提供一个新实例(如果你想使用场景树"
+"中预先存在的节点,你可以复制它并传递复制的实例)。当返回 [code]null[/code] 或"
"非控制节点时,将使用默认的工具提示。\n"
-"返回的节点将作为子节点添加到 [PopupPanel],因此您应该只提供该面板的内容。该 "
+"返回的节点将作为子节点添加到 [PopupPanel],因此你应该只提供该面板的内容。该 "
"[PopupPanel] 可以使用 [method Theme.set_stylebox] 为类型 "
"[code]\"TooltipPanel\"[/code] 设置主题(参见 [member tooltip_text] 示例)。\n"
-"[b]注意:[/b]工具提示会被缩小到最小大小。如果您想确保它完全可见,您可能需要将"
+"[b]注意:[/b]工具提示会被缩小到最小大小。如果你想确保它完全可见,你可能需要将"
"其 [member custom_minimum_size] 设置为非零值。\n"
"[b]注意:[/b]返回时节点(和任何相关的子节点)应该是 [member CanvasItem."
"visible],否则,实例化它的视口将无法可靠地计算它的最小大小。\n"
@@ -26435,7 +27130,7 @@ msgid ""
"yourself (see [method set_offset])."
msgstr ""
"工作原理与 [method set_anchor] 相同,但取代 [code]keep_offset[/code] 参数和自"
-"动更新的偏移,它允许您自己设置偏移量(参见 [method set_offset])。"
+"动更新的偏移,它允许你自己设置偏移量(参见 [method set_offset])。"
msgid ""
"Sets both anchor preset and offset preset. See [method set_anchors_preset] "
@@ -26510,7 +27205,7 @@ msgid ""
"[/codeblocks]"
msgstr ""
"在鼠标指针处显示给定的控件。调用此方法的好时机是在 [method _get_drag_data] "
-"中。控件不得位于场景树中。您不应释放控件,也不应在拖动持续时间之外保留对控件的"
+"中。控件不得位于场景树中。你不应释放控件,也不应在拖动持续时间之外保留对控件的"
"引用。拖拽结束后它会自动删除。\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -26952,7 +27647,7 @@ msgstr ""
"的合适的视口拉伸模式,而不是单独缩放控件。\n"
"[b]注意:[/b][member FontFile.oversampling] [i]不[/i]考虑 [Control] [member "
"scale]。这意味着放大/缩小会导致位图字体和光栅化(非 MSDF)动态字体显得模糊或像"
-"素化。为确保无论缩放比例如何,文本都保持清晰,您可以通过启用 [member "
+"素化。为确保无论缩放比例如何,文本都保持清晰,你可以通过启用 [member "
"ProjectSettings.gui/theme/default_font_multichannel_signed_distance_field](仅"
"适用于默认项目字体);或在自定义字体的 DynamicFont 的导入选项中,启用[b]多通道"
"有符号距离场[/b]来启用 MSDF 字体渲染。对于系统字体,可以在检查器中启用 "
@@ -26979,6 +27674,14 @@ msgstr ""
"该节点的边界矩形的大小,使用该节点的坐标系。[Container] 节点会自动更新此属性。"
msgid ""
+"Tells the parent [Container] nodes how they should resize and place the node "
+"on the X axis. Use a combination of the [enum SizeFlags] constants to change "
+"the flags. See the constants to learn what each does."
+msgstr ""
+"告诉父 [Container] 节点应如何调整尺寸并将其放置在 X 轴上。请使用 [enum "
+"SizeFlags] 常量的组合来更改标志。查看常量以了解每个常量的作用。"
+
+msgid ""
"If the node and at least one of its neighbors uses the [constant SIZE_EXPAND] "
"size flag, the parent [Container] will let it take more or less space "
"depending on this property. If this node has a stretch ratio of 2 and its "
@@ -26989,6 +27692,14 @@ msgstr ""
"居节点的拉伸比为 1,则该节点将占用三分之二的可用空间。"
msgid ""
+"Tells the parent [Container] nodes how they should resize and place the node "
+"on the Y axis. Use a combination of the [enum SizeFlags] constants to change "
+"the flags. See the constants to learn what each does."
+msgstr ""
+"告诉父 [Container] 节点应如何调整尺寸并将其放置在 Y 轴上。请使用 [enum "
+"SizeFlags] 常量的组合来更改标志。查看常量以了解每个常量的作用。"
+
+msgid ""
"The [Theme] resource this node and all its [Control] and [Window] children "
"use. If a child node has its own [Theme] resource set, theme items are merged "
"with child's definitions having higher priority.\n"
@@ -27494,7 +28205,7 @@ msgid ""
"size_flags_stretch_ratio]. Use with [member size_flags_horizontal] and "
"[member size_flags_vertical]."
msgstr ""
-"告诉父级 [Container] 让该节点占用您标记的轴上的所有可用空间。如果将多个相邻节"
+"告诉父级 [Container] 让该节点占用你标记的轴上的所有可用空间。如果将多个相邻节"
"点设置为扩展,它们将根据其拉伸比共享空间。见 [member "
"size_flags_stretch_ratio]。用于 [member size_flags_horizontal] 和 [member "
"size_flags_vertical]。"
@@ -27638,6 +28349,38 @@ msgid "A 2D convex polygon shape used for physics collision."
msgstr "用于物理碰撞的 2D 凸多边形形状。"
msgid ""
+"A 2D convex polygon shape, intended for use in physics. Used internally in "
+"[CollisionPolygon2D] when it's in [code]BUILD_SOLIDS[/code] mode.\n"
+"[ConvexPolygonShape2D] is [i]solid[/i], which means it detects collisions "
+"from objects that are fully inside it, unlike [ConcavePolygonShape2D] which "
+"is hollow. This makes it more suitable for both detection and physics.\n"
+"[b]Convex decomposition:[/b] A concave polygon can be split up into several "
+"convex polygons. This allows dynamic physics bodies to have complex concave "
+"collisions (at a performance cost) and can be achieved by using several "
+"[ConvexPolygonShape3D] nodes or by using the [CollisionPolygon2D] node in "
+"[code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a "
+"sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that "
+"appears above the viewport, and choose [b]Create Polygon2D Sibling[/b].\n"
+"[b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions "
+"against compared to [ConcavePolygonShape2D], but it is slower than primitive "
+"collision shapes such as [CircleShape2D] and [RectangleShape2D]. Its use "
+"should generally be limited to medium-sized objects that cannot have their "
+"collision accurately represented by primitive shapes."
+msgstr ""
+"2D 凸多边形形状,旨在用于物理。[CollisionPolygon2D] 为 [code]BUILD_SOLIDS[/"
+"code] 模式时内部会使用这个类。\n"
+"[ConvexPolygonShape2D] 是[i]实心[/i]的,与空心的 [ConcavePolygonShape2D] 不"
+"同,如果对象完全位于其内部,也能够检测到碰撞。因此更适于检测和物理。\n"
+"[b]凸分解:[/b]凹多边形可以拆分为多个凸多边形。这样就能够让动态物理体拥有复杂"
+"的凹碰撞(以消耗性能为代价),做法是使用多个 [ConvexPolygonShape3D] 节点,或者"
+"使用 [code]BUILD_SOLIDS[/code] 模式的 [CollisionPolygon2D] 节点。要根据精灵生"
+"成碰撞多边形,请选中 [Sprite2D] 节点,前往出现在视口上方的 [b]Sprite2D[/b] 菜"
+"单,然后选择[b]创建 Polygon2D 同级[/b]。\n"
+"[b]性能:[/b][ConvexPolygonShape2D] 检查碰撞的速度比 [ConcavePolygonShape2D] "
+"要快,但比 [CircleShape2D]、[RectangleShape2D] 等基本碰撞形状要慢。通常应该仅"
+"限于中等大小的对象,在无法使用基本形状精确表示碰撞时使用。"
+
+msgid ""
"Based on the set of points provided, this assigns the [member points] "
"property using the convex hull algorithm, removing all unneeded points. See "
"[method Geometry2D.convex_hull] for details."
@@ -27659,6 +28402,39 @@ msgstr ""
msgid "A 3D convex polyhedron shape used for physics collision."
msgstr "用于物理碰撞的 3D 凸多面体形状。"
+msgid ""
+"A 3D convex polyhedron shape, intended for use in physics. Usually used to "
+"provide a shape for a [CollisionShape3D].\n"
+"[ConvexPolygonShape3D] is [i]solid[/i], which means it detects collisions "
+"from objects that are fully inside it, unlike [ConcavePolygonShape3D] which "
+"is hollow. This makes it more suitable for both detection and physics.\n"
+"[b]Convex decomposition:[/b] A concave polyhedron can be split up into "
+"several convex polyhedra. This allows dynamic physics bodies to have complex "
+"concave collisions (at a performance cost) and can be achieved by using "
+"several [ConvexPolygonShape3D] nodes. To generate a convex decomposition from "
+"a mesh, select the [MeshInstance3D] node, go to the [b]Mesh[/b] menu that "
+"appears above the viewport, and choose [b]Create Multiple Convex Collision "
+"Siblings[/b]. Alternatively, [method MeshInstance3D."
+"create_multiple_convex_collisions] can be called in a script to perform this "
+"decomposition at run-time.\n"
+"[b]Performance:[/b] [ConvexPolygonShape3D] is faster to check collisions "
+"against compared to [ConcavePolygonShape3D], but it is slower than primitive "
+"collision shapes such as [SphereShape3D] and [BoxShape3D]. Its use should "
+"generally be limited to medium-sized objects that cannot have their collision "
+"accurately represented by primitive shapes."
+msgstr ""
+"3D 凸多面体形状,旨在用于物理。常用来为 [CollisionShape3D] 提供形状。\n"
+"[ConvexPolygonShape3D] 是[i]实心[/i]的,与空心的 [ConcavePolygonShape3D] 不"
+"同,如果对象完全位于其内部,也能够检测到碰撞。因此更适于检测和物理。\n"
+"[b]凸分解:[/b]凹多面体可以拆分为多个凸多面体。这样就能够让动态物理体拥有复杂"
+"的凹碰撞(以消耗性能为代价),做法是使用多个 [ConvexPolygonShape3D] 节点。要根"
+"据网格生成凸分解,请选中 [MeshInstance3D] 节点,前往出现在视口上方的 [b]Mesh[/"
+"b] 菜单,然后选择[b]创建多个凸碰撞同级[/b]。或者也可以在脚本中调用 [method "
+"MeshInstance3D.create_multiple_convex_collisions],在运行时执行分解。\n"
+"[b]性能:[/b][ConvexPolygonShape3D] 检查碰撞的速度比 [ConcavePolygonShape3D] "
+"要快,但比 [SphereShape3D]、[BoxShape3D] 等基本碰撞形状要慢。通常应该仅限于中"
+"等大小的对象,在无法使用基本形状精确表示碰撞时使用。"
+
msgid "The list of 3D points forming the convex polygon shape."
msgstr "形成凸多边形的 3D 点列表。"
@@ -28461,6 +29237,159 @@ msgstr "粒子将在盒子的体积中发射。"
msgid "Particles will be emitted in a ring or cylinder."
msgstr "粒子将以环形或圆柱的形式发射出来。"
+msgid "Provides access to advanced cryptographic functionalities."
+msgstr "提供对高阶加密功能的访问。"
+
+msgid ""
+"The Crypto class provides access to advanced cryptographic functionalities.\n"
+"Currently, this includes asymmetric key encryption/decryption, signing/"
+"verification, and generating cryptographically secure random bytes, RSA keys, "
+"HMAC digests, and self-signed [X509Certificate]s.\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"extends Node\n"
+"\n"
+"var crypto = Crypto.new()\n"
+"var key = CryptoKey.new()\n"
+"var cert = X509Certificate.new()\n"
+"\n"
+"func _ready():\n"
+" # Generate new RSA key.\n"
+" key = crypto.generate_rsa(4096)\n"
+" # Generate new self-signed certificate with the given key.\n"
+" cert = crypto.generate_self_signed_certificate(key, \"CN=mydomain.com,"
+"O=My Game Company,C=IT\")\n"
+" # Save key and certificate in the user folder.\n"
+" key.save(\"user://generated.key\")\n"
+" cert.save(\"user://generated.crt\")\n"
+" # Encryption\n"
+" var data = \"Some data\"\n"
+" var encrypted = crypto.encrypt(key, data.to_utf8_buffer())\n"
+" # Decryption\n"
+" var decrypted = crypto.decrypt(key, encrypted)\n"
+" # Signing\n"
+" var signature = crypto.sign(HashingContext.HASH_SHA256, data."
+"sha256_buffer(), key)\n"
+" # Verifying\n"
+" var verified = crypto.verify(HashingContext.HASH_SHA256, data."
+"sha256_buffer(), signature, key)\n"
+" # Checks\n"
+" assert(verified)\n"
+" assert(data.to_utf8_buffer() == decrypted)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"using Godot;\n"
+"using System.Diagnostics;\n"
+"\n"
+"public partial class MyNode : Node\n"
+"{\n"
+" private Crypto _crypto = new Crypto();\n"
+" private CryptoKey _key = new CryptoKey();\n"
+" private X509Certificate _cert = new X509Certificate();\n"
+"\n"
+" public override void _Ready()\n"
+" {\n"
+" // Generate new RSA key.\n"
+" _key = _crypto.GenerateRsa(4096);\n"
+" // Generate new self-signed certificate with the given key.\n"
+" _cert = _crypto.GenerateSelfSignedCertificate(_key, \"CN=mydomain.com,"
+"O=My Game Company,C=IT\");\n"
+" // Save key and certificate in the user folder.\n"
+" _key.Save(\"user://generated.key\");\n"
+" _cert.Save(\"user://generated.crt\");\n"
+" // Encryption\n"
+" string data = \"Some data\";\n"
+" byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8Buffer());\n"
+" // Decryption\n"
+" byte[] decrypted = _crypto.Decrypt(_key, encrypted);\n"
+" // Signing\n"
+" byte[] signature = _crypto.Sign(HashingContext.HashType.Sha256, Data."
+"Sha256Buffer(), _key);\n"
+" // Verifying\n"
+" bool verified = _crypto.Verify(HashingContext.HashType.Sha256, Data."
+"Sha256Buffer(), signature, _key);\n"
+" // Checks\n"
+" Debug.Assert(verified);\n"
+" Debug.Assert(data.ToUtf8Buffer() == decrypted);\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"Crypto 类提供对高阶加密功能的访问。\n"
+"目前,包括非对称密钥的加密/解密和签名/验证、生成加密安全随机字节、RSA 密钥、"
+"HMAC 摘要以及自签名的 [X509Certificate]。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"extends Node\n"
+"\n"
+"var crypto = Crypto.new()\n"
+"var key = CryptoKey.new()\n"
+"var cert = X509Certificate.new()\n"
+"\n"
+"func _ready():\n"
+" # 生成新的 RSA 密钥。\n"
+" key = crypto.generate_rsa(4096)\n"
+" # 使用给定的密钥生成新的自签名证书。\n"
+" cert = crypto.generate_self_signed_certificate(key, \"CN=mydomain.com,"
+"O=My Game Company,C=IT\")\n"
+" # 将密钥和证书保存在用户文件夹中。\n"
+" key.save(\"user://generated.key\")\n"
+" cert.save(\"user://generated.crt\")\n"
+" # 加密\n"
+" var data = \"Some data\"\n"
+" var encrypted = crypto.encrypt(key, data.to_utf8_buffer())\n"
+" # 解密\n"
+" var decrypted = crypto.decrypt(key, encrypted)\n"
+" # 签名\n"
+" var signature = crypto.sign(HashingContext.HASH_SHA256, data."
+"sha256_buffer(), key)\n"
+" # 验证\n"
+" var verified = crypto.verify(HashingContext.HASH_SHA256, data."
+"sha256_buffer(), signature, key)\n"
+" # 校验\n"
+" assert(verified)\n"
+" assert(data.to_utf8_buffer() == decrypted)\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"using Godot;\n"
+"using System.Diagnostics;\n"
+"\n"
+"public partial class MyNode : Node\n"
+"{\n"
+" private Crypto _crypto = new Crypto();\n"
+" private CryptoKey _key = new CryptoKey();\n"
+" private X509Certificate _cert = new X509Certificate();\n"
+"\n"
+" public override void _Ready()\n"
+" {\n"
+" // 生成新的 RSA 密钥。\n"
+" _key = _crypto.GenerateRsa(4096);\n"
+" // 使用给定的密钥生成新的自签名证书。\n"
+" _cert = _crypto.GenerateSelfSignedCertificate(_key, \"CN=mydomain.com,"
+"O=My Game Company,C=IT\");\n"
+" // 将密钥和证书保存在用户文件夹中。\n"
+" _key.Save(\"user://generated.key\");\n"
+" _cert.Save(\"user://generated.crt\");\n"
+" // 加密\n"
+" string data = \"Some data\";\n"
+" byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8Buffer());\n"
+" // 解密\n"
+" byte[] decrypted = _crypto.Decrypt(_key, encrypted);\n"
+" // 签名\n"
+" byte[] signature = _crypto.Sign(HashingContext.HashType.Sha256, Data."
+"Sha256Buffer(), _key);\n"
+" // 验证\n"
+" bool verified = _crypto.Verify(HashingContext.HashType.Sha256, Data."
+"Sha256Buffer(), signature, _key);\n"
+" // 校验\n"
+" Debug.Assert(verified);\n"
+" Debug.Assert(data.ToUtf8Buffer() == decrypted);\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid ""
"Compares two [PackedByteArray]s for equality without leaking timing "
"information in order to prevent timing attacks.\n"
@@ -28530,7 +29459,7 @@ msgstr ""
"根据给定的 [CryptoKey] 和 [param issuer_name] 生成自签名的 [X509Certificate]。"
"证书有效性将由 [param not_before] 和 [param not_after](第一个有效日期和最后一"
"个有效日期)定义。[param issuer_name] 必须至少包含“CN=”(通用名称,即域"
-"名)、“O=”(组织,即您的公司名称)、“C=”(国家,即 2 个字母的该组织所在的国家/"
+"名)、“O=”(组织,即你的公司名称)、“C=”(国家,即 2 个字母的该组织所在的国家/"
"地区的 ISO-3166 代码)。\n"
"生成 RSA 密钥和 X509 自签名证书的小示例。\n"
"[codeblocks]\n"
@@ -28645,8 +29574,8 @@ msgid ""
"[MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG "
"node also has a significant CPU cost, so it should be avoided during gameplay."
msgstr ""
-"此节点允许您创建与 CSG 系统一起使用的盒子。\n"
-"[b]注意:[/b] CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
+"此节点允许你创建与 CSG 系统一起使用的盒子。\n"
+"[b]注意:[/b]CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
"[MeshInstance3D] 相比,创建 CSG 节点具有显着的 CPU 成本。在另一个 CSG 节点中,"
"移动一个 CSG 节点,也会大量消耗 CPU,因此在游戏过程中,应该避免这种情况。"
@@ -28657,7 +29586,7 @@ msgid "The material used to render the box."
msgstr "用于渲染盒子的材质。"
msgid "A CSG node that allows you to combine other CSG modifiers."
-msgstr "允许您组合其他 CSG 修改器的 CSG 节点。"
+msgstr "允许你组合其他 CSG 修改器的 CSG 节点。"
msgid ""
"For complex arrangements of shapes, it is sometimes needed to add structure "
@@ -28678,7 +29607,7 @@ msgstr ""
"CSGCombiner3D 节点的子节点的一组形状进行操作,并对作为第二个 CSGCombiner3D 节"
"点的子节点的第二组形状进行一组单独的操作,然后执行以下操作: 将两个最终结果作"
"为输入来创建最终形状。\n"
-"[b]注意:[/b] CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
+"[b]注意:[/b]CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
"[MeshInstance3D] 相比,创建 CSG 节点具有显著的 CPU 成本。在另一个 CSG 节点中,"
"移动一个 CSG 节点,也会大量消耗 CPU,因此在游戏过程中,应该避免这种情况。"
@@ -28693,8 +29622,8 @@ msgid ""
"[MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG "
"node also has a significant CPU cost, so it should be avoided during gameplay."
msgstr ""
-"此节点允许您创建与 CSG 系统一起使用的圆柱体(或圆锥体)。\n"
-"[b]注意:[/b] CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
+"此节点允许你创建与 CSG 系统一起使用的圆柱体(或圆锥体)。\n"
+"[b]注意:[/b]CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
"[MeshInstance3D] 相比,创建 CSG 节点具有显着的 CPU 成本。在另一个 CSG 节点中,"
"移动一个 CSG 节点,也会大量消耗 CPU,因此在游戏过程中,应该避免这种情况。"
@@ -28741,7 +29670,7 @@ msgstr ""
"此 CSG 节点允许你将任何网格资源用作 CSG 形状,前提是它是闭合的、不自相交、不包"
"含内部面并且没有连接到两个面以上的边。 另请参阅 [CSGPolygon3D],以绘制 2D 挤出"
"多边形以用作 CSG 节点。\n"
-"[b]注意:[/b] CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
+"[b]注意:[/b]CSG 节点旨在用于关卡原型设计。与使用 [PrimitiveMesh] 创建 "
"[MeshInstance3D] 相比,创建 CSG 节点具有显着的 CPU 成本。在另一个 CSG 节点中,"
"移动一个 CSG 节点,也会大量消耗 CPU,因此在游戏过程中,应该避免这种情况。"
@@ -29297,6 +30226,9 @@ msgid ""
"Returns the right tangent angle (in degrees) for the point at [param index]."
msgstr "返回索引为 [param index] 的点的右侧切线夹角(单位为度)。"
+msgid "Removes the point at [param index] from the curve."
+msgstr "移除曲线中索引为 [param index] 的点。"
+
msgid ""
"Returns the Y value for the point that would exist at the X position [param "
"offset] along the curve."
@@ -29912,6 +30844,20 @@ msgstr ""
msgid "A 3D cylinder shape used for physics collision."
msgstr "用于物理碰撞的 3D 圆柱体形状。"
+msgid ""
+"A 2D capsule shape, intended for use in physics. Usually used to provide a "
+"shape for a [CollisionShape3D].\n"
+"[b]Note:[/b] There are several known bugs with cylinder collision shapes. "
+"Using [CapsuleShape3D] or [BoxShape3D] instead is recommended.\n"
+"[b]Performance:[/b] [CylinderShape3D] is fast to check collisions against, "
+"but it is slower than [CapsuleShape3D], [BoxShape3D], and [CylinderShape3D]."
+msgstr ""
+"3D 胶囊形状,旨在用于物理学。通常用于为 [CollisionShape3D] 提供形状。\n"
+"[b]注意:[/b]圆柱体碰撞形状有若干已知的问题。建议改用 [CapsuleShape3D] 或 "
+"[BoxShape3D]。\n"
+"[b]性能:[/b][CylinderShape3D] 可以快速检查碰撞,但比 [CapsuleShape3D]、"
+"[BoxShape3D] 和 [CylinderShape3D] 慢。"
+
msgid "The cylinder's height."
msgstr "圆柱体的高度。"
@@ -30307,6 +31253,307 @@ msgstr "[enum DecalTexture] 枚举的最大大小。"
msgid "A built-in data structure that holds key-value pairs."
msgstr "包含键值对的内置数据结构。"
+msgid ""
+"Dictionaries are associative containers that contain values referenced by "
+"unique keys. Dictionaries will preserve the insertion order when adding new "
+"entries. In other programming languages, this data structure is often "
+"referred to as a hash map or an associative array.\n"
+"You can define a dictionary by placing a comma-separated list of [code]key: "
+"value[/code] pairs inside curly braces [code]{}[/code].\n"
+"Creating a dictionary:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {} # Creates an empty dictionary.\n"
+"\n"
+"var dict_variable_key = \"Another key name\"\n"
+"var dict_variable_value = \"value2\"\n"
+"var another_dict = {\n"
+" \"Some key name\": \"value1\",\n"
+" dict_variable_key: dict_variable_value,\n"
+"}\n"
+"\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"\n"
+"# Alternative Lua-style syntax.\n"
+"# Doesn't require quotes around keys, but only string constants can be used "
+"as key names.\n"
+"# Additionally, key names must start with a letter or an underscore.\n"
+"# Here, `some_key` is a string literal, not a variable!\n"
+"another_dict = {\n"
+" some_key = 42,\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary(); // Creates an empty "
+"dictionary.\n"
+"var pointsDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"You can access a dictionary's value by referencing its corresponding key. In "
+"the above example, [code]points_dict[\"White\"][/code] will return [code]50[/"
+"code]. You can also write [code]points_dict.White[/code], which is "
+"equivalent. However, you'll have to use the bracket syntax if the key you're "
+"accessing the dictionary with isn't a fixed string (such as a number or "
+"variable).\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"@export_enum(\"White\", \"Yellow\", \"Orange\") var my_color: String\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"func _ready():\n"
+" # We can't use dot syntax here as `my_color` is a variable.\n"
+" var points = points_dict[my_color]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"[Export(PropertyHint.Enum, \"White,Yellow,Orange\")]\n"
+"public string MyColor { get; set; }\n"
+"private Godot.Collections.Dictionary _pointsDict = new Godot.Collections."
+"Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"\n"
+"public override void _Ready()\n"
+"{\n"
+" int points = (int)_pointsDict[MyColor];\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"In the above code, [code]points[/code] will be assigned the value that is "
+"paired with the appropriate color selected in [code]my_color[/code].\n"
+"Dictionaries can contain more complex data:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {\n"
+" \"First Array\": [1, 2, 3, 4] # Assigns an Array to a String key.\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"First Array\", new Godot.Collections.Array{1, 2, 3, 4}}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"To add a key to an existing dictionary, access it like an existing key and "
+"assign to it:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"points_dict[\"Blue\"] = 150 # Add \"Blue\" as a key and assign 150 as its "
+"value.\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var pointsDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"pointsDict[\"Blue\"] = 150; // Add \"Blue\" as a key and assign 150 as its "
+"value.\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"Finally, dictionaries can contain different types of keys and values in the "
+"same dictionary:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# This is a valid dictionary.\n"
+"# To access the string \"Nested value\" below, use `my_dict.sub_dict.sub_key` "
+"or `my_dict[\"sub_dict\"][\"sub_key\"]`.\n"
+"# Indexing styles can be mixed and matched depending on your needs.\n"
+"var my_dict = {\n"
+" \"String Key\": 5,\n"
+" 4: [1, 2, 3],\n"
+" 7: \"Hello\",\n"
+" \"sub_dict\": {\"sub_key\": \"Nested value\"},\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// This is a valid dictionary.\n"
+"// To access the string \"Nested value\" below, use `((Godot.Collections."
+"Dictionary)myDict[\"sub_dict\"])[\"sub_key\"]`.\n"
+"var myDict = new Godot.Collections.Dictionary {\n"
+" {\"String Key\", 5},\n"
+" {4, new Godot.Collections.Array{1,2,3}},\n"
+" {7, \"Hello\"},\n"
+" {\"sub_dict\", new Godot.Collections.Dictionary{{\"sub_key\", \"Nested "
+"value\"}}}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"The keys of a dictionary can be iterated with the [code]for[/code] keyword:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var groceries = {\"Orange\": 20, \"Apple\": 2, \"Banana\": 4}\n"
+"for fruit in groceries:\n"
+" var amount = groceries[fruit]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var groceries = new Godot.Collections.Dictionary{{\"Orange\", 20}, "
+"{\"Apple\", 2}, {\"Banana\", 4}};\n"
+"foreach (var (fruit, amount) in groceries)\n"
+"{\n"
+" // `fruit` is the key, `amount` is the value.\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a "
+"dictionary which can be modified independently of the original dictionary, "
+"use [method duplicate].\n"
+"[b]Note:[/b] Erasing elements while iterating over dictionaries is [b]not[/b] "
+"supported and will result in unpredictable behavior."
+msgstr ""
+"字典是关系容器,包含的值(Value)由唯一的键(Key)引用。添加新条目时,字典会保"
+"持插入顺序。在其他编程语言中,这种数据结构有时也称为哈希表或关联数组。\n"
+"在大括号 [code]{}[/code] 中放置用逗号分隔的一对对 [code]键: 值[/code] 列表就可"
+"以定义字典。\n"
+"字典的创建:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {} # 创建空字典。\n"
+"\n"
+"var dict_variable_key = \"Another key name\"\n"
+"var dict_variable_value = \"value2\"\n"
+"var another_dict = {\n"
+" \"Some key name\": \"value1\",\n"
+" dict_variable_key: dict_variable_value,\n"
+"}\n"
+"\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"\n"
+"# 备选 Lua 分隔语法。\n"
+"# 不需要在键周围加引号,但键名只能为字符串常量。\n"
+"# 另外,键名必须以字母或下划线开头。\n"
+"# 此处的 `some_key` 是字符串字面量,不是变量!\n"
+"another_dict = {\n"
+" some_key = 42,\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary(); // 创建空字典。\n"
+"var pointsDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"你可以通过键来访问字典中对应的值。上面的例子中,[code]points_dict[\"White\"][/"
+"code] 会返回 [code]50[/code]。你也可以写 [code]points_dict.White[/code],和前"
+"面的写法是等价的。不过如果用来访问字典的键不是固定字符串的话(例如数字或者变"
+"量),那么就只能使用方括号语法。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"@export_enum(\"White\", \"Yellow\", \"Orange\") var my_color: String\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"func _ready():\n"
+" # 不能使用点语法,因为 `my_color` 是变量。\n"
+" var points = points_dict[my_color]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"[Export(PropertyHint.Enum, \"White,Yellow,Orange\")]\n"
+"public string MyColor { get; set; }\n"
+"private Godot.Collections.Dictionary _pointsDict = new Godot.Collections."
+"Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"\n"
+"public override void _Ready()\n"
+"{\n"
+" int points = (int)_pointsDict[MyColor];\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"在上面的代码中,[code]points[/code] 会被赋值为与 [code]my_color[/code] 中选中"
+"的颜色相对应的值。\n"
+"字典可以包含更复杂的数据:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {\n"
+" \"First Array\": [1, 2, 3, 4] # 将 Array 赋给 String 键。\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"First Array\", new Godot.Collections.Array{1, 2, 3, 4}}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"要往已有字典中添加键,请像已有键一样进行访问并赋值:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var points_dict = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
+"points_dict[\"Blue\"] = 150 # 将 \"Blue\" 添加为键,并将 150 赋为它的值。\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var pointsDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" {\"White\", 50},\n"
+" {\"Yellow\", 75},\n"
+" {\"Orange\", 100}\n"
+"};\n"
+"pointsDict[\"Blue\"] = 150; // 将 \"Blue\" 添加为键,并将 150 赋为它的值。\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"最后,同一个字典里可以包含不同类型的键和值:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"# 这是有效的字典。\n"
+"# 要访问下面的 \"Nested value\",请使用 `my_dict.sub_dict.sub_key` 或 "
+"`my_dict[\"sub_dict\"][\"sub_key\"]`。\n"
+"# 索引风格可以按需混合使用。\n"
+"var my_dict = {\n"
+" \"String Key\": 5,\n"
+" 4: [1, 2, 3],\n"
+" 7: \"Hello\",\n"
+" \"sub_dict\": {\"sub_key\": \"Nested value\"},\n"
+"}\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"// 这是有效的字典。\n"
+"// 要访问下面的 \"Nested value\",请使用 `((Godot.Collections."
+"Dictionary)myDict[\"sub_dict\"])[\"sub_key\"]`。\n"
+"var myDict = new Godot.Collections.Dictionary {\n"
+" {\"String Key\", 5},\n"
+" {4, new Godot.Collections.Array{1,2,3}},\n"
+" {7, \"Hello\"},\n"
+" {\"sub_dict\", new Godot.Collections.Dictionary{{\"sub_key\", \"Nested "
+"value\"}}}\n"
+"};\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"字典中的键可以用 [code]for[/code] 关键字进行遍历:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var groceries = {\"Orange\": 20, \"Apple\": 2, \"Banana\": 4}\n"
+"for fruit in groceries:\n"
+" var amount = groceries[fruit]\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var groceries = new Godot.Collections.Dictionary{{\"Orange\", 20}, "
+"{\"Apple\", 2}, {\"Banana\", 4}};\n"
+"foreach (var (fruit, amount) in groceries)\n"
+"{\n"
+" // `fruit` 为键,`amount` 为值。\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[b]注意:[/b]字典始终按引用传递。要获取字典的副本,能独立于原字典进行修改,请"
+"使用 [method duplicate]。\n"
+"[b]注意:[/b][b]不支持[/b]在遍历字典时清除元素,可能造成无法预知的行为。"
+
msgid "GDScript basics: Dictionary"
msgstr "GDScript 基础:字典"
@@ -30362,6 +31609,72 @@ msgstr ""
"[param default],如果省略了该参数则返回 [code]null[/code]。"
msgid ""
+"Returns [code]true[/code] if the dictionary contains an entry with the given "
+"[param key].\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {\n"
+" \"Godot\" : 4,\n"
+" 210 : null,\n"
+"}\n"
+"\n"
+"print(my_dict.has(\"Godot\")) # Prints true\n"
+"print(my_dict.has(210)) # Prints true\n"
+"print(my_dict.has(4)) # Prints false\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" { \"Godot\", 4 },\n"
+" { 210, default },\n"
+"};\n"
+"\n"
+"GD.Print(myDict.ContainsKey(\"Godot\")); // Prints true\n"
+"GD.Print(myDict.ContainsKey(210)); // Prints true\n"
+"GD.Print(myDict.ContainsKey(4)); // Prints false\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"In GDScript, this is equivalent to the [code]in[/code] operator:\n"
+"[codeblock]\n"
+"if \"Godot\" in {\"Godot\": 4}:\n"
+" print(\"The key is here!\") # Will be printed.\n"
+"[/codeblock]\n"
+"[b]Note:[/b] This method returns [code]true[/code] as long as the [param key] "
+"exists, even if its corresponding value is [code]null[/code]."
+msgstr ""
+"如果该字典包含给定的键 [param key],则返回 [code]true[/code]。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"var my_dict = {\n"
+" \"Godot\" : 4,\n"
+" 210 : null,\n"
+"}\n"
+"\n"
+"print(my_dict.has(\"Godot\")) # 输出 true\n"
+"print(my_dict.has(210)) # 输出 true\n"
+"print(my_dict.has(4)) # 输出 false\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var myDict = new Godot.Collections.Dictionary\n"
+"{\n"
+" { \"Godot\", 4 },\n"
+" { 210, default },\n"
+"};\n"
+"\n"
+"GD.Print(myDict.ContainsKey(\"Godot\")); // 输出 true\n"
+"GD.Print(myDict.ContainsKey(210)); // 输出 true\n"
+"GD.Print(myDict.ContainsKey(4)); // 输出 false\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"在 GDScript 中等价于 [code]in[/code] 运算符:\n"
+"[codeblock]\n"
+"if \"Godot\" in {\"Godot\": 4}:\n"
+" print(\"这个键存在!\") # 会进行输出。\n"
+"[/codeblock]\n"
+"[b]注意:[/b]只要键 [param key] 存在,该方法就会返回 [code]true[/code],即便这"
+"个键对应的值为 [code]null[/code]。"
+
+msgid ""
"Returns [code]true[/code] if the dictionary contains all keys in the given "
"[param keys] array.\n"
"[codeblock]\n"
@@ -30488,6 +31801,131 @@ msgstr ""
msgid "Provides methods for managing directories and their content."
msgstr "提供管理目录及其内容的方法。"
+msgid ""
+"This class is used to manage directories and their content, even outside of "
+"the project folder.\n"
+"[DirAccess] can't be instantiated directly. Instead it is created with a "
+"static method that takes a path for which it will be opened.\n"
+"Most of the methods have a static alternative that can be used without "
+"creating a [DirAccess]. Static methods only support absolute paths (including "
+"[code]res://[/code] and [code]user://[/code]).\n"
+"[codeblock]\n"
+"# Standard\n"
+"var dir = DirAccess.open(\"user://levels\")\n"
+"dir.make_dir(\"world1\")\n"
+"# Static\n"
+"DirAccess.make_dir_absolute(\"user://levels/world1\")\n"
+"[/codeblock]\n"
+"[b]Note:[/b] Many resources types are imported (e.g. textures or sound "
+"files), and their source asset will not be included in the exported game, as "
+"only the imported version is used. Use [ResourceLoader] to access imported "
+"resources.\n"
+"Here is an example on how to iterate through the files of a directory:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"func dir_contents(path):\n"
+" var dir = DirAccess.open(path)\n"
+" if dir:\n"
+" dir.list_dir_begin()\n"
+" var file_name = dir.get_next()\n"
+" while file_name != \"\":\n"
+" if dir.current_is_dir():\n"
+" print(\"Found directory: \" + file_name)\n"
+" else:\n"
+" print(\"Found file: \" + file_name)\n"
+" file_name = dir.get_next()\n"
+" else:\n"
+" print(\"An error occurred when trying to access the path.\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public void DirContents(string path)\n"
+"{\n"
+" using var dir = DirAccess.Open(path);\n"
+" if (dir != null)\n"
+" {\n"
+" dir.ListDirBegin();\n"
+" string fileName = dir.GetNext();\n"
+" while (fileName != \"\")\n"
+" {\n"
+" if (dir.CurrentIsDir())\n"
+" {\n"
+" GD.Print($\"Found directory: {fileName}\");\n"
+" }\n"
+" else\n"
+" {\n"
+" GD.Print($\"Found file: {fileName}\");\n"
+" }\n"
+" fileName = dir.GetNext();\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" GD.Print(\"An error occurred when trying to access the path.\");\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"这个类可以用来管理目录及其内容,不限于项目文件夹。\n"
+"[DirAccess] 无法直接实例化。请使用接受要打开的路径的静态方法创建。\n"
+"大多数方法都有静态备选项,无需创建 [DirAccess] 即可使用。静态方法仅支持绝对路"
+"径(包含 [code]res://[/code] 和 [code]user://[/code])。\n"
+"[codeblock]\n"
+"# 标准\n"
+"var dir = DirAccess.open(\"user://levels\")\n"
+"dir.make_dir(\"world1\")\n"
+"# 静态\n"
+"DirAccess.make_dir_absolute(\"user://levels/world1\")\n"
+"[/codeblock]\n"
+"[b]注意:[/b]很多资源类型是经过导入的(例如纹理和声音文件),因为在游戏中只会"
+"用到导入后的版本,所以导出后的游戏中不包含对应的源资产。请使用 "
+"[ResourceLoader] 访问导入的资源。\n"
+"以下是遍历目录中文件的示例:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"func dir_contents(path):\n"
+" var dir = DirAccess.open(path)\n"
+" if dir:\n"
+" dir.list_dir_begin()\n"
+" var file_name = dir.get_next()\n"
+" while file_name != \"\":\n"
+" if dir.current_is_dir():\n"
+" print(\"发现目录:\" + file_name)\n"
+" else:\n"
+" print(\"发现文件:\" + file_name)\n"
+" file_name = dir.get_next()\n"
+" else:\n"
+" print(\"尝试访问路径时出错。\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public void DirContents(string path)\n"
+"{\n"
+" using var dir = DirAccess.Open(path);\n"
+" if (dir != null)\n"
+" {\n"
+" dir.ListDirBegin();\n"
+" string fileName = dir.GetNext();\n"
+" while (fileName != \"\")\n"
+" {\n"
+" if (dir.CurrentIsDir())\n"
+" {\n"
+" GD.Print($\"发现目录:{fileName}\");\n"
+" }\n"
+" else\n"
+" {\n"
+" GD.Print($\"发现文件:{fileName}\");\n"
+" }\n"
+" fileName = dir.GetNext();\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" GD.Print(\"尝试访问路径时出错。\");\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid "File system"
msgstr "文件系统"
@@ -30967,9 +32405,27 @@ msgid ""
"illuminating the scene (during a night cycle, for example)."
msgstr ""
"使灯光仅对天空着色器可见。使用此模式时,灯光不会将灯光投射到场景中(通过直接照"
-"明或通过全局照明),但可以通过天空着色器访问。例如,当您想要控制天空效果而不照"
+"明或通过全局照明),但可以通过天空着色器访问。例如,当你想要控制天空效果而不照"
"亮场景时(例如,在夜间循环期间),这可能很有用。"
+msgid "A server interface for low-level window management."
+msgstr "用于低阶窗口管理的服务器接口。"
+
+msgid ""
+"[DisplayServer] handles everything related to window management. It is "
+"separated from [OS] as a single operating system may support multiple display "
+"servers.\n"
+"[b]Headless mode:[/b] Starting the engine with the [code]--headless[/code] "
+"[url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line "
+"argument[/url] disables all rendering and window management functions. Most "
+"functions from [DisplayServer] will return dummy values in this case."
+msgstr ""
+"所有与窗口管理相关的内容都由 [DisplayServer](显示服务器)处理。因为一个操作系"
+"统可能支持多个显示服务器,所以与 [OS] 是分开的。\n"
+"[b]无头模式:[/b]如果使用 [code]--headless[/code] [url=$DOCS_URL/tutorials/"
+"editor/command_line_tutorial.html]命令行参数[/url]启动引擎,就会禁用所有渲染和"
+"窗口管理功能。此时 [DisplayServer] 的大多数函数都会返回虚拟值。"
+
msgid "Returns the user's clipboard as a string if possible."
msgstr "如果可能,将用户的剪贴板作为字符串返回。"
@@ -30987,7 +32443,7 @@ msgstr ""
"贴板作为字符串返回。这是当用户在任何应用程序中选择文本时设置的剪贴板,而不是在"
"按下 [kbd]Ctrl + C[/kbd] 时设置的。然后可以通过在支持主剪贴板机制的任何应用程"
"序中,通过点击鼠标中键来粘贴该剪贴板数据。\n"
-"[b]注意:[/b] 这个方法只在 Linux(X11)上实现。"
+"[b]注意:[/b]这个方法只在 Linux(X11)上实现。"
msgid "Returns [code]true[/code] if there is content on the user's clipboard."
msgstr "如果用户的剪贴板中有内容,则返回 [code]true[/code]。"
@@ -31009,7 +32465,7 @@ msgstr ""
"置为给定的字符串。这是用户在应用程序中选中文本时设置的剪贴板,不是按 "
"[kbd]Ctrl + C[/kbd] 时设置的。设置后可以在任何支持主剪贴板机制的应用程序中通过"
"点击鼠标中键粘贴剪贴板数据。\n"
-"[b]注意:[/b] 这个方法只在 Linux(X11)上实现。"
+"[b]注意:[/b]这个方法只在 Linux(X11)上实现。"
msgid "Returns the default mouse cursor shape set by [method cursor_set_shape]."
msgstr "返回默认鼠标光标形状,由 [method cursor_set_shape] 设置。"
@@ -31038,6 +32494,36 @@ msgstr ""
"见 [method cursor_get_shape] 和 [method cursor_set_custom_image]。"
msgid ""
+"Shows a text input dialog which uses the operating system's native look-and-"
+"feel. [param callback] will be called with a [String] argument equal to the "
+"text field's contents when the dialog is closed for any reason.\n"
+"[b]Note:[/b] This method is implemented only on macOS."
+msgstr ""
+"显示文本输入对话框,这个对话框的外观和行为与操作系统原生对话框一致。无论该对话"
+"框因为什么原因而关闭,都会使用文本字段的内容作为 [String] 参数来调用 [param "
+"callback]。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。"
+
+msgid ""
+"Shows a text dialog which uses the operating system's native look-and-feel. "
+"[param callback] will be called when the dialog is closed for any reason.\n"
+"[b]Note:[/b] This method is implemented only on macOS."
+msgstr ""
+"显示文本对话框,这个对话框的外观和行为与操作系统原生对话框一致。无论该对话框因"
+"为什么原因而关闭,都会使用调用 [param callback]。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。"
+
+msgid ""
+"Allows the [param process_id] PID to steal focus from this window. In other "
+"words, this disables the operating system's focus stealing protection for the "
+"specified PID.\n"
+"[b]Note:[/b] This method is implemented only on Windows."
+msgstr ""
+"让进程 PID [param process_id] 窃取该窗口的焦点。换句话说,会禁用操作系统对指"
+"定 PID 的焦点窃取保护。\n"
+"[b]注意:[/b]该方法仅在 Windows 上实现。"
+
+msgid ""
"Forces window manager processing while ignoring all [InputEvent]s. See also "
"[method process_events].\n"
"[b]Note:[/b] This method is implemented on Windows and macOS."
@@ -31158,6 +32644,341 @@ msgstr ""
"[b]注意:[/b]这个列表中不含原生对话框。"
msgid ""
+"Adds a new checkable item with text [param label] to the global menu with ID "
+"[param menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的可勾选菜单项,显示的文本为 "
+"[param label]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new checkable item with text [param label] and icon [param icon] to "
+"the global menu with ID [param menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的可勾选菜单项,显示的文本为 "
+"[param label],图标为 [param icon]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new item with text [param label] and icon [param icon] to the global "
+"menu with ID [param menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的菜单项,显示的文本为 [param "
+"label],图标为 [param icon]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new radio-checkable item with text [param label] and icon [param icon] "
+"to the global menu with ID [param menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have "
+"any built-in checking behavior and must be checked/unchecked manually. See "
+"[method global_menu_set_item_checked] for more info on how to control it.\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的单选菜单项,显示的文本为 [param "
+"label],图标为 [param icon]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b]单选菜单项只负责显示选中标记,并没有任何内置检查行为,必须手动进"
+"行选中、取消选中的操作。关于如何进行控制的更多信息见 [method "
+"global_menu_set_item_checked]。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new item with text [param label] to the global menu with ID [param "
+"menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的菜单项,显示的文本为 [param "
+"label]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new item with text [param label] to the global menu with ID [param "
+"menu_root].\n"
+"Contrarily to normal binary items, multistate items can have more than two "
+"states, as defined by [param max_states]. Each press or activate of the item "
+"will increase the state by one. The default value is defined by [param "
+"default_state].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] By default, there's no indication of the current item state, it "
+"should be changed manually.\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的菜单项,显示的文本为 [param "
+"label]。\n"
+"与常规的二态菜单项不同,多状态菜单项的状态可以多于两个,由 [param max_states] "
+"定义。每点击或激活该菜单项一次,状态就会加一。默认值由 [param default_state] "
+"定义。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b]默认情况下不会展示当前菜单项的状态,应该手动更改。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a new radio-checkable item with text [param label] to the global menu "
+"with ID [param menu_root].\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"An [param accelerator] can optionally be defined, which is a keyboard "
+"shortcut that can be pressed to trigger the menu button even if it's not "
+"currently open. The [param accelerator] is generally a combination of [enum "
+"KeyModifierMask]s and [enum Key]s using bitwise OR such as "
+"[code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).\n"
+"[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have "
+"any built-in checking behavior and must be checked/unchecked manually. See "
+"[method global_menu_set_item_checked] for more info on how to control it.\n"
+"[b]Note:[/b] The [param callback] and [param key_callback] Callables need to "
+"accept exactly one Variant parameter, the parameter passed to the Callables "
+"will be the value passed to [param tag].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加新的单选菜单项,显示的文本为 [param "
+"label]。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"还可以定义键盘快捷键 [param accelerator],按下后即便该菜单按钮尚未打开,也会进"
+"行触发。[param accelerator] 通常是将 [enum KeyModifierMask] 和 [enum Key] 用按"
+"位或操作进行的组合,例如 [code]KEY_MASK_CTRL | KEY_A[/code]([kbd]Ctrl + A[/"
+"kbd])。\n"
+"[b]注意:[/b]单选菜单项只负责显示选中标记,并没有任何内置检查行为,必须手动进"
+"行选中、取消选中的操作。关于如何进行控制的更多信息见 [method "
+"global_menu_set_item_checked]。\n"
+"[b]注意:[/b][param callback] 和 [param key_callback] Callable 均只接受一个 "
+"Variant 参数,传入 Callable 的参数是传给 [param tag] 的参数。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds a separator between items to the global menu with ID [param menu_root]. "
+"Separators also occupy an index.\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加分隔符。分隔符也拥有索引。\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Adds an item that will act as a submenu of the global menu [param menu_root]. "
+"The [param submenu] argument is the ID of the global menu root that will be "
+"shown when the item is clicked.\n"
+"Returns index of the inserted item, it's not guaranteed to be the same as "
+"[param index] value.\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"向 ID 为 [param menu_root] 的全局菜单添加作为子菜单的菜单项。[param submenu] "
+"参数为全局菜单根菜单项的 ID,会在点击该菜单项时显示\n"
+"返回插入菜单项的索引,不保证与 [param index] 的值相同。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
+"Removes all items from the global menu with ID [param menu_root].\n"
+"[b]Note:[/b] This method is implemented only on macOS.\n"
+"[b]Supported system menu IDs:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - Main menu (macOS).\n"
+"\"_dock\" - Dock popup menu (macOS).\n"
+"[/codeblock]"
+msgstr ""
+"移除 ID 为 [param menu_root] 的全局菜单中的所有菜单项。\n"
+"[b]注意:[/b]该方法仅在 macOS 上实现。\n"
+"[b]支持的系统菜单 ID:[/b]\n"
+"[codeblock]\n"
+"\"_main\" - 主菜单(macOS)。\n"
+"\"_dock\" - 程序坞弹出菜单(macOS)。\n"
+"[/codeblock]"
+
+msgid ""
"Returns the accelerator of the item at index [param idx]. Accelerators are "
"special combinations of keys that activate the item, no matter which control "
"is focused.\n"
@@ -31503,15 +33324,6 @@ msgstr ""
"[b]注意:[/b]这个方法在 macOS、Windows 和 Linux(X11)上实现。"
msgid ""
-"Returns [code]true[/code] if touch events are available (Android or iOS), the "
-"capability is detected on the Webplatform or if [member ProjectSettings."
-"input_devices/pointing/emulate_touch_from_mouse] is [code]true[/code]."
-msgstr ""
-"如果触摸事件可用(Android 或 iOS)、在 Web 平台上检测到该功能或如果 [member "
-"ProjectSettings.input_devices/pointing/emulate_touch_from_mouse] 为 "
-"[code]true[/code] 时,则返回 [code]true[/code]。"
-
-msgid ""
"Returns active keyboard layout index.\n"
"[b]Note:[/b] This method is implemented on Linux (X11), macOS and Windows."
msgstr ""
@@ -32027,7 +33839,7 @@ msgid ""
"[b]Note:[/b] This method is implemented on Android, iOS and Web."
msgstr ""
"如果该平台有虚拟键盘,则显示虚拟键盘。\n"
-"[param existing_text] 参数对于实现您自己的 [LineEdit] 或 [TextEdit] 很有用,因"
+"[param existing_text] 参数对于实现你自己的 [LineEdit] 或 [TextEdit] 很有用,因"
"为它告诉虚拟键盘已经输入了哪些文本(虚拟键盘使用它进行自动更正和预测)。\n"
"[param position] 参数为编辑文本的屏幕空间 [Rect2]。\n"
"[param type] 参数允许配置要显示的虚拟键盘类型。\n"
@@ -32065,6 +33877,12 @@ msgid ""
msgstr "返回活动弹出窗口的 ID,如果没有则返回 [constant INVALID_WINDOW_ID]。"
msgid ""
+"Returns the [method Object.get_instance_id] of the [Window] the [param "
+"window_id] is attached to."
+msgstr ""
+"返回 [param window_id] 所附加的 [Window] 的 [method Object.get_instance_id]。"
+
+msgid ""
"Returns the screen the window specified by [param window_id] is currently "
"positioned on. If the screen overlaps multiple displays, the screen where the "
"window's center is located is returned. See also [method "
@@ -32095,7 +33913,7 @@ msgid ""
"Windows."
msgstr ""
"该函数返回用于插件的内部结构指针。\n"
-"[b]注意:[/b] 该方法在 Android、Linux(X11)、macOS 和 Windows 上实现。"
+"[b]注意:[/b]该方法在 Android、Linux(X11)、macOS 和 Windows 上实现。"
msgid ""
"Returns the bounding box of control, or menu item that was used to open the "
@@ -32148,12 +33966,33 @@ msgid "Returns the V-Sync mode of the given window."
msgstr "返回给定窗口的垂直同步模式。"
msgid ""
+"Returns [code]true[/code] if the window specified by [param window_id] is "
+"focused."
+msgstr "如果 [param window_id] 指定的窗口已获得焦点,则返回 [code]true[/code]。"
+
+msgid ""
"Returns [code]true[/code] if the given window can be maximized (the maximize "
"button is enabled)."
msgstr ""
"如果给定的窗口能够最大化(最大化按钮已启用),则返回 [code]true[/code]。"
msgid ""
+"Returns [code]true[/code], if double-click on a window title should maximize "
+"it.\n"
+"[b]Note:[/b] This method is implemented only on macOS."
+msgstr ""
+"如果双击窗口标题应将其最大化,则返回 [code]true[/code]。\n"
+"[b]注意:[/b]这个方法仅在 macOS 上实现。"
+
+msgid ""
+"Returns [code]true[/code], if double-click on a window title should minimize "
+"it.\n"
+"[b]Note:[/b] This method is implemented only on macOS."
+msgstr ""
+"如果双击窗口标题应将其最小化,则返回 [code]true[/code]。\n"
+"[b]注意:[/b]这个方法仅在 macOS 上实现。"
+
+msgid ""
"Moves the window specified by [param window_id] to the foreground, so that it "
"is visible over other windows."
msgstr "将由 [param window_id] 指定的窗口移动至前台,使其位于其他窗口之上。"
@@ -32879,8 +34718,8 @@ msgid ""
msgstr ""
"具有完整多窗口支持的全屏模式。\n"
"全屏窗口覆盖屏幕的整个显示区域,没有边框或装饰。显示视频模式没有更改。\n"
-"[b]注意:[/b] 无论平台如何,启用全屏都会更改窗口大小以匹配显示器的大小。因此,"
-"请确保您的项目在启用全屏模式时支持[url=$DOCS_URL/tutorials/rendering/"
+"[b]注意:[/b]无论平台如何,启用全屏都会更改窗口大小以匹配显示器的大小。因此,"
+"请确保你的项目在启用全屏模式时支持[url=$DOCS_URL/tutorials/rendering/"
"multiple_resolutions.html]多种分辨率[/url]。"
msgid ""
@@ -32907,7 +34746,7 @@ msgstr ""
"Menu 出现。\n"
"[b]在 Linux(X11)上:[/b]独占全屏模式会绕过合成器。\n"
"[b]注意:[/b]无论平台如何,启用全屏都会更改窗口大小以匹配显示器的大小。因此,"
-"确保您的项目在启用全屏模式时支持[url=$DOCS_URL/tutorials/rendering/"
+"确保你的项目在启用全屏模式时支持[url=$DOCS_URL/tutorials/rendering/"
"multiple_resolutions.html]多个分辨率[/url]。"
msgid ""
@@ -32961,6 +34800,24 @@ msgstr ""
"见 [method window_set_transient])。"
msgid ""
+"Window content is expanded to the full size of the window. Unlike borderless "
+"window, the frame is left intact and can be used to resize the window, title "
+"bar is transparent, but have minimize/maximize/close buttons.\n"
+"Use [method window_set_window_buttons_offset] to adjust minimize/maximize/"
+"close buttons offset.\n"
+"Use [method window_get_safe_title_margins] to determine area under the title "
+"bar that is not covered by decorations.\n"
+"[b]Note:[/b] This flag is implemented only on macOS."
+msgstr ""
+"窗口内容扩展到窗口的全部大小。与无边框窗口不同,框架仍保持不变,可以调整窗口大"
+"小,标题栏是透明的,但具有最小化/最大化/关闭按钮。\n"
+"使用 [method window_set_window_buttons_offset] 调整最小化/最大化/关闭按钮的偏"
+"移量。\n"
+"使用 [method window_get_safe_title_margins] 确定标题栏下方未被装饰覆盖的区"
+"域。\n"
+"[b]注意:[/b]该标志仅在 macOS 上实现。"
+
+msgid ""
"All mouse events are passed to the underlying window of the same application."
msgstr "所有鼠标事件都被传递到同一应用程序的底层窗口。"
@@ -32997,6 +34854,33 @@ msgstr ""
"window_set_window_event_callback]。"
msgid ""
+"Sent when the device \"Back\" button is pressed, see [method "
+"window_set_window_event_callback].\n"
+"[b]Note:[/b] This event is implemented only on Android."
+msgstr ""
+"当按下设备的“后退”按钮时发送,见 [method window_set_window_event_callback]。\n"
+"[b]注意:[/b]该事件仅在 Android 上实现。"
+
+msgid ""
+"Sent when the window is moved to the display with different DPI, or display "
+"DPI is changed, see [method window_set_window_event_callback].\n"
+"[b]Note:[/b] This flag is implemented only on macOS."
+msgstr ""
+"当窗口被移动到具有不同 DPI 的显示器上,或者显示器的 DPI 更改时发送,见 "
+"[method window_set_window_event_callback]。\n"
+"[b]注意:[/b]该标志仅在 macOS 上实现。"
+
+msgid ""
+"Sent when the window title bar decoration is changed (e.g. [constant "
+"WINDOW_FLAG_EXTEND_TO_TITLE] is set or window entered/exited full screen "
+"mode), see [method window_set_window_event_callback].\n"
+"[b]Note:[/b] This flag is implemented only on macOS."
+msgstr ""
+"当窗口标题栏的装饰改变时发送(例如 [constant WINDOW_FLAG_EXTEND_TO_TITLE] 被设"
+"置或窗口进入/退出全屏模式),见 [method window_set_window_event_callback]。\n"
+"[b]注意:[/b]该标志仅在 macOS 上实现。"
+
+msgid ""
"No vertical synchronization, which means the engine will display frames as "
"fast as possible (tearing may be visible). Framerate is unlimited "
"(nonwithstanding [member Engine.max_fps])."
@@ -33077,6 +34961,19 @@ msgstr ""
"- macOS:窗口主视图的 [code]NSView*[/code]。\n"
"- iOS:窗口主视图的 [code]UIView*[/code]。"
+msgid ""
+"OpenGL context (only with the GL Compatibility renderer):\n"
+"- Windows: [code]HGLRC[/code] for the window.\n"
+"- Linux: [code]GLXContext*[/code] for the window.\n"
+"- macOS: [code]NSOpenGLContext*[/code] for the window.\n"
+"- Android: [code]EGLContext[/code] for the window."
+msgstr ""
+"OpenGL 上下文(仅适用于 GL 兼容性渲染器):\n"
+"- Windows:窗口的 [code]HGLRC[/code]。\n"
+"- Linux:窗口的 [code]GLXContext*[/code]。\n"
+"- macOS:窗口的 [code]NSOpenGLContext*[/code]。\n"
+"- Android:窗口的 [code]EGLContext[/code]。"
+
msgid "Utterance has begun to be spoken."
msgstr "发言开始。"
@@ -33469,7 +35366,7 @@ msgstr ""
"commandPalette.AddCommand(\"command\", \"test/command\", commandCallable)\n"
"[/csharp]\n"
"[/codeblocks]\n"
-"[b]注意:[/b] 不应直接实例化此类。相反,使用 [method EditorInterface."
+"[b]注意:[/b]不应直接实例化此类。相反,使用 [method EditorInterface."
"get_command_palette] 访问单例。"
msgid ""
@@ -33597,7 +35494,7 @@ msgid ""
"the ID of the [EditorDebuggerSession] that received the message (which you "
"can retrieve via [method get_session])."
msgstr ""
-"重写此方法以处理传入的消息。[param session_id] 是接收到消息的 "
+"覆盖此方法以处理传入的消息。[param session_id] 是接收到消息的 "
"[EditorDebuggerSession] 的 ID(你可以通过 [method get_session] 检索到它)。"
msgid ""
@@ -33605,29 +35502,19 @@ msgid ""
"[param capture] is \"my_message\" then messages starting with \"my_message:\" "
"will be passes to the [method _capture] method."
msgstr ""
-"重写此方法以启用从调试器接收消息。如果[param capture]是\"my_message\",那么以"
+"覆盖此方法以启用从调试器接收消息。如果[param capture]是\"my_message\",那么以"
"\"my_message:\"开头的消息将会传递到[method _capture]方法。"
msgid ""
"Override this method to be notified whenever a new [EditorDebuggerSession] is "
"created (the session may be inactive during this stage)."
msgstr ""
-"重写此方法,以在创建新的[EditorDebuggerSession]时被通知(此阶段期间可能处于非"
+"覆盖此方法,以在创建新的[EditorDebuggerSession]时被通知(此阶段期间可能处于非"
"活动状态)。"
msgid "Returns the [EditorDebuggerSession] with the given [param id]."
msgstr "返回具有给定 [param id] 的 [EditorDebuggerSession]。"
-msgid ""
-"Returns an array of [EditorDebuggerSession] currently available to this "
-"debugger plugin.\n"
-"Note: Not sessions in the array may be inactive, check their state via "
-"[method EditorDebuggerSession.is_active]"
-msgstr ""
-"返回该调试器插件当前可用的 [EditorDebuggerSession] 数组。\n"
-"注意:不是数组中的会话可能处于非活动状态,通过 [method EditorDebuggerSession."
-"is_active] 检查它们的状态"
-
msgid "A class to interact with the editor debugger."
msgstr "与编辑器调试器交互的类。"
@@ -35668,6 +37555,20 @@ msgstr ""
"apple-events[/url]。"
msgid ""
+"Enable if you need to use the microphone or other audio input sources, if "
+"it's enabled you should also provide usage message in the [code]privacy/"
+"microphone_usage_description[/code] option. See [url=https://developer.apple."
+"com/documentation/bundleresources/entitlements/"
+"com_apple_security_device_audio-input]com.apple.security.device.audio-input[/"
+"url]."
+msgstr ""
+"请在需要使用麦克风或其他音频输入源时启用,启用时还应在 [code]privacy/"
+"microphone_usage_description[/code] 选项中提供用途信息。见 [url=https://"
+"developer.apple.com/documentation/bundleresources/entitlements/"
+"com_apple_security_device_audio-input]com.apple.security.device.audio-input[/"
+"url]。"
+
+msgid ""
"Enable to allow access to the user's calendar, if it's enabled you should "
"also provide usage message in the [code]privacy/calendar_usage_description[/"
"code] option. See [url=https://developer.apple.com/documentation/"
@@ -35699,6 +37600,18 @@ msgstr ""
"自定义权利 [code].plist[/code] 文件,如果指定,则会忽略导出配置中的其他权利。"
msgid ""
+"You can temporarily enable this entitlement to use native debugger (GDB, "
+"LLDB) with the exported app. This entitlement should be disabled for "
+"production export. See [url=https://developer.apple.com/documentation/xcode/"
+"embedding-a-helper-tool-in-a-sandboxed-app]Embedding a command-line tool in a "
+"sandboxed app[/url]."
+msgstr ""
+"临时启用这个权利就可以对导出的应用使用原生调试器(GDB、LLDB)。生产导出应该禁"
+"用这项权利。见 [url=https://developer.apple.com/documentation/xcode/embedding-"
+"a-helper-tool-in-a-sandboxed-app]Embedding a command-line tool in a sandboxed "
+"app[/url]。"
+
+msgid ""
"Allows app to load arbitrary libraries and frameworks (not signed with the "
"same Team ID as the main executable or by Apple). Enable it if you are using "
"GDExtension add-ons or ad-hoc signing, or want to support user-provided "
@@ -35713,6 +37626,33 @@ msgstr ""
"library-validation]com.apple.security.cs.disable-library-validation[/url]。"
msgid ""
+"Enable if you need to use location information from Location Services, if "
+"it's enabled you should also provide usage message in the [code]privacy/"
+"location_usage_description[/code] option. See [url=https://developer.apple."
+"com/documentation/bundleresources/entitlements/com_apple_security_personal-"
+"information_location]com.apple.security.personal-information.location[/url]."
+msgstr ""
+"如果你需要使用位置服务的位置信息,请启用此选项。如果已启用,则还应在"
+"[code]privacy/location_usage_description[/code]选项中提供使用说明。请参阅"
+"[url=https://developer.apple.com/documentation/bundleresources/entitlements/"
+"com_apple_security_personal-information_location]com.apple.security.personal-"
+"information.location[/url]。"
+
+msgid ""
+"Enable to allow access to the user's Photos library, if it's enabled you "
+"should also provide usage message in the [code]privacy/"
+"photos_library_usage_description[/code] option. See [url=https://developer."
+"apple.com/documentation/bundleresources/entitlements/"
+"com_apple_security_personal-information_photos-library]com.apple.security."
+"personal-information.photos-library[/url]."
+msgstr ""
+"启用后允许对用户的照片库进行访问,启用时还应在 [code]privacy/"
+"photos_library_usage_description[/code] 选项中提供用途信息。见 [url=https://"
+"developer.apple.com/documentation/bundleresources/entitlements/"
+"com_apple_security_personal-information_photos-library]com.apple.security."
+"personal-information.photos-library[/url]。"
+
+msgid ""
"The \"Full Name\", \"Common Name\" or SHA-1 hash of the signing identity used "
"to sign [code].app[/code] bundle."
msgstr ""
@@ -35742,6 +37682,13 @@ msgstr ""
"可以使用环境变量 [code]GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE[/code] 覆盖。"
msgid ""
+"If enabled, a wrapper that can be used to run the application with console "
+"output is created alongside the exported application."
+msgstr ""
+"启用后,会在导出后的应用程序旁创建一个封装程序,可以用来以带命令行输出的形式运"
+"行该应用程序。"
+
+msgid ""
"If [code]true[/code], the application is rendered at native display "
"resolution, otherwise it is always rendered at loHPI resolution and upscaled "
"by OS when required."
@@ -36243,6 +38190,19 @@ msgstr ""
"导出预设的选项需要更新,则返回 [code]true[/code]。"
msgid ""
+"Adds a custom file to be exported. [param path] is the virtual path that can "
+"be used to load the file, [param file] is the binary data of the file.\n"
+"When called inside [method _export_file] and [param remap] is [code]true[/"
+"code], the current file will not be exported, but instead remapped to this "
+"custom file. [param remap] is ignored when called in other places."
+msgstr ""
+"添加一个要导出的自定义文件。[param path] 是可以用来加载该文件的虚拟路径,"
+"[param file] 是该文件的二进制数据。\n"
+"在 [method _export_file] 中调用时,如果 [param remap] 为 [code]true[/code],则"
+"当前文件将不会被导出,而是被重新映射到这个自定义文件。在其他地方调用时会忽略 "
+"[param remap]。"
+
+msgid ""
"Adds an iOS bundle file from the given [param path] to the exported project."
msgstr "将给定的[param path]中的iOS bundle文件添加到导出的项目中。"
@@ -36263,7 +38223,7 @@ msgid ""
msgstr ""
"将动态库(*.dylib、*.framework)添加到iOS的Xcode项目的链接阶段,并将其嵌入到生"
"成的二进制文件中。\n"
-"[b]注意:[/b] 对于静态库(*.a),该方法的工作方式与[code]add_ios_framework[/"
+"[b]注意:[/b]对于静态库(*.a),该方法的工作方式与[code]add_ios_framework[/"
"code]相同。\n"
"此方法不该用于系统库,因为它们已经存在于设备上。"
@@ -36509,7 +38469,7 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"返回所选文件的 LineEdit。\n"
-"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果您希望隐"
+"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果你希望隐"
"藏它或其任何子项,请使用它们的 [member CanvasItem.visible] 属性。"
msgid ""
@@ -37220,9 +39180,9 @@ msgid ""
"This method must be overridden to do the actual importing work. See this "
"class' description for an example of overriding this method."
msgstr ""
-"使用指定的导入选项 [code]options[/code] 将 [code]source_file[/code] 导入到 "
-"[code]save_path[/code] 中。此函数将修改[code]platform_variants[/code] 和 "
-"[code]gen_files[/code] 数组。\n"
+"使用指定的导入选项 [param options] 将 [param source_file] 导入到 [param "
+"save_path] 中。此函数将修改 [param platform_variants] 和 [param gen_files] 数"
+"组。\n"
"必须重写这个方法才能完成实际的导入工作。参阅本类的描述以了解如何重写该方法。"
msgid ""
@@ -37744,7 +39704,7 @@ msgid ""
"The [param secondary] argument is [code]true[/code] when the committed handle "
"is secondary (see [method add_handles] for more information)."
msgstr ""
-"重写该方法,以提交一个正在编辑的控柄(控柄必须是之前通过 [method add_handles] "
+"覆盖该方法,以提交一个正在编辑的控柄(控柄必须是之前通过 [method add_handles] "
"添加的)。这通常意味着为该修改创建一个 [UndoRedo] 动作,将当前控柄值用作“做”,"
"并将 [param restore] 参数用作“撤销”。\n"
"如果 [param cancel] 参数为 [code]true[/code],则应直接设置 [param restore] "
@@ -37760,7 +39720,7 @@ msgid ""
"If the [param cancel] argument is [code]true[/code], the [param restores] "
"transforms should be directly set, without any [UndoRedo] action."
msgstr ""
-"重写该方法,以提交一组正在编辑的子小工具(参见 [method "
+"覆盖该方法,以提交一组正在编辑的子小工具(参见 [method "
"_subgizmos_intersect_ray] 和 [method _subgizmos_intersect_frustum])。这通常意"
"味着为该更改创建一个 [UndoRedo] 动作,将当前变换用作“做”,并将 [param "
"restores] 变换用作“撤消”。\n"
@@ -37774,7 +39734,7 @@ msgid ""
"The [param secondary] argument is [code]true[/code] when the requested handle "
"is secondary (see [method add_handles] for more information)."
msgstr ""
-"重写该方法,以返回编辑的控柄的名称(控柄必须先前通过 [method add_handles] 添加"
+"覆盖该方法,以返回编辑的控柄的名称(控柄必须先前通过 [method add_handles] 添加"
"的)。可以命名控柄以供用户在编辑时引用。\n"
"当请求的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
"信息,请参阅 [method add_handles])。"
@@ -37786,7 +39746,7 @@ msgid ""
"The [param secondary] argument is [code]true[/code] when the requested handle "
"is secondary (see [method add_handles] for more information)."
msgstr ""
-"重写该方法,以返回一个控柄的当前值。该值将在编辑开始时被请求,并用作 [method "
+"覆盖该方法,以返回一个控柄的当前值。该值将在编辑开始时被请求,并用作 [method "
"_commit_handle] 中的 [code]restore[/code] 参数。\n"
"当请求的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
"信息,请参阅 [method add_handles])。"
@@ -37796,7 +39756,7 @@ msgid ""
"transform will be requested at the start of an edit and used as the "
"[code]restore[/code] argument in [method _commit_subgizmos]."
msgstr ""
-"重写该方法,以返回子小工具的当前变换。该变换将在编辑开始时被请求,并用作 "
+"覆盖该方法,以返回子小工具的当前变换。该变换将在编辑开始时被请求,并用作 "
"[method _commit_subgizmos] 中的 [code]restore[/code] 参数。"
msgid ""
@@ -37805,7 +39765,7 @@ msgid ""
"The [param secondary] argument is [code]true[/code] when the requested handle "
"is secondary (see [method add_handles] for more information)."
msgstr ""
-"重写该方法,只要给定的控柄应该在编辑器中被高亮显示时就返回 [code]true[/"
+"覆盖该方法,只要给定的控柄应该在编辑器中被高亮显示时就返回 [code]true[/"
"code]。\n"
"当请求的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
"信息,请参阅 [method add_handles])。"
@@ -37815,7 +39775,7 @@ msgid ""
"requested. It's common to call [method clear] at the beginning of this method "
"and then add visual elements depending on the node's properties."
msgstr ""
-"重写该方法,每当请求小工具更新时将添加所有小工具元素。通常在该方法的开头调用 "
+"覆盖该方法,每当请求小工具更新时将添加所有小工具元素。通常在该方法的开头调用 "
"[method clear],然后根据节点的属性添加可视元素。"
msgid ""
@@ -37826,7 +39786,7 @@ msgid ""
"The [param secondary] argument is [code]true[/code] when the edited handle is "
"secondary (see [method add_handles] for more information)."
msgstr ""
-"重写该方法,当用户拖动小工具控柄(之前使用 [method add_handles] 添加的)时更新"
+"覆盖该方法,当用户拖动小工具控柄(之前使用 [method add_handles] 添加的)时更新"
"节点属性。提供的 [param point] 是屏幕坐标中的鼠标位置, [param camera] 可用于"
"将其转换为射线投射。\n"
"当编辑的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
@@ -37838,7 +39798,7 @@ msgid ""
"_subgizmos_intersect_frustum]). The [param transform] is given in the "
"Node3D's local coordinate system."
msgstr ""
-"重写该方法,以在子小工具编辑期间更新节点属性(参见 [method "
+"覆盖该方法,以在子小工具编辑期间更新节点属性(参见 [method "
"_subgizmos_intersect_ray] 和 [method _subgizmos_intersect_frustum])。[param "
"transform] 是在 Node3D 的局部坐标系中给出的。"
@@ -37852,7 +39812,7 @@ msgid ""
"will be used in other virtual methods like [method _get_subgizmo_transform] "
"or [method _commit_subgizmos]."
msgstr ""
-"重写该方法,以允许使用鼠标拖动框选来选择子小工具。给定一个 [param camera] 和一"
+"覆盖该方法,以允许使用鼠标拖动框选来选择子小工具。给定一个 [param camera] 和一"
"个 [param frustum],这个方法应该返回哪些子小工具包含在锥体中。[param frustum] "
"参数由一个构成选择锥体的所有 [code]Plane[/code] 的 [code]Array[/code] 组成。返"
"回的值应该包含一个唯一的子小工具标识符列表,它可以有任何非负值,并将用于其他虚"
@@ -37866,7 +39826,7 @@ msgid ""
"used in other virtual methods like [method _get_subgizmo_transform] or "
"[method _commit_subgizmos]."
msgstr ""
-"重写该方法,以允许使用鼠标点击选择子小工具。给定屏幕坐标中的 [param camera] "
+"覆盖该方法,以允许使用鼠标点击选择子小工具。给定屏幕坐标中的 [param camera] "
"和 [param point] 时,该方法应返回应选择哪个子小工具。返回值应该是一个唯一的子"
"小工具标识符,它可以有任何非负值,并将用于其他虚方法,如 [method "
"_get_subgizmo_transform] 或 [method _commit_subgizmos]。"
@@ -37992,7 +39952,7 @@ msgid ""
"Override this method to define whether the gizmos handled by this plugin can "
"be hidden or not. Returns [code]true[/code] if not overridden."
msgstr ""
-"重写该方法,以定义是否可以隐藏该插件处理的小工具。如果未被重写,则返回 "
+"覆盖该方法,以定义是否可以隐藏该插件处理的小工具。如果未被覆盖,则返回 "
"[code]true[/code]。"
msgid ""
@@ -38008,7 +39968,7 @@ msgid ""
"information).\n"
"Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以提交正在编辑的控柄(控柄必须是先前在 [method _redraw] 期间通过 "
+"覆盖该方法,以提交正在编辑的控柄(控柄必须是先前在 [method _redraw] 期间通过 "
"[method EditorNode3DGizmo.add_handles] 添加的)。这通常意味着为该更改创建一个 "
"[UndoRedo] 动作,将当前控柄值用作“做”,并将 [param restore] 参数用作“撤销”。\n"
"如果 [param cancel] 参数为 [code]true[/code],则 [param restore] 值应被直接设"
@@ -38027,7 +39987,7 @@ msgid ""
"subgizmo methods, transforms are given in local space respect to the gizmo's "
"Node3D. Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以提交一组正在编辑的子小工具(参见 [method "
+"覆盖该方法,以提交一组正在编辑的子小工具(参见 [method "
"_subgizmos_intersect_ray] 和 [method _subgizmos_intersect_frustum])。这通常意"
"味着为该更改创建一个 [UndoRedo] 动作,将当前变换用作“做”,并将 [param "
"restores] 变换用作“撤消”。\n"
@@ -38040,13 +40000,13 @@ msgid ""
"nodes of your choice, return [code]null[/code] for the rest of nodes. See "
"also [method _has_gizmo]."
msgstr ""
-"重写此方法,为选择的空间节点返回一个自定义的 [EditorNode3DGizmo],为其余节点返"
+"覆盖此方法,为选择的空间节点返回一个自定义的 [EditorNode3DGizmo],为其余节点返"
"回 [code]null[/code]。另见 [method _has_gizmo]。"
msgid ""
"Override this method to provide the name that will appear in the gizmo "
"visibility menu."
-msgstr "重写该方法,以提供将出现在小工具可见性菜单中的名称。"
+msgstr "覆盖该方法,以提供将出现在小工具可见性菜单中的名称。"
msgid ""
"Override this method to provide gizmo's handle names. The [param secondary] "
@@ -38054,7 +40014,7 @@ msgid ""
"[method EditorNode3DGizmo.add_handles] for more information). Called for this "
"plugin's active gizmos."
msgstr ""
-"重写该方法,以提供小工具的控柄名称。当请求的控柄是次要控柄时,[param "
+"覆盖该方法,以提供小工具的控柄名称。当请求的控柄是次要控柄时,[param "
"secondary] 参数为 [code]true[/code](有关更多信息,请参阅 [method "
"EditorNode3DGizmo.add_handles])。为该插件的活动小工具而调用。"
@@ -38067,7 +40027,7 @@ msgid ""
"information).\n"
"Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以返回一个控柄的当前值。该值将在编辑开始时被请求,并用作 [method "
+"覆盖该方法,以返回一个控柄的当前值。该值将在编辑开始时被请求,并用作 [method "
"_commit_handle] 中的 [code]restore[/code] 参数。\n"
"当请求的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
"信息,请参阅 [method EditorNode3DGizmo.add_handles])。\n"
@@ -38081,9 +40041,9 @@ msgid ""
"overridden, this method will return [code]0[/code], which means custom gizmos "
"will automatically get higher priority than built-in gizmos."
msgstr ""
-"重写该方法,以设置该小工具的优先级。具有更高优先级的小工具,将在处理控柄或子小"
+"覆盖该方法,以设置该小工具的优先级。具有更高优先级的小工具,将在处理控柄或子小"
"工具选择等输入时具有优先权。\n"
-"所有内置编辑器小工具都会返回 [code]-1[/code] 的优先级。如果未被重写,该方法将"
+"所有内置编辑器小工具都会返回 [code]-1[/code] 的优先级。如果未被覆盖,该方法将"
"返回 [code]0[/code],这意味着自定义小工具将自动获得比内置小工具更高的优先级。"
msgid ""
@@ -38093,7 +40053,7 @@ msgid ""
"used in the [code]restore[/code] argument in [method _commit_subgizmos]. "
"Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以返回子小工具的当前变换。对于所有子小工具方法,变换应该在相对于小"
+"覆盖该方法,以返回子小工具的当前变换。对于所有子小工具方法,变换应该在相对于小"
"工具的 Node3D 的局部空间中。此变换将在编辑开始时被请求,并在 [method "
"_commit_subgizmos] 中的 [code]restore[/code] 参数中使用。为该插件的活动小工具"
"而调用。"
@@ -38104,7 +40064,7 @@ msgid ""
"if it returns [code]true[/code] the node gets a generic [EditorNode3DGizmo] "
"assigned and is added to this plugin's list of active gizmos."
msgstr ""
-"重写该方法,以定义哪些 Node3D 节点具有来自该插件的小工具。每当将 [Node3D] 节点"
+"覆盖该方法,以定义哪些 Node3D 节点具有来自该插件的小工具。每当将 [Node3D] 节点"
"添加到场景时,该方法都会被调用,如果它返回 [code]true[/code],则该节点将被分配"
"一个通用的 [EditorNode3DGizmo],并被添加到该插件的活动小工具列表中。"
@@ -38115,7 +40075,7 @@ msgid ""
"EditorNode3DGizmo.add_handles] for more information). Called for this "
"plugin's active gizmos."
msgstr ""
-"重写该方法,以在编辑器中高亮显示给定控柄时返回 [code]true[/code]。当请求的控柄"
+"覆盖该方法,以在编辑器中高亮显示给定控柄时返回 [code]true[/code]。当请求的控柄"
"是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多信息,请参"
"阅 [method EditorNode3DGizmo.add_handles])。为该插件的活动小工具而调用。"
@@ -38123,7 +40083,7 @@ msgid ""
"Override this method to define whether Node3D with this gizmo should be "
"selectable even when the gizmo is hidden."
msgstr ""
-"重写该方法,以定义具有该小工具的 Node3D 是否应该是可选的,即使该小工具被隐藏。"
+"覆盖该方法,以定义具有该小工具的 Node3D 是否应该是可选的,即使该小工具被隐藏。"
msgid ""
"Override this method to add all the gizmo elements whenever a gizmo update is "
@@ -38131,7 +40091,7 @@ msgid ""
"beginning of this method and then add visual elements depending on the node's "
"properties."
msgstr ""
-"重写该方法,以在每当请求小工具更新时添加所有小工具元素。通常在该方法的开头调"
+"覆盖该方法,以在每当请求小工具更新时添加所有小工具元素。通常在该方法的开头调"
"用 [method EditorNode3DGizmo.clear],然后根据节点的属性添加可视元素。"
msgid ""
@@ -38143,7 +40103,7 @@ msgid ""
"secondary (see [method EditorNode3DGizmo.add_handles] for more information).\n"
"Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以在用户拖动小工具控柄(控柄是之前使用 [method EditorNode3DGizmo."
+"覆盖该方法,以在用户拖动小工具控柄(控柄是之前使用 [method EditorNode3DGizmo."
"add_handles] 添加的)时更新节点的属性。提供的 [param screen_pos] 是屏幕坐标中"
"的鼠标位置, [param camera] 可用于将其转换为射线投射。\n"
"当编辑的控柄是次要控柄时,[param secondary] 参数为 [code]true[/code](有关更多"
@@ -38156,7 +40116,7 @@ msgid ""
"_subgizmos_intersect_frustum]). The [param transform] is given in the "
"Node3D's local coordinate system. Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以在子小工具编辑期间更新节点属性(参见 [method "
+"覆盖该方法,以在子小工具编辑期间更新节点属性(参见 [method "
"_subgizmos_intersect_ray] 和 [method _subgizmos_intersect_frustum])。[param "
"transform] 在 Node3D 的局部坐标系中给出。为该插件的活动小工具而调用。"
@@ -38171,7 +40131,7 @@ msgid ""
"[method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for "
"this plugin's active gizmos."
msgstr ""
-"重写该方法,以允许使用鼠标拖动框选来选择子小工具。给定一个 [param camera] 和 "
+"覆盖该方法,以允许使用鼠标拖动框选来选择子小工具。给定一个 [param camera] 和 "
"[param frustum_planes],该方法应返回哪些子小工具包含在视锥体中。[param "
"frustum_planes] 参数由一个构成选择视锥体的所有 [code]Plane[/code] 的"
"[code]Array[/code] 组成。返回的值应该包含一个唯一的子小工具标识符列表,这些标"
@@ -38186,7 +40146,7 @@ msgid ""
"be used in other virtual methods like [method _get_subgizmo_transform] or "
"[method _commit_subgizmos]. Called for this plugin's active gizmos."
msgstr ""
-"重写该方法,以允许使用鼠标点击选择子小工具。给定屏幕坐标中的 [param camera] "
+"覆盖该方法,以允许使用鼠标点击选择子小工具。给定屏幕坐标中的 [param camera] "
"和 [param screen_pos] 时,该方法应返回应选择哪个子小工具。返回值应该是一个唯一"
"的子小工具标识符,它可以有任何非负值,并将用于其他虚方法,如 [method "
"_get_subgizmo_transform] 或 [method _commit_subgizmos]。为该插件的活动小工具而"
@@ -38827,7 +40787,7 @@ msgid ""
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
-"在插件中重写该方法,以返回一个 [Texture2D] 以便为插件提供一个图标。\n"
+"在插件中覆盖该方法,以返回一个 [Texture2D] 以便为插件提供一个图标。\n"
"对于主界面插件,它出现在屏幕顶部,“2D”、“3D”、“脚本”和 “AssetLib” 按钮的右"
"侧。\n"
"理想情况下,插件图标应为透明背景的白色,大小为 16x16 像素。\n"
@@ -38859,7 +40819,7 @@ msgid ""
"For main screen plugins, this appears at the top of the screen, to the right "
"of the \"2D\", \"3D\", \"Script\", and \"AssetLib\" buttons."
msgstr ""
-"在插件中重写该方法,以在 Godot 编辑器中显示时提供该插件的名称。\n"
+"在插件中覆盖该方法,以在 Godot 编辑器中显示时提供该插件的名称。\n"
"对于主屏幕插件,它显示在屏幕顶部,在“2D”“3D”“脚本”“AssetLib”按钮的右侧。"
msgid ""
@@ -38881,7 +40841,7 @@ msgid ""
" return state\n"
"[/codeblock]"
msgstr ""
-"重写该方法,以提供要保存的状态数据,如视图位置、网格设置、折叠等。这可用于保存"
+"覆盖该方法,以提供要保存的状态数据,如视图位置、网格设置、折叠等。这可用于保存"
"场景(再次打开时,保持状态)和切换选项卡( 选项卡返回时,可以恢复状态)。每个"
"场景的数据会自动被保存在编辑器元数据文件夹中的 [code]editstate[/code] 文件中。"
"如果想为插件存储全局的(独立于场景的)编辑器数据,可以改用 [method "
@@ -38909,7 +40869,7 @@ msgid ""
" configuration.set_value(\"MyPlugin\", \"icon_color\", $Icon.modulate)\n"
"[/codeblock]"
msgstr ""
-"重写该方法,以提供该插件的 GUI 布局、或想要存储的任何其他数据。这用于在调用 "
+"覆盖该方法,以提供该插件的 GUI 布局、或想要存储的任何其他数据。这用于在调用 "
"[method queue_save_layout]、或更改编辑器布局(例如更改停靠面板的位置)时,保存"
"项目的编辑器布局。数据被存储在编辑器元数据目录中的 [code]editor_layout.cfg[/"
"code] 文件中。\n"
@@ -39084,7 +41044,7 @@ msgid ""
msgstr ""
"将自定义控件添加到容器中(见 [enum CustomControlContainer])。在编辑器用户界面"
"中,有许多位置可以添加自定义控件。\n"
-"请记住,必须自己管理您的自定义控件的可见性(并且很可能在添加后隐藏它)。\n"
+"请记住,必须自己管理你的自定义控件的可见性(并且很可能在添加后隐藏它)。\n"
"当插件被停用时,请确保使用 [method remove_control_from_container] 移除自定义控"
"件,并使用 [method Node.queue_free] 将其释放。"
@@ -39123,7 +41083,7 @@ msgstr ""
"[b]注意:[/b]基本类型是该类型的类层次继承的基本引擎类,而不是任何自定义类型的"
"父类。\n"
"可以使用虚方法 [method _handles] 通过检查脚本或使用 [code]is[/code] 关键字来检"
-"查您的自定义对象是否正在被编辑。\n"
+"查你的自定义对象是否正在被编辑。\n"
"在运行时,这将是一个带有脚本的简单对象,因此不需要调用该函数。\n"
"[b]注意:[/b]以这种方式添加的自定义类型不是真正的类。它们只是使用特定脚本创建"
"节点的助手。"
@@ -39559,7 +41519,7 @@ msgid ""
"Vector3.x). The [param changing] argument avoids the editor requesting this "
"property to be refreshed (leave as [code]false[/code] if unsure)."
msgstr ""
-"如果一个或几个属性发生了变化,必然会调用这个函数。[param field] 用于您的编辑器"
+"如果一个或几个属性发生了变化,必然会调用这个函数。[param field] 用于你的编辑器"
"可以单独修改字段的情况(例如,Vector3.x)。[param changing] 参数可以避免编辑器"
"请求刷新该属性(如果不确定,请保留为 [code]false[/code])。"
@@ -39648,7 +41608,7 @@ msgstr "删除某个属性时发出。内部使用。"
msgid ""
"Emit it if you want to add this value as an animation key (check for keying "
"being enabled first)."
-msgstr "如果您想将此值添加这个值为动画键,请触发它(首先检查是否启用了键控)。"
+msgstr "如果你想将此值添加这个值为动画键,请触发它(首先检查是否启用了键控)。"
msgid "Emit it if you want to key a property with a single value."
msgstr "如果你想用一个单一的值来键入一个属性,请触发它。"
@@ -39780,7 +41740,7 @@ msgid ""
"[b]Note:[/b] Implement [method _handle_menu_selected] to handle these custom "
"items."
msgstr ""
-"在更新 [EditorResourcePicker] 的上下文菜单时调用该虚方法。实现该方法以使用您自"
+"在更新 [EditorResourcePicker] 的上下文菜单时调用该虚方法。实现该方法以使用你自"
"己的选项覆盖“新建 ...”项目。[param menu_node] 是对 [PopupMenu] 节点的引用。\n"
"[b]注意:[/b]实现 [method _handle_menu_selected] 来处理这些自定义项。"
@@ -39962,7 +41922,27 @@ msgid ""
"Returns [code]true[/code] if your generator supports the resource of type "
"[param type]."
msgstr ""
-"如果您的生成器支持类型为 [param type] 的资源,则返回 [code]true[/code]。"
+"如果你的生成器支持类型为 [param type] 的资源,则返回 [code]true[/code]。"
+
+msgid "A plugin that advanced tooltip for its handled resource type."
+msgstr "为处理的资源类型制作高阶工具提示的插件。"
+
+msgid ""
+"Resource tooltip plugins are used by [FileSystemDock] to generate customized "
+"tooltips for specific resources. E.g. tooltip for a [Texture2D] displays a "
+"bigger preview and the texture's dimensions.\n"
+"A plugin must be first registered with [method FileSystemDock."
+"add_resource_tooltip_plugin]. When the user hovers a resource in filesystem "
+"dock which is handled by the plugin, [method _make_tooltip_for_path] is "
+"called to create the tooltip. It works similarly to [method Control."
+"_make_custom_tooltip]."
+msgstr ""
+"[FileSystemDock] 使用的资源工具提示插件,能够为指定资源生成自定义工具提示。例"
+"如,[Texture2D] 的工具提示会显示较大的预览和该纹理的尺寸。\n"
+"插件必须先使用 [method FileSystemDock.add_resource_tooltip_plugin] 注册。用户"
+"悬停在文件系统面板中该插件能够处理的资源上时,就会调用 [method "
+"_make_tooltip_for_path] 来创建工具提示。工作原理类似于 [method Control."
+"_make_custom_tooltip]。"
msgid ""
"Return [code]true[/code] if the plugin is going to handle the given "
@@ -39971,6 +41951,51 @@ msgstr ""
"如果插件要处理给定的 [Resource] 类型 [param type],则返回 [code]true[/code]。"
msgid ""
+"Create and return a tooltip that will be displayed when the user hovers a "
+"resource under the given [param path] in filesystem dock.\n"
+"The [param metadata] dictionary is provided by preview generator (see method "
+"EditorResourcePreviewGenerator._generate]).\n"
+"[param base] is the base default tooltip, which is a [VBoxContainer] with a "
+"file name, type and size labels. If another plugin handled the same file "
+"type, [param base] will be output from the previous plugin. For best result, "
+"make sure the base tooltip is part of the returned [Control].\n"
+"[b]Note:[/b] It's unadvised to use [method ResourceLoader.load], especially "
+"with heavy resources like models or textures, because it will make the editor "
+"unresponsive when creating the tooltip. You can use [method "
+"request_thumbnail] if you want to display a preview in your tooltip.\n"
+"[b]Note:[/b] If you decide to discard the [param base], make sure to call "
+"[method Node.queue_free], because it's not freed automatically.\n"
+"[codeblock]\n"
+"func _make_tooltip_for_path(path, metadata, base):\n"
+" var t_rect = TextureRect.new()\n"
+" request_thumbnail(path, t_rect)\n"
+" base.add_child(t_rect) # The TextureRect will appear at the bottom of the "
+"tooltip.\n"
+" return base\n"
+"[/codeblock]"
+msgstr ""
+"创建并返回工具提示,会在用户悬停在文件系统面板上路径为 [param path] 的资源上时"
+"显示。\n"
+"元数据字典 [param metadata] 由预览生成器提供(见 [method "
+"EditorResourcePreviewGenerator._generate])。\n"
+"[param base] 是基础的默认工具提示,是一个包含文件名、类型、大小标签的 "
+"[VBoxContainer]。如果其他插件也能够处理相同的文件类型,那么 [param base] 就是"
+"上一个插件的输出。为了达到最佳效果,请确保基础工具提示是返回的 [Control] 的一"
+"部分。\n"
+"[b]注意:[/b]不建议使用 [method ResourceLoader.load],尤其是模型、纹理等开销较"
+"大的资源,否则会在创建工具提示时让编辑器失去响应。如果想要在工具提示中显示预"
+"览,可以使用 [method request_thumbnail]。\n"
+"[b]注意:[/b]如果你决定要丢弃 [param base],请确保调用了 [method Node."
+"queue_free],否则不会自动释放。\n"
+"[codeblock]\n"
+"func _make_tooltip_for_path(path, metadata, base):\n"
+" var t_rect = TextureRect.new()\n"
+" request_thumbnail(path, t_rect)\n"
+" base.add_child(t_rect) # TextureRect 会出现在工具提示的底部。\n"
+" return base\n"
+"[/codeblock]"
+
+msgid ""
"Requests a thumbnail for the given [TextureRect]. The thumbnail is created "
"asynchronously by [EditorResourcePreview] and automatically set when "
"available."
@@ -40174,7 +42199,7 @@ msgid ""
"dock on the editor. Add options via [method add_import_option] and [method "
"add_import_option_advanced]."
msgstr ""
-"重写以添加常规导入选项。这些将出现在编辑器的主导入停靠面板中。通过 [method "
+"覆盖以添加常规导入选项。这些将出现在编辑器的主导入停靠面板中。通过 [method "
"add_import_option] 和 [method add_import_option_advanced] 添加选项。"
msgid ""
@@ -40182,7 +42207,7 @@ msgid ""
"import dialog. Add options via [method add_import_option] and [method "
"add_import_option_advanced]."
msgstr ""
-"重写以添加内部导入选项。这些将出现在 3D 场景导入对话框中。通过 [method "
+"覆盖以添加内部导入选项。这些将出现在 3D 场景导入对话框中。通过 [method "
"add_import_option] 和 [method add_import_option_advanced] 添加选项。"
msgid ""
@@ -40384,7 +42409,7 @@ msgid "Emitted when the selection changes."
msgstr "更改选择时发出。"
msgid "Object that holds the project-independent editor settings."
-msgstr "保存与项目无关的编辑器设置的对象。"
+msgstr "保存编辑器设置的对象,这些设置与项目无关。"
msgid ""
"Object that holds the project-independent editor settings. These settings are "
@@ -40419,33 +42444,37 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_editor_settings]."
msgstr ""
-"保存与项目无关的编辑器设置的对象。这些设置通常在[b]编辑器 > 编辑器设置[/b]菜单"
+"保存编辑器设置的对象,这些设置与项目无关,通常在[b]编辑器 > 编辑器设置[/b]菜单"
"中可见。\n"
-"属性名称使用斜线分隔符来区分部分。设置的值可以是任何 [Variant] 类型。建议对编"
-"辑器设置使用 [code]snake_case[/code],以与 Godot 编辑器本身保持一致。\n"
+"属性名称中使用斜线分隔符来区分不同的部分。设置的值可以是任何 [Variant] 类型。"
+"编辑器设置的名称建议使用 [code]snake_case[/code] 形式,与 Godot 编辑器本身保持"
+"一致。\n"
"可以使用以下方法访问设置,例如:\n"
"[codeblocks]\n"
"[gdscript]\n"
"var settings = get_editor_interface().get_editor_settings()\n"
-"# `settings.set(\"some/property\", 10)` 在内部像该类重写 `_set()` 一样工作。\n"
+"# 也可以写 `settings.set(\"some/property\", 10)`,因为这个类内部覆盖了 "
+"`_set()`。\n"
"settings.set_setting(\"some/property\", 10)\n"
-"# `settings.get(\"some/property\")` 在内部像该类重写 `_get()` 一样工作。\n"
+"# 也可以写 `settings.get(\"some/property\")` ,因为这个类内部覆盖了 "
+"`_get()`。\n"
"settings.get_setting(\"some/property\")\n"
"var list_of_settings = settings.get_property_list()\n"
"[/gdscript]\n"
"[csharp]\n"
"EditorSettings settings = GetEditorInterface().GetEditorSettings();\n"
-"// `settings.set(\"some/property\", 10)` 在内部像该类重写 `_set()` 一样工"
-"作。\n"
+"// 也可以写 `settings.set(\"some/property\", 10)`,因为这个类内部覆盖了 "
+"`_set()`。\n"
"settings.SetSetting(\"some/property\", Value);\n"
-"// `settings.get(\"some/property\")` 在内部像该类重写 `_get()` 一样工作。\n"
+"// 也可以写 `settings.get(\"some/property\")` ,因为这个类内部覆盖了 "
+"`_get()`。\n"
"settings.GetSetting(\"some/property\");\n"
"Godot.Collections.Array<Godot.Collections.Dictionary> listOfSettings = "
"settings.GetPropertyList();\n"
"[/csharp]\n"
"[/codeblocks]\n"
-"[b]注意:[/b]该类不应被直接实例化。而是使用 [method EditorInterface."
-"get_editor_settings] 访问其单例。"
+"[b]注意:[/b]不能直接实例化这个类。请改用 [method EditorInterface."
+"get_editor_settings] 访问单例。"
msgid ""
"Adds a custom property info to a property. The dictionary must contain:\n"
@@ -41077,6 +43106,14 @@ msgstr ""
"时会被窗口管理器拦截。这意味着 Godot 不会看到该修饰键被按下。"
msgid ""
+"If [code]true[/code], warps the mouse around the 3D viewport while panning in "
+"the 3D editor. This makes it possible to pan over a large area without having "
+"to exit panning and adjust the mouse cursor."
+msgstr ""
+"如果为 [code]true[/code],则会在 3D 编辑器中平移时,鼠标超出 3D 视口范围后将其"
+"传送到对侧。这样在大型区域中平移就不必先退出平移然后调整鼠标光标。"
+
+msgid ""
"The modifier key that must be held to zoom in the 3D editor.\n"
"[b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will "
"be intercepted by the window manager when clicking a mouse button at the same "
@@ -41267,6 +43304,14 @@ msgstr ""
"panning/animation_editors_panning_scheme]。"
msgid ""
+"If [code]true[/code], warps the mouse around the 2D viewport while panning in "
+"the 2D editor. This makes it possible to pan over a large area without having "
+"to exit panning and adjust the mouse cursor."
+msgstr ""
+"如果为 [code]true[/code],则会在 2D 编辑器中平移时,鼠标超出 2D 视口范围后将其"
+"传送到对侧。这样在大型区域中平移就不必先退出平移然后调整鼠标光标。"
+
+msgid ""
"The radius in which points can be selected in the [Polygon2D] and "
"[CollisionPolygon2D] editors (in pixels). Higher values make it easier to "
"select points quickly, but can make it more difficult to select the expected "
@@ -41285,6 +43330,13 @@ msgstr ""
"形先前的形状。拖动一个点直到释放鼠标左键前,会显示该轮廓。"
msgid ""
+"If [code]true[/code], reopens shader files that were open in the shader "
+"editor when the project was last closed."
+msgstr ""
+"如果为 [code]true[/code],则会重新打开项目上一次关闭时着色器编辑器中打开的着色"
+"器文件。"
+
+msgid ""
"If [code]true[/code], displays a grid while the TileMap editor is active. See "
"also [member editors/tiles_editor/grid_color]."
msgstr ""
@@ -41558,6 +43610,9 @@ msgstr ""
"翻译由社区提供。如果发现错误,[url=$DOCS_URL/contributing/documentation/"
"editor_and_docs_localization.html]请在 Weblate 上为编辑器翻译作出贡献![/url]"
+msgid "The preferred monitor to display the editor."
+msgstr "显示编辑器所优先使用的监视器。"
+
msgid ""
"Expanding main editor window content to the title, if supported by "
"[DisplayServer]. See [constant DisplayServer.WINDOW_FLAG_EXTEND_TO_TITLE].\n"
@@ -42993,7 +45048,7 @@ msgstr "获取与该解析器关联的文件扩展名列表,例如 [code][\"cs
msgid ""
"Override this method to define a custom parsing logic to extract the "
"translatable strings."
-msgstr "重写该方法,定义自定义解析逻辑以提取可翻译的字符串。"
+msgstr "覆盖该方法,定义自定义解析逻辑以提取可翻译的字符串。"
msgid "Manages undo history of scenes opened in the editor."
msgstr "管理编辑器中打开场景的撤销历史。"
@@ -43198,8 +45253,8 @@ msgstr ""
"定义编辑器使用的 API,负责从底层 VCS 提取信息。该 API 的实现包含在 VCS 插件"
"中,这些插件是继承 [EditorVCSInterface] 并被附加(按需)到 "
"[EditorVCSInterface] 的单例实例的 GDExtension 插件。以下列出的所有虚函数都不会"
-"亲自执行操作,而是会去调用 VCS 插件中内部重写的函数,以提供即插即用的体验。自"
-"定义 VCS 插件应当继承 [EditorVCSInterface] 并重写这些虚函数。"
+"亲自执行操作,而是会去调用 VCS 插件中内部覆盖的函数,以提供即插即用的体验。自"
+"定义 VCS 插件应当继承 [EditorVCSInterface] 并覆盖这些虚函数。"
msgid "Checks out a [param branch_name] in the VCS."
msgstr "检出 VCS 中的 [param branch_name] 分支。"
@@ -43508,14 +45563,45 @@ msgstr ""
"使用指定的端口 [param port] 并分配所需的通道 [param channels],向外部地址 "
"[param address] 建立连接。可以在连接期间可以传递数据 [param data] ,形式为 32 "
"位整数。\n"
-"[b]注意:[/b]在调用此方法之前,必须先调用 [method create_host] 或 [method "
+"[b]注意:[/b]在调用此方法之前,必须先调用 [method create_host] 或 [method "
"create_host_bound]。"
+msgid ""
+"Create an ENetHost that will allow up to [param max_peers] connected peers, "
+"each allocating up to [param max_channels] channels, optionally limiting "
+"bandwidth to [param in_bandwidth] and [param out_bandwidth]."
+msgstr ""
+"创建一个 ENetHost,最多允许 [param max_peers] 个连接的对等体,每个连接最多分"
+"配 [param max_channels] 个通道,可选择将带宽限制为 [param in_bandwidth] 和 "
+"[param out_bandwidth]。"
+
+msgid ""
+"Create an ENetHost like [method create_host] which is also bound to the given "
+"[param bind_address] and [param bind_port]."
+msgstr ""
+"创建一个类似 [method create_host] 的 ENetHost,它还被绑定到给定的 [param "
+"bind_address] 和 [param bind_port]。"
+
msgid "Destroys the host and all resources associated with it."
msgstr "销毁主机和与其关联的所有资源。"
msgid ""
"Configure this ENetHost to use the custom Godot extension allowing DTLS "
+"encryption for ENet clients. Call this before [method connect_to_host] to "
+"have ENet connect using DTLS validating the server certificate against [param "
+"hostname]. You can pass the optional [param client_options] parameter to "
+"customize the trusted certification authorities, or disable the common name "
+"verification. See [method TLSOptions.client] and [method TLSOptions."
+"client_unsafe]."
+msgstr ""
+"配置此 ENetHost 以使用允许对 ENet 客户端进行 DTLS 加密的自定义 Godot 扩展。在 "
+"[method connect_to_host] 之前调用它,让 ENet 连接使用 DTLS 根据 [param "
+"hostname] 验证服务器证书。可以通过可选的 [param client_options] 参数来自定义受"
+"信任的证书颁发机构,或禁用通用名称验证。见 [method TLSOptions.client] 和 "
+"[method TLSOptions.client_unsafe]。"
+
+msgid ""
+"Configure this ENetHost to use the custom Godot extension allowing DTLS "
"encryption for ENet servers. Call this right after [method create_host_bound] "
"to have ENet expect peers to connect using DTLS. See [method TLSOptions."
"server]."
@@ -43570,6 +45656,32 @@ msgstr ""
"定期调用该函数来处理连接、断开连接、和接收新数据包。"
msgid ""
+"Sends a [param packet] toward a destination from the address and port "
+"currently bound by this ENetConnection instance. \n"
+"This is useful as it serves to establish entries in NAT routing tables on all "
+"devices between this bound instance and the public facing internet, allowing "
+"a prospective client's connection packets to be routed backward through the "
+"NAT device(s) between the public internet and this host.\n"
+"This requires forward knowledge of a prospective client's address and "
+"communication port as seen by the public internet - after any NAT devices "
+"have handled their connection request. This information can be obtained by a "
+"[url=https://en.wikipedia.org/wiki/STUN]STUN[/url] service, and must be "
+"handed off to your host by an entity that is not the prospective client. This "
+"will never work for a client behind a Symmetric NAT due to the nature of the "
+"Symmetric NAT routing algorithm, as their IP and Port cannot be known "
+"beforehand."
+msgstr ""
+"向目标发送数据包 [param packet],发送方是该 ENetConnection 实例当前绑定的地址"
+"和端口。\n"
+"这样能够在该绑定实例和公共互联网之间的所有设备的 NAT 路由表中建立相关条目,因"
+"此非常有用,能够让潜在客户端的连接数据包能够通过公共互联网和该主机之间的 NAT "
+"设备进行反向路由。\n"
+"要求在 NAT 设备处理连接请求后,预先了解公共互联网所看到的潜在客户端的地址和通"
+"信端口。这一信息可以通过 [url=https://zh.wikipedia.org/wiki/STUN]STUN[/url] 服"
+"务获取,必须由非潜在客户端的实体交给你的主机。由于对称 NAT 路由算法的性质,这"
+"种方法对于对称 NAT 之后的客户端无效,因为无法提前得知他们的 IP 和端口。"
+
+msgid ""
"No compression. This uses the most bandwidth, but has the upside of requiring "
"the fewest CPU resources. This option may also be used to make network "
"debugging using tools like Wireshark easier."
@@ -44105,7 +46217,57 @@ msgid ""
"The [Engine] singleton allows you to query and modify the project's run-time "
"parameters, such as frames per second, time scale, and others."
msgstr ""
-"[Engine] 单例使您可以查询和修改项目的运行时参数,例如每秒帧数,时间范围等。"
+"[Engine] 单例使你可以查询和修改项目的运行时参数,例如每秒帧数,时间范围等。"
+
+msgid ""
+"Returns the name of the CPU architecture the Godot binary was built for. "
+"Possible return values are [code]x86_64[/code], [code]x86_32[/code], "
+"[code]arm64[/code], [code]arm32[/code], [code]rv64[/code], [code]riscv[/"
+"code], [code]ppc64[/code], [code]ppc[/code], [code]wasm64[/code] and "
+"[code]wasm32[/code].\n"
+"To detect whether the current CPU architecture is 64-bit, you can use the "
+"fact that all 64-bit architecture names have [code]64[/code] in their name:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"if \"64\" in Engine.get_architecture_name():\n"
+" print(\"Running a 64-bit build of Godot.\")\n"
+"else:\n"
+" print(\"Running a 32-bit build of Godot.\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"if (Engine.GetArchitectureName().Contains(\"64\"))\n"
+" GD.Print(\"Running a 64-bit build of Godot.\");\n"
+"else\n"
+" GD.Print(\"Running a 32-bit build of Godot.\");\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[b]Note:[/b] [method get_architecture_name] does [i]not[/i] return the name "
+"of the host CPU architecture. For example, if running an x86_32 Godot binary "
+"on a x86_64 system, the returned value will be [code]x86_32[/code]."
+msgstr ""
+"返回构建 Godot 二进制文件所针对的 CPU 架构的名称。可能的返回值有 "
+"[code]x86_64[/code]、[code]x86_32[/code]、[code]arm64[/code]、[code]arm32[/"
+"code]、[code]rv64[/code]、[code]riscv[/code]、[code]ppc64[/code]、[code]ppc[/"
+"code]、[code]wasm64[/code] 和 [code]wasm32[/code]。\n"
+"要检测当前 CPU 架构是否为 64 位,可以利用所有 64 位架构名称中都包含 [code]64[/"
+"code]:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"if \"64\" in Engine.get_architecture_name():\n"
+" print(\"正在运行 64 位 Godot。\")\n"
+"else:\n"
+" print(\"正在运行 32 位 Godot。\")\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"if (Engine.GetArchitectureName().Contains(\"64\"))\n"
+" GD.Print(\"正在运行 64 位 Godot。\");\n"
+"else\n"
+" GD.Print(\"正在运行 32 位 Godot。\");\n"
+"[/csharp]\n"
+"[/codeblocks]\n"
+"[b]注意:[/b][method get_architecture_name] 返回的[i]不是[/i]主机 CPU 架构的名"
+"称。例如,如果在 x86_64 系统上运行 x86_32 的 Godot 二进制文件,那么返回值将是 "
+"[code]x86_32[/code]。"
msgid ""
"Returns engine author information in a Dictionary.\n"
@@ -46300,7 +48462,7 @@ msgid ""
"[/codeblocks]"
msgstr ""
"如果文件光标已经读到了文件末尾,则返回 [code]true[/code]。\n"
-"[b]注意:[/b] [code]eof_reached() == false[/code] 不能用于检查是否有更多可用数"
+"[b]注意:[/b][code]eof_reached() == false[/code] 不能用于检查是否有更多可用数"
"据。要在有更多可用数据时循环,请使用:\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -46341,8 +48503,8 @@ msgstr ""
"将文件的缓冲区写入磁盘。当关闭文件时,会自动进行刷新。这意味着你不需要在关闭文"
"件前手动调用 [method flush]。尽管如此,即使项目崩溃而不是正常关闭,调用 "
"[method flush] 仍可用于确保数据安全。\n"
-"[b]注意:[/b] 只有在你真正需要的时候才调用 [method flush]。否则,它会因不断的"
-"磁盘写入而降低性能。"
+"[b]注意:[/b]只有在你真正需要的时候才调用 [method flush]。否则,它会因不断的磁"
+"盘写入而降低性能。"
msgid ""
"Returns the next 8 bits from the file as an integer. See [method store_8] for "
@@ -46466,6 +48628,14 @@ msgid ""
msgstr "返回一个给定路径文件的 MD5 字符串,如果失败则返回一个空的 [String]。"
msgid ""
+"Returns the last time the [param file] was modified in Unix timestamp format "
+"or returns a [String] \"ERROR IN [param file]\". This Unix timestamp can be "
+"converted to another format using the [Time] singleton."
+msgstr ""
+"以 Unix 时间戳格式返回 [param file]的最后修改时间,或者返回一个 [String] “在 "
+"[param file] 中出错”。这个Unix 时间戳可以用 [Time] 单例转换为其他格式。"
+
+msgid ""
"Returns a [String] saved in Pascal format from the file.\n"
"Text is interpreted as being UTF-8 encoded."
msgstr ""
@@ -46830,6 +49000,28 @@ msgid "Uses the [url=https://www.gzip.org/]gzip[/url] compression method."
msgstr "使用 [url=https://www.gzip.org/]gzip[/url] 压缩方法。"
msgid ""
+"Uses the [url=https://github.com/google/brotli]brotli[/url] compression "
+"method (only decompression is supported)."
+msgstr ""
+"使用 [url=https://github.com/google/brotli]brotli[/url] 压缩方法(仅支持解压"
+"缩)。"
+
+msgid "A dialog for selecting files or directories in the filesystem."
+msgstr "用于选择文件系统中的文件或目录的对话框。"
+
+msgid ""
+"[FileDialog] is a preset dialog used to choose files and directories in the "
+"filesystem. It supports filter masks. [FileDialog] automatically sets its "
+"window title according to the [member file_mode]. If you want to use a custom "
+"title, disable this by setting [member mode_overrides_title] to [code]false[/"
+"code]."
+msgstr ""
+"[FileDialog] 是用来选择文件系统中文件和目录的预设对话框。支持过滤器掩码。"
+"[FileDialog] 会根据 [member file_mode] 自动设置窗口的标题。如果你想使用自定义"
+"标题,请将 [member mode_overrides_title] 设置为 [code]false[/code],禁用此功"
+"能。"
+
+msgid ""
"Adds a comma-delimited file name [param filter] option to the [FileDialog] "
"with an optional [param description], which restricts what files can be "
"picked.\n"
@@ -46862,7 +49054,7 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"返回对话框的垂直框容器,可以向其中添加自定义控件。\n"
-"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果您希望隐"
+"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果你希望隐"
"藏它或其任何子项,请使用它们的 [member CanvasItem.visible] 属性。"
msgid "Invalidate and update the current dialog content list."
@@ -48418,7 +50610,7 @@ msgid ""
"will prevent MSDF fonts and [TextMesh] from working correctly."
msgstr ""
"如果不等于零,则加粗字体轮廓。负值会减小轮廓厚度。\n"
-"[b]注意:[/b] 加粗字体可能有自相交的轮廓,这将阻止 MSDF 字体和 [TextMesh] 正常"
+"[b]注意:[/b]加粗字体可能有自相交的轮廓,这将阻止 MSDF 字体和 [TextMesh] 正常"
"工作。"
msgid "Active face index in the TrueType / OpenType collection file."
@@ -49395,6 +51587,26 @@ msgid ""
msgstr "选择的阴影投射标志。可能的取值见 [enum ShadowCastingSetting]。"
msgid ""
+"Overrides the bounding box of this node with a custom one. This can be used "
+"to avoid the expensive [AABB] recalculation that happens when a skeleton is "
+"used with a [MeshInstance3D] or to have fine control over the "
+"[MeshInstance3D]'s bounding box. To use the default AABB, set value to an "
+"[AABB] with all fields set to [code]0.0[/code]. To avoid frustum culling, set "
+"[member custom_aabb] to a very large AABB that covers your entire game world "
+"such as [code]AABB(-10000, -10000, -10000, 20000, 20000, 20000)[/code]. To "
+"disable all forms of culling (including occlusion culling), call [method "
+"RenderingServer.instance_set_ignore_culling] on the [GeometryInstance3D]'s "
+"[RID]."
+msgstr ""
+"使用自定义边界框覆盖该节点的边界框。骨架使用 [MeshInstance3D] 时可以避免重新计"
+"算 [AABB] 节省性能,也可以用来对 [MeshInstance3D] 的边界框进行精确控制。要使用"
+"默认的 AABB,请将其设为所有字段均为 [code]0.0[/code] 的 [AABB]。要避免视锥剔"
+"除,请将 [member custom_aabb] 设为大到能够覆盖整个游戏世界的 AABB,例如 "
+"[code]AABB(-10000, -10000, -10000, 20000, 20000, 20000)[/code]。要禁用所有形式"
+"的剔除(包括遮挡剔除),请使用该 [GeometryInstance3D] 的 [RID] 调用 [method "
+"RenderingServer.instance_set_ignore_culling]。"
+
+msgid ""
"The extra distance added to the GeometryInstance3D's bounding box ([AABB]) to "
"increase its cull box."
msgstr ""
@@ -49871,7 +52083,7 @@ msgid ""
"_convert_scene_node] and before [method _export_post].\n"
"This method can be used to modify the final JSON of each node."
msgstr ""
-"导出过程的一部分。该方法在 [method _convert_scene_node] 之后和 [method "
+"导出过程的一部分。该方法在 [method _convert_scene_node] 之后 [method "
"_export_post] 之前运行。\n"
"该方法可用于修改每个节点的最终 JSON。"
@@ -49903,7 +52115,7 @@ msgid ""
"will be added to the scene tree. Multiple nodes can be generated in this step "
"if they are added as a child of the returned node."
msgstr ""
-"导入过程的一部分。该方法在 [method _parse_node_extensions] 之后和 [method "
+"导入过程的一部分。该方法在 [method _parse_node_extensions] 之后 [method "
"_import_post_parse] 之前运行。\n"
"当从 GLTFNode 生成一个 Godot 场景节点时运行。返回的节点将被添加到场景树中。如"
"果将多个节点添加为返回节点的子节点,则可以在该步骤中生成这些节点。"
@@ -49915,7 +52127,7 @@ msgid ""
"GLTFDocumentExtension class. This is used to validate if a GLTF file with "
"required extensions can be loaded."
msgstr ""
-"导入过程的一部分。该方法在 [method _import_preflight] 之后和 [method "
+"导入过程的一部分。该方法在 [method _import_preflight] 之后 [method "
"_parse_node_extensions] 之前运行。\n"
"返回一组被该 GLTFDocumentExtension 类支持的 GLTF 扩展。这用于验证是否可以加载"
"一个具有所需扩展名的 GLTF 文件。"
@@ -49926,7 +52138,7 @@ msgid ""
"This method can be used to make modifications to each of the generated Godot "
"scene nodes."
msgstr ""
-"导入过程的一部分。该方法在 [method _import_post_parse] 之后和 [method "
+"导入过程的一部分。该方法在 [method _import_post_parse] 之后 [method "
"_import_post] 之前运行。\n"
"该方法可用于对每个生成的 Godot 场景节点进行修改。"
@@ -49945,7 +52157,7 @@ msgid ""
"This method can be used to modify any of the data imported so far, including "
"any scene nodes, before running the final per-node import step."
msgstr ""
-"导入过程的一部分。该方法在 [method _generate_scene_node] 之后和 [method "
+"导入过程的一部分。该方法在 [method _generate_scene_node] 之后 [method "
"_import_node] 之前运行。\n"
"在运行最终的各节点导入步骤之前,该方法可用于修改到目前为止导入的任何数据,包括"
"任何场景节点。"
@@ -49965,6 +52177,17 @@ msgstr ""
msgid ""
"Part of the import process. This method is run after [method "
+"_parse_node_extensions] and before [method _parse_texture_json].\n"
+"Runs when parsing image data from a GLTF file. The data could be sourced from "
+"a separate file, a URI, or a buffer, and then is passed as a byte array."
+msgstr ""
+"导入过程的一部分。该方法在 [method _parse_node_extensions] 之后 [method "
+"_parse_texture_json] 之前运行。\n"
+"从 GLTF 文件中解析图像数据时运行。数据可以从单独的文件、URI 或缓冲中获取,然后"
+"作为字节数组传递。"
+
+msgid ""
+"Part of the import process. This method is run after [method "
"_get_supported_extensions] and before [method _generate_scene_node].\n"
"Runs when parsing the node extensions of a GLTFNode. This method can be used "
"to process the extension JSON data into a format that can be used by [method "
@@ -49977,6 +52200,16 @@ msgstr ""
"[method _generate_scene_node] 使用的格式。该返回值应该是 [enum Error] 枚举中的"
"一个成员。"
+msgid ""
+"Part of the import process. This method is run after [method "
+"_parse_image_data] and before [method _generate_scene_node].\n"
+"Runs when parsing the texture JSON from the GLTF textures array. This can be "
+"used to set the source image index to use as the texture."
+msgstr ""
+"导入过程的一部分。该方法在 [method _parse_image_data] 之后 [method "
+"_generate_scene_node] 之前运行。\n"
+"从 GLTF 纹理数组中解析纹理 JSON 时运行。可用于设置用作纹理的源图像索引。"
+
msgid "Represents a GLTF light."
msgstr "代表 GLTF 灯光。"
@@ -50460,6 +52693,13 @@ msgstr ""
"引用的相机。"
msgid ""
+"Gets the images of the GLTF file as an array of [Texture2D]s. These are the "
+"images that the [member GLTFTexture.src_image] index refers to."
+msgstr ""
+"以 [Texture2D] 数组的形式获取 GLTF 文件中的图像。这些是 [member GLTFTexture."
+"src_image] 索引引用的图像。"
+
+msgid ""
"Returns an array of all [GLTFLight]s in the GLTF file. These are the lights "
"that the [member GLTFNode.light] index refers to."
msgstr ""
@@ -50474,6 +52714,20 @@ msgstr ""
"的网格。"
msgid ""
+"Returns the index of the [GLTFNode] corresponding to this Godot scene node. "
+"This is the inverse of [method get_scene_node]. Useful during the export "
+"process.\n"
+"[b]Note:[/b] Not every Godot scene node will have a corresponding [GLTFNode], "
+"and not every [GLTFNode] will have a scene node generated. If there is no "
+"[GLTFNode] index for this scene node, [code]-1[/code] is returned."
+msgstr ""
+"返回与该 Godot 场景节点对应的 [GLTFNode] 的索引。这个方法与 [method "
+"get_scene_node] 互逆。可以在导出过程中使用。\n"
+"[b]注意:[/b]并不是所有 Godot 场景节点都有对应的 [GLTFNode],也并不是所有 "
+"[GLTFNode] 都会生成场景节点。如果该场景节点没有 [GLTFNode] 索引,则会返回 "
+"[code]-1[/code]。"
+
+msgid ""
"Returns an array of all [GLTFNode]s in the GLTF file. These are the nodes "
"that [member GLTFNode.children] and [member root_nodes] refer to. This "
"includes nodes that may not be generated in the Godot scene, or nodes that "
@@ -50484,6 +52738,20 @@ msgstr ""
"可能生成多个 Godot 场景节点的节点。"
msgid ""
+"Returns the Godot scene node that corresponds to the same index as the "
+"[GLTFNode] it was generated from. This is the inverse of [method "
+"get_node_index]. Useful during the import process.\n"
+"[b]Note:[/b] Not every [GLTFNode] will have a scene node generated, and not "
+"every generated scene node will have a corresponding [GLTFNode]. If there is "
+"no scene node for this [GLTFNode] index, [code]null[/code] is returned."
+msgstr ""
+"返回指定索引的 [GLTFNode] 对应生成的 Godot 场景节点。这个方法与 [method "
+"get_node_index] 互逆。可以在导入过程中使用。\n"
+"[b]注意:[/b]并不是所有 [GLTFNode] 都会生成场景节点,也并不是所有 Godot 场景节"
+"点都有对应的 [GLTFNode]。如果该 [GLTFNode] 索引没有场景节点,则会返回 "
+"[code]null[/code]。"
+
+msgid ""
"Returns an array of all [GLTFSkeleton]s in the GLTF file. These are the "
"skeletons that the [member GLTFNode.skeleton] index refers to."
msgstr ""
@@ -50541,6 +52809,14 @@ msgstr ""
"设置该状态中的 [GLTFCamera]。这些是 [member GLTFNode.camera] 索引引用的相机。"
msgid ""
+"Sets the images in the state stored as an array of [Texture2D]s. This can be "
+"used during export. These are the images that the [member GLTFTexture."
+"src_image] index refers to."
+msgstr ""
+"设置状态中以 [Texture2D] 数组形式存储的图像。可以在导出时使用。这些是 [member "
+"GLTFTexture.src_image] 索引所引用的图像。"
+
+msgid ""
"Sets the [GLTFLight]s in the state. These are the lights that the [member "
"GLTFNode.light] index refers to."
msgstr ""
@@ -50633,6 +52909,13 @@ msgstr ""
"纹理采样器的 ID,在对图像进行采样时使用。如果为 -1,则使用默认的纹理采样器(线"
"性过滤,并在两个轴上重复环绕)。"
+msgid ""
+"The index of the image associated with this texture, see [method GLTFState."
+"get_images]. If -1, then this texture does not have an image assigned."
+msgstr ""
+"与该纹理关联的图像索引,见 [method GLTFState.get_images]。如果为 -1,则该纹理"
+"未与图像相关联。"
+
msgid "Represents a GLTF texture sampler"
msgstr "代表 GLTF 纹理采样器"
@@ -50761,7 +53044,7 @@ msgid ""
"trail_section_subdivisions] properties."
msgstr ""
"如果[code]true[/code] ,可以使用网格换肤系统来启用粒子轨迹。\n"
-"[b]注意:[/b] 与[GPUParticles3D]不同的是,trail sections和subdivisions的数量是"
+"[b]注意:[/b]与[GPUParticles3D]不同的是,trail sections和subdivisions的数量是"
"通过属性[member trail_sections]和[member trail_section_subdivisions]设置的。"
msgid ""
@@ -50843,7 +53126,7 @@ msgstr "用粒子控制数千条鱼"
msgid ""
"Returns the axis-aligned bounding box that contains all the particles that "
"are active in the current frame."
-msgstr "返回包含当前帧中所有活动粒子的轴对齐包围盒。"
+msgstr "返回包含当前帧中所有活动粒子的轴对齐边界框。"
msgid "Returns the [Mesh] that is drawn at index [param pass]."
msgstr "返回在索引 [param pass] 处绘制的 [Mesh] 。"
@@ -51165,10 +53448,10 @@ msgid ""
"[CPUParticles3D]."
msgstr ""
"盒状3D粒子碰撞形状影响[GPUParticles3D]节点。\n"
-"[b]注意:[/b] [member ParticleProcessMaterial.collision_mode]必须是[constant "
+"[b]注意:[/b][member ParticleProcessMaterial.collision_mode]必须是[constant "
"ParticleProcessMaterial.COLLISION_RIGID]或[constant ParticleProcessMaterial."
"COLLISION_HIDE_ON_CONTACT]在经过[GPUParticles3D]的材质上,碰撞才能发挥作用。\n"
-"[b]注意:[/b] 粒子碰撞只影响到[GPUParticles3D],而不是[CPUParticles3D]。"
+"[b]注意:[/b]粒子碰撞只影响到[GPUParticles3D],而不是[CPUParticles3D]。"
msgid "The collision box's size in 3D units."
msgstr "碰撞框的范围,使用 3D 单位。"
@@ -51505,6 +53788,18 @@ msgid "Sets the offset for the gradient color at index [param point]."
msgstr "设置渐变色在索引 [param point] 处的偏移。"
msgid ""
+"Gradient's colors returned as a [PackedColorArray].\n"
+"[b]Note:[/b] This property returns a copy, modifying the return value does "
+"not update the gradient. To update the gradient use [method set_color] method "
+"(for updating colors individually) or assign to this property directly (for "
+"bulk-updating all colors at once)."
+msgstr ""
+"[PackedColorArray] 形式的渐变色颜色。\n"
+"[b]注意:[/b]这个属性返回的是副本,修改返回值并不会对渐变色进行更新。要更新渐"
+"变色,请使用 [method set_color] 方法(单独更新颜色)或直接为这个属性赋值(一次"
+"性更新所有颜色)。"
+
+msgid ""
"The color space used to interpolate between points of the gradient. It does "
"not affect the returned colors, which will always be in sRGB space. See [enum "
"ColorSpace] for available modes.\n"
@@ -51522,6 +53817,18 @@ msgid ""
msgstr "用于在渐变点之间进行插值的算法。可用的模式见 [enum InterpolationMode]。"
msgid ""
+"Gradient's offsets returned as a [PackedFloat32Array].\n"
+"[b]Note:[/b] This property returns a copy, modifying the return value does "
+"not update the gradient. To update the gradient use [method set_offset] "
+"method (for updating offsets individually) or assign to this property "
+"directly (for bulk-updating all offsets at once)."
+msgstr ""
+"[PackedFloat32Array] 形式的渐变色偏移。\n"
+"[b]注意:[/b]这个属性返回的是副本,修改返回值并不会对渐变色进行更新。要更新渐"
+"变色,请使用 [method set_offset] 方法(单独更新偏移)或直接为这个属性赋值(一"
+"次性更新所有偏移)。"
+
+msgid ""
"Constant interpolation, color changes abruptly at each point and stays "
"uniform between. This might cause visible aliasing when used for a gradient "
"texture in some cases."
@@ -51638,6 +53945,9 @@ msgstr "颜色按照直线进行线性插值。"
msgid "The colors are linearly interpolated in a circular pattern."
msgstr "颜色按照圆形模式进行线性插值。"
+msgid "The colors are linearly interpolated in a square pattern."
+msgstr "颜色按照方形模式进行线性插值。"
+
msgid ""
"The gradient fill is restricted to the range defined by [member fill_from] to "
"[member fill_to] offsets."
@@ -52500,6 +54810,19 @@ msgid "A container that arranges its child controls in a grid layout."
msgstr "将子控件按照网格布局排列的容器。"
msgid ""
+"[GridContainer] arranges its child controls in a grid layout. The number of "
+"columns is specified by the [member columns] property, whereas the number of "
+"rows depends on how many are needed for the child controls. The number of "
+"rows and columns is preserved for every size of the container.\n"
+"[b]Note:[/b] [GridContainer] only works with child nodes inheriting from "
+"[Control]. It won't rearrange child nodes inheriting from [Node2D]."
+msgstr ""
+"[GridContainer] 会将其子控件按照网格布局排列。网格的列数由 [member columns] 属"
+"性指定,行数取决于容器中子控件的数量。将保留每个大小的容器的列和行。\n"
+"[b]注意:[/b][GridContainer] 只对继承自 [Control] 的子节点生效。它不会重新排列"
+"继承自 [Node2D] 的子节点。"
+
+msgid ""
"The number of columns in the [GridContainer]. If modified, [GridContainer] "
"reorders its Control-derived children to accommodate the new layout."
msgstr ""
@@ -52615,6 +54938,11 @@ msgid ""
msgstr "返回一个包含网格中非空单元格坐标的 [Vector3] 数组。"
msgid ""
+"Returns an array of all cells with the given item index specified in [param "
+"item]."
+msgstr "返回所有具有 [param item] 中指定的项目索引的单元格的数组。"
+
+msgid ""
"Returns the map coordinates of the cell containing the given [param "
"local_position]. If [param local_position] is in global coordinates, consider "
"using [method Node3D.to_local] before passing it to this method. See also "
@@ -52733,6 +55061,19 @@ msgstr ""
"代表一个空的单元格)的无效单元格。"
msgid ""
+"A physics joint that restricts the movement of two 2D physics bodies to a "
+"fixed axis."
+msgstr "将两个物理体的运动限制在某个固定轴上的物理关节。"
+
+msgid ""
+"A physics joint that restricts the movement of two 2D physics bodies to a "
+"fixed axis. For example, a [StaticBody2D] representing a piston base can be "
+"attached to a [RigidBody2D] representing the piston head, moving up and down."
+msgstr ""
+"将两个物理体的运动限制在某个固定轴上的物理关节。例如代表活塞基底的 "
+"[StaticBody2D] 可以附加至代表能够上下移动的活塞头的 [RigidBody2D] 之上。"
+
+msgid ""
"The body B's initial anchor position defined by the joint's origin and a "
"local offset [member initial_offset] along the joint's Y axis (along the "
"groove)."
@@ -52749,6 +55090,113 @@ msgid ""
"Provides functionality for computing cryptographic hashes chunk by chunk."
msgstr "提供分段计算加密哈希的功能。"
+msgid ""
+"The HashingContext class provides an interface for computing cryptographic "
+"hashes over multiple iterations. Useful for computing hashes of big files (so "
+"you don't have to load them all in memory), network streams, and data streams "
+"in general (so you don't have to hold buffers).\n"
+"The [enum HashType] enum shows the supported hashing algorithms.\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"const CHUNK_SIZE = 1024\n"
+"\n"
+"func hash_file(path):\n"
+" # Check that file exists.\n"
+" if not FileAccess.file_exists(path):\n"
+" return\n"
+" # Start a SHA-256 context.\n"
+" var ctx = HashingContext.new()\n"
+" ctx.start(HashingContext.HASH_SHA256)\n"
+" # Open the file to hash.\n"
+" var file = FileAccess.open(path, FileAccess.READ)\n"
+" # Update the context after reading each chunk.\n"
+" while not file.eof_reached():\n"
+" ctx.update(file.get_buffer(CHUNK_SIZE))\n"
+" # Get the computed hash.\n"
+" var res = ctx.finish()\n"
+" # Print the result as hex string and array.\n"
+" printt(res.hex_encode(), Array(res))\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public const int ChunkSize = 1024;\n"
+"\n"
+"public void HashFile(string path)\n"
+"{\n"
+" // Check that file exists.\n"
+" if (!FileAccess.FileExists(path))\n"
+" {\n"
+" return;\n"
+" }\n"
+" // Start a SHA-256 context.\n"
+" var ctx = new HashingContext();\n"
+" ctx.Start(HashingContext.HashType.Sha256);\n"
+" // Open the file to hash.\n"
+" using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);\n"
+" // Update the context after reading each chunk.\n"
+" while (!file.EofReached())\n"
+" {\n"
+" ctx.Update(file.GetBuffer(ChunkSize));\n"
+" }\n"
+" // Get the computed hash.\n"
+" byte[] res = ctx.Finish();\n"
+" // Print the result as hex string and array.\n"
+" GD.PrintT(res.HexEncode(), (Variant)res);\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"HashingContext 类提供了一个接口,用于在多次迭代中计算加密哈希值。常用于计算大"
+"文件(不必全部加载到内存中)、网络流和一般数据流(不必持有缓冲区)的哈希值。\n"
+"[enum HashType] 枚举显示了支持的哈希算法。\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"const CHUNK_SIZE = 1024\n"
+"\n"
+"func hash_file(path):\n"
+" # 检查文件是否存在。\n"
+" if not FileAccess.file_exists(path):\n"
+" return\n"
+" # 启动一个 SHA-256 上下文。\n"
+" var ctx = HashingContext.new()\n"
+" ctx.start(HashingContext.HASH_SHA256)\n"
+" # 打开文件进行哈希处理。\n"
+" var file = FileAccess.open(path, FileAccess.READ)\n"
+" # 读取每个块后更新上下文。\n"
+" while not file.eof_reached():\n"
+" ctx.update(file.get_buffer(CHUNK_SIZE))\n"
+" # 获取计算的哈希值。\n"
+" var res = ctx.finish()\n"
+" # 将结果打印为十六进制字符串和数组。\n"
+" printt(res.hex_encode(), Array(res))\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"public const int ChunkSize = 1024;\n"
+"\n"
+"public void HashFile(string path)\n"
+"{\n"
+" // 检查文件是否存在。\n"
+" if (!FileAccess.FileExists(path))\n"
+" {\n"
+" return;\n"
+" }\n"
+" // 启动一个 SHA-256 上下文。\n"
+" var ctx = new HashingContext();\n"
+" ctx.Start(HashingContext.HashType.Sha256);\n"
+" // 打开文件进行哈希处理。\n"
+" using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);\n"
+" // 读取每个块后更新上下文。\n"
+" while (!file.EofReached())\n"
+" {\n"
+" ctx.Update(file.GetBuffer(ChunkSize));\n"
+" }\n"
+" // 获取计算的哈希值。\n"
+" byte[] res = ctx.Finish();\n"
+" // 将结果打印为十六进制字符串和数组。\n"
+" GD.PrintT(res.HexEncode(), (Variant)res);\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid "Closes the current context, and return the computed hash."
msgstr "关闭当前上下文,并返回计算出的哈希值。"
@@ -53238,7 +55686,7 @@ msgstr ""
"[b]注意:[/b]TLS 支持目前仅限于 TLS 1.0、TLS 1.1 和 TLS 1.2。尝试连接到仅支持 "
"TLS 1.3 的服务器时将返回一个错误。\n"
"[b]警告:[/b]目前不支持 TLS 证书撤销和证书绑定。只要吊销的证书在其他方面有效,"
-"就会被接受。如果这是一个问题,您可能希望使用有效期较短的自动管理的证书。"
+"就会被接受。如果这是一个问题,你可能希望使用有效期较短的自动管理的证书。"
msgid "HTTP client class"
msgstr "HTTP 客户端类"
@@ -54446,9 +56894,9 @@ msgstr ""
"[/csharp]\n"
"[/codeblocks]\n"
"[b]Gzipped 响应体[/b]:HTTPRequest 将自动处理响应体的解压缩。除非已经指定了一"
-"个,否则 [code]Accept-Encoding[/code] 报头将自动添加到您的每个请求中。任何带"
+"个,否则 [code]Accept-Encoding[/code] 报头将自动添加到你的每个请求中。任何带"
"有 [code]Content-Encoding: gzip[/code] 报头的响应都将自动解压,并作为未压缩的"
-"字节传送给您。"
+"字节传送给你。"
msgid "Making HTTP requests"
msgstr "发出 HTTP 请求"
@@ -54504,7 +56952,7 @@ msgstr ""
"返回 [constant ERR_CANT_CONNECT]。\n"
"[b]注意:[/b]当 [param method] 为 [constant HTTPClient.METHOD_GET] 时,通过 "
"[param request_data] 发送的有效载荷可能会被服务器忽略,甚至导致服务器拒绝请求"
-"(参阅 [url= https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1]RFC "
+"(参阅 [url=https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1]RFC "
"7231 第 4.3.1 节[/url]了解更多详情)。作为一种变通方法,可以在 URL 中将数据作"
"为查询字符串发送(有关示例,请参见 [method String.uri_encode])。\n"
"[b]注意:[/b]建议使用传输加密(TLS)并避免在 HTTP GET URL 参数中发送敏感信息"
@@ -56639,8 +59087,8 @@ msgstr ""
"[b]注意:[/b]对于 Android,[method vibrate_handheld] 需要在导出预设中启用 "
"[code]VIBRATE[/code] 权限。否则,[method vibrate_handheld] 将无效。\n"
"[b]注意:[/b]对于 iOS,仅 iOS 13 及更高版本支持指定持续时间。\n"
-"[b]注意:[/b] 某些网络浏览器,如 Safari 和 Android 版的 Firefox 不支持 "
-"[method vibrate_handheld]。"
+"[b]注意:[/b]某些网络浏览器,如 Safari 和 Android 版的 Firefox 不支持 [method "
+"vibrate_handheld]。"
msgid ""
"Sets the mouse position to the specified vector, provided in pixels and "
@@ -56957,6 +59405,26 @@ msgstr ""
msgid "An input event type for actions."
msgstr "动作的输入事件类型。"
+msgid ""
+"Contains a generic action which can be targeted from several types of inputs. "
+"Actions and their events can be set in the [b]Input Map[/b] tab in [b]Project "
+"> Project Settings[/b], or with the [InputMap] class.\n"
+"[b]Note:[/b] Unlike the other [InputEvent] subclasses which map to unique "
+"physical events, this virtual one is not emitted by the engine. This class is "
+"useful to emit actions manually with [method Input.parse_input_event], which "
+"are then received in [method Node._input]. To check if a physical event "
+"matches an action from the Input Map, use [method InputEvent.is_action] and "
+"[method InputEvent.is_action_pressed]."
+msgstr ""
+"包含一个通用动作,该动作可以被多种类型的输入作为目标。动作及其事件可以在[b]项"
+"目 > 项目设置[/b]的[b]输入映射[/b]选项卡中设置,也可以使用 [InputMap] 类设"
+"置。\n"
+"[b]注意:[/b]与映射到唯一物理事件的其他 [InputEvent] 子类不同,这个虚拟事件不"
+"是由引擎发出的。这个类可以用来使用 [method Input.parse_input_event] 手动发出动"
+"作,这样就能够在 [method Node._input] 中接收到这些动作。要检查物理事件是否"
+"与“输入映射”中的动作相匹配,请使用 [method InputEvent.is_action] 和 [method "
+"InputEvent.is_action_pressed]。"
+
msgid "Using InputEvent: Actions"
msgstr "使用 InputEvent:动作"
@@ -56998,6 +59466,14 @@ msgid "Abstract base class for touch gestures."
msgstr "触摸手势的抽象基类。"
msgid ""
+"InputEventGestures are sent when a user performs a supported gesture on a "
+"touch screen. Gestures can't be emulated using mouse, because they typically "
+"require multi-touch."
+msgstr ""
+"用户在触摸屏上执行支持的手势时会发送 InputEventGesture。无法用鼠标模拟手势,因"
+"为手势一般都要求多点触控。"
+
+msgid ""
"The local gesture position relative to the [Viewport]. If used in [method "
"Control._gui_input], the position is relative to the current [Control] that "
"received this gesture."
@@ -58563,7 +61039,7 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"返回垂直滚动条。\n"
-"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果您希望隐"
+"[b]警告:[/b]这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果你希望隐"
"藏它或其任何子项,请使用它们的 [member CanvasItem.visible] 属性。"
msgid "Returns [code]true[/code] if one or more items are selected."
@@ -58813,7 +61289,7 @@ msgstr "选择项目时使用的文本颜色 [Color]。"
msgid ""
"[Color] of the guideline. The guideline is a line drawn between each row of "
"items."
-msgstr "指导线的颜色[Color]。指导线是在每行项目之间画的一条线。"
+msgstr "参考线的颜色 [Color]。参考线是在每行项目之间画的一条线。"
msgid "The horizontal spacing between items."
msgstr "项目之间的水平间距。"
@@ -58857,7 +61333,7 @@ msgstr "当该 [ItemList] 未获得焦点时,用作光标的样式盒 [StyleBo
msgid ""
"The focused style for the [ItemList], drawn on top of the background, but "
"below everything else."
-msgstr "该 [ItemList]的焦点样式,绘制在背景之上,但低于其他东西。"
+msgstr "该 [ItemList] 的焦点样式,绘制在背景之上,但低于其他东西。"
msgid "[StyleBox] for the hovered, but not selected items."
msgstr "悬停但未被选中的项目的 [StyleBox]。"
@@ -59208,7 +61684,7 @@ msgstr ""
"[method stringify] 用于将任何数据类型转换为 JSON 字符串。\n"
"[method parse] 用于将任何现有的 JSON 数据转换为可以在 Godot 中使用的 "
"[Variant]。如果解析成功,使用 [member data] 检索 [Variant],并使用 "
-"[code]typeof[/code] 检查 Variant 的类型是否符合您的预期。JSON 对象被转换为 "
+"[code]typeof[/code] 检查 Variant 的类型是否符合你的预期。JSON 对象被转换为 "
"[Dictionary],但 JSON 数据可用于存储 [Array]、数字、[String],甚至只是一个布尔"
"值。\n"
"[b]示例[/b]\n"
@@ -59230,7 +61706,7 @@ msgstr ""
" print(\"JSON Parse Error: \", json.get_error_message(), \" in \", "
"json_string, \" at line \", json.get_error_line())\n"
"[/codeblock]\n"
-"或者,您可以使用静态 [method parse_string] 方法解析字符串,但它不允许处理错"
+"或者,你可以使用静态 [method parse_string] 方法解析字符串,但它不允许处理错"
"误。\n"
"[codeblock]\n"
"var data = JSON.parse_string(json_string) # 如果解析失败则返回 null。\n"
@@ -60713,8 +63189,8 @@ msgid ""
"(shadows not connecting to their casters). Real-time [Light3D] shadows are "
"not affected by this [member bias] property."
msgstr ""
-"计算阴影时使用的偏差。增加 [member bias] 可以修复生成的烘焙光照贴图上的阴影粉"
-"刺,但会引入阴影悬浮(阴影未连接到其障碍物)。实时 [Light3D] 阴影不受该 "
+"计算阴影时使用的偏置。增加 [member bias] 可以修复生成的烘焙光照贴图上的阴影失"
+"真,但会引入阴影悬浮(阴影未连接到其障碍物)。实时 [Light3D] 阴影不受该 "
"[member bias] 属性的影响。"
msgid ""
@@ -61030,7 +63506,7 @@ msgid ""
msgstr ""
"如果 [param uses_spherical_harmonics] 为 [code]true[/code],则告诉引擎将光照贴"
"图数据视为使用了定向信息烘焙的。\n"
-"[b]注意:[/b] 在已烘焙的光照贴图上更改此值不会导致再次烘焙它们。这意味着在再次"
+"[b]注意:[/b]在已烘焙的光照贴图上更改此值不会导致再次烘焙它们。这意味着在再次"
"烘焙光照贴图之前,材质外观将看起来不正确,在这种情况下,此处设置的值将被丢弃,"
"因为整个 [LightmapGIData] 资源被光照贴图器替换。"
@@ -61068,7 +63544,7 @@ msgstr ""
"[LightmapGI] 一起使用。在大多数专用 GPU 上,它可以比大多数基于 CPU 的光照贴图"
"更快地烘焙光照贴图。LightmapperRD 使用计算着色器来烘焙光照贴图,因此它不需要安"
"装 CUDA 或 OpenCL 库即可使用。\n"
-"[b]注意:[/b] 仅在使用 Vulkan 后端(Forward+ 或移动),而不是 OpenGL 时可用。"
+"[b]注意:[/b]仅在使用 Vulkan 后端(Forward+ 或移动),而不是 OpenGL 时可用。"
msgid ""
"Represents a single manually placed probe for dynamic object lighting with "
@@ -61088,7 +63564,7 @@ msgstr ""
"照明。\n"
"通常,通过将 [member LightmapGI.generate_probes_subdiv] 设置为 [constant "
"LightmapGI.GENERATE_PROBES_DISABLED] 以外的值,来自动放置 [LightmapGI] 探针。"
-"通过在烘焙光照贴图之前创建 [LightmapProbe] 节点,您可以在特定区域,添加更多探"
+"通过在烘焙光照贴图之前创建 [LightmapProbe] 节点,你可以在特定区域,添加更多探"
"针以获得更多细节,或者禁用自动生成、并仅依赖手动放置的探针。"
msgid "Occludes light cast by a Light2D, casting shadows."
@@ -61398,7 +63874,7 @@ msgid ""
msgstr ""
"返回该 [LineEdit] 的 [PopupMenu]。默认情况下,右键点击 [LineEdit] 会显示该菜"
"单。\n"
-"可以添加自定义菜单项或移除标准菜单项。确保您的 ID 不与标准 ID 冲突(请参阅 "
+"可以添加自定义菜单项或移除标准菜单项。确保你的 ID 不与标准 ID 冲突(请参阅 "
"[enum MenuItems])。例如:\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -63142,6 +65618,13 @@ msgstr "用于 [Mesh] 凸分解操作的参数。"
msgid "If enabled uses approximation for computing convex hulls."
msgstr "如果启用,则在计算凸包时使用近似计算。"
+msgid ""
+"Controls the precision of the convex-hull generation process during the "
+"clipping plane selection stage. Ranges from [code]1[/code] to [code]16[/code]."
+msgstr ""
+"控制凸包生成过程的精度,这个过程发生在选择裁剪平面的阶段。范围从 [code]1[/"
+"code] 到 [code]16[/code]。"
+
msgid "Maximum concavity. Ranges from [code]0.0[/code] to [code]1.0[/code]."
msgstr "最大凹度。范围从 [code]0.0[/code] 到 [code]1.0[/code]。"
@@ -63160,6 +65643,44 @@ msgid ""
msgstr ""
"控制生成凸包的自适应采样。范围从 [code]0.0[/code] 到 [code]0.01[/code] 。"
+msgid "Mode for the approximate convex decomposition."
+msgstr "近似凸分解的模式。"
+
+msgid "If enabled normalizes the mesh before applying the convex decomposition."
+msgstr "如果启用,则会在应用凸分解前将网格归一化。"
+
+msgid ""
+"Controls the granularity of the search for the \"best\" clipping plane. "
+"Ranges from [code]1[/code] to [code]16[/code]."
+msgstr ""
+"控制搜索“最佳”裁剪平面的颗粒度。范围从 [code]1[/code] 到 [code]16[/code]。"
+
+msgid ""
+"If enabled projects output convex hull vertices onto original source mesh to "
+"increase floating point accuracy of the results."
+msgstr "如果启用,则项目会将凸包顶点输出到来源网格之上,提高结果的浮点数精度。"
+
+msgid "Maximum number of voxels generated during the voxelization stage."
+msgstr "体素化阶段生成的最大体素数量。"
+
+msgid ""
+"Controls the bias toward clipping along revolution axes. Ranges from "
+"[code]0.0[/code] to [code]1.0[/code]."
+msgstr ""
+"控制对沿回转轴裁剪的偏置。范围从 [code]0.0[/code] 到 [code]1.0[/code] 。"
+
+msgid ""
+"Controls the bias toward clipping along symmetry planes. Ranges from "
+"[code]0.0[/code] to [code]1.0[/code]."
+msgstr ""
+"控制对沿对称平面裁剪的偏置。范围从 [code]0.0[/code] 到 [code]1.0[/code] 。"
+
+msgid "Constant for voxel-based approximate convex decomposition."
+msgstr "常量,表示基于体素的近似凸分解。"
+
+msgid "Constant for tetrahedron-based approximate convex decomposition."
+msgstr "常量,表示基于四面体的近似凸分解。"
+
msgid "Helper tool to access and edit [Mesh] data."
msgstr "用于访问和编辑 [Mesh] 数据的辅助工具。"
@@ -63480,8 +66001,18 @@ msgid ""
"This helper creates a [MeshInstance3D] child node with gizmos at every vertex "
"calculated from the mesh geometry. It's mainly used for testing."
msgstr ""
-"该助手创建一个 [MeshInstance3D] 子节点,该子节点在每个顶点处都有小工具,这些顶"
-"点是根据该网格几何体计算出的。它主要用于测试。"
+"创建 [MeshInstance3D] 子节点的辅助函数,会根据网格几何体计算出各个顶点的小工"
+"具。主要用于测试。"
+
+msgid ""
+"This helper creates a [StaticBody3D] child node with multiple "
+"[ConvexPolygonShape3D] collision shapes calculated from the mesh geometry via "
+"convex decomposition. The convex decomposition operation can be controlled "
+"with parameters from the optional [param settings]."
+msgstr ""
+"创建 [StaticBody3D] 子节点的辅助函数,会根据网格几何体使用凸分解计算出多个 "
+"[ConvexPolygonShape3D] 碰撞形状。凸分解操作可以通过可选的 [param settings] 参"
+"数控制。"
msgid ""
"This helper creates a [StaticBody3D] child node with a "
@@ -64912,8 +67443,8 @@ msgid ""
"Called to check if the server can act as a relay in the current "
"configuration. See [method MultiplayerPeer.is_server_relay_supported]."
msgstr ""
-"检查 [MultiplayerPeer] 在当前配置中是否能够作为中继时调用。见 [method "
-"MultiplayerAPI.is_server_relay_supported]。"
+"检查服务器在当前配置中是否能够作为中继时调用。见 [method MultiplayerPeer."
+"is_server_relay_supported]。"
msgid ""
"Called when the [MultiplayerAPI] is polled. See [method MultiplayerAPI.poll]."
@@ -65059,6 +67590,37 @@ msgid ""
msgstr "将属性从多人游戏权威同步到远程对等体。"
msgid ""
+"By default, [MultiplayerSynchronizer] synchronizes configured properties to "
+"all peers.\n"
+"Visibility can be handled directly with [method set_visibility_for] or as-"
+"needed with [method add_visibility_filter] and [method update_visibility].\n"
+"[MultiplayerSpawner]s will handle nodes according to visibility of "
+"synchronizers as long as the node at [member root_path] was spawned by one.\n"
+"Internally, [MultiplayerSynchronizer] uses [method MultiplayerAPI."
+"object_configuration_add] to notify synchronization start passing the [Node] "
+"at [member root_path] as the [code]object[/code] and itself as the "
+"[code]configuration[/code], and uses [method MultiplayerAPI."
+"object_configuration_remove] to notify synchronization end in a similar way.\n"
+"[b]Note:[/b] Synchronization is not supported for [Object] type properties, "
+"like [Resource]. Properties that are unique to each peer, like the instance "
+"IDs of [Object]s (see [method Object.get_instance_id]) or [RID]s, will also "
+"not work in synchronization."
+msgstr ""
+"默认情况下,[MultiplayerSynchronizer] 会将配置的属性同步到所有对等体。\n"
+"可以使用 [method set_visibility_for] 直接处理可见性,也可以通过 [method "
+"add_visibility_filter] 和 [method update_visibility] 在需要时进行处理。\n"
+"[MultiplayerSpawner] 会根据同步器的可见性来处理节点,只要 [member root_path] "
+"的节点是出生出来的。\n"
+"内部而言,[MultiplayerSynchronizer] 使用 [method MultiplayerAPI."
+"object_configuration_add] 来通知同步开始,将位于 [member root_path] 的 [Node] "
+"作为 [code]object[/code] 传入、将自己作为 [code]configuration[/code] 传入。使"
+"用 [method MultiplayerAPI.object_configuration_remove] 通知同步结束的方法相"
+"同。\n"
+"[b]注意:[/b]不支持对 [Resource] 等 [Object] 类型属性进行同步。对等体的唯一属"
+"性也无法进行同步,例如 [Object] 的实例 ID(见 [method Object."
+"get_instance_id])或 [RID]。"
+
+msgid ""
"Adds a peer visibility filter for this synchronizer.\n"
"[param filter] should take a peer ID [int] and return a [bool]."
msgstr ""
@@ -65084,8 +67646,15 @@ msgid ""
"If [param for_peer] is [code]0[/code] (the default), all peers' visibilties "
"are updated."
msgstr ""
-"根据可见性过滤器更新 [param peer] 的可见性。如果 [param peer] 为 [code]0[/"
-"code](默认值),则更新所有对等体的可见性。"
+"根据可见性过滤器更新 [param for_peer] 的可见性。如果 [param for_peer] 为 "
+"[code]0[/code](默认值),则更新所有对等体的可见性。"
+
+msgid ""
+"Time interval between delta synchronizations. When set to [code]0.0[/code] "
+"(the default), delta synchronizations happen every network process frame."
+msgstr ""
+"两次增量同步之间的时间间隔。当设置为 [code]0.0[/code](默认值)时,每个网络处"
+"理帧都会发生增量同步。"
msgid ""
"Whether synchronization should be visible to all peers by default. See "
@@ -65099,6 +67668,13 @@ msgid "Resource containing which properties to synchronize."
msgstr "包含要同步的属性的资源。"
msgid ""
+"Time interval between synchronizations. When set to [code]0.0[/code] (the "
+"default), synchronizations happen every network process frame."
+msgstr ""
+"两次同步之间的时间间隔。当设置为 [code]0.0[/code](默认值)时,每个网络处理帧"
+"都会发生同步。"
+
+msgid ""
"Node path that replicated properties are relative to.\n"
"If [member root_path] was spawned by a [MultiplayerSpawner], the node will be "
"also be spawned and despawned based on this synchronizer visibility options."
@@ -65291,6 +67867,14 @@ msgid ""
msgstr "返回该代理目前正在使用的路径所对应的路径查询结果。"
msgid ""
+"Returns the reachable final position of the current navigation path in global "
+"coordinates. This can change if the navigation path is altered in any way. "
+"Because of this, it would be best to check this each frame."
+msgstr ""
+"返回当前导航路径中可到达的最终位置的全局坐标。如果导航路径由于任何原因发生改"
+"变,这个位置也可能发生变化。因此,最好每一帧都检查一下。"
+
+msgid ""
"Returns whether or not the specified layer of the [member navigation_layers] "
"bitmask is enabled, given a [param layer_number] between 1 and 32."
msgstr ""
@@ -65383,6 +67967,46 @@ msgstr ""
"将防撞仿真的内部速度替换为 [param velocity]。代理传送到新的位置之后,应该在同"
"一帧里使用这个函数。如果频繁调用这个函数,可能会让代理卡住。"
+msgid ""
+"If [code]true[/code] the agent is registered for an RVO avoidance callback on "
+"the [NavigationServer2D]. When [member velocity] is used and the processing "
+"is completed a [code]safe_velocity[/code] Vector2 is received with a signal "
+"connection to [signal velocity_computed]. Avoidance processing with many "
+"registered agents has a significant performance cost and should only be "
+"enabled on agents that currently require it."
+msgstr ""
+"如果为 [code]true[/code],该代理会在 [NavigationServer2D] 上注册 RVO 避障回"
+"调。当使用 [member velocity] 并且处理完成时,会通过与 [signal "
+"velocity_computed] 的信号连接接收到安全速度 [code]safe_velocity[/code] "
+"Vector2。注册的代理过多会为避障处理带来显著的性能开销,应该仅在需要它的代理上"
+"启用。"
+
+msgid ""
+"A bitfield determining the avoidance layers for this NavigationAgent. Other "
+"agents with a matching bit on the [member avoidance_mask] will avoid this "
+"agent."
+msgstr ""
+"决定该 NavigationAgent 避障层的位域。[member avoidance_mask] 中该位域存在交集"
+"的其他代理会躲避这个代理。"
+
+msgid ""
+"A bitfield determining what other avoidance agents and obstacles this "
+"NavigationAgent will avoid when a bit matches at least one of their [member "
+"avoidance_layers]."
+msgstr ""
+"决定该 NavigationAgent 会躲避那些代理和障碍物的位域,需要该位域与对方的 "
+"[member avoidance_layers] 存在至少一个共同的比特位。"
+
+msgid ""
+"The agent does not adjust the velocity for other agents that would match the "
+"[member avoidance_mask] but have a lower [member avoidance_priority]. This in "
+"turn makes the other agents with lower priority adjust their velocities even "
+"more to avoid collision with this agent."
+msgstr ""
+"该代理不会针对 [member avoidance_mask] 存在匹配但 [member avoidance_priority] "
+"更低的代理调整速度。相应地,优先级更低的代理则会对其速度进行更大的调整,从而避"
+"免与这个代理发生碰撞。"
+
msgid "If [code]true[/code] shows debug visuals for this agent."
msgstr "如果为 [code]true[/code],则为该代理显示调试内容。"
@@ -65420,10 +68044,34 @@ msgstr "该代理所需考虑的最大邻居数。"
msgid "The maximum speed that an agent can move."
msgstr "代理所能达到的最大移动速度。"
+msgid ""
+"A bitfield determining which navigation layers of navigation regions this "
+"agent will use to calculate a path. Changing it during runtime will clear the "
+"current navigation path and generate a new one, according to the new "
+"navigation layers."
+msgstr ""
+"决定该代理计算路径所使用的导航地区导航层的位域。运行时进行修改会清空当前的导航"
+"路径,并根据新的导航层生成一条新的路径。"
+
msgid "The distance to search for other agents."
msgstr "搜索其他代理的距离。"
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"allows agents to not have to hit a path point on the path exactly, but only "
+"to reach its general area. If this value is set too high, the NavigationAgent "
+"will skip points on the path, which can lead too leaving the navigation mesh. "
+"If this value is set too low, the NavigationAgent will be stuck in a repath "
+"loop because it will constantly overshoot or undershoot the distance to the "
+"next point on each physics frame update."
+msgstr ""
+"距离阈值,用于确定是否已到达某个路径点。使用这个值,代理就不必精确地到达某个路"
+"径点,到达该路径点的大致区域内即可。如果这个值设得太大,该 NavigationAgent 会"
+"跳过路径上的点,可能导致其离开该导航网格。如果这个值设得太小,该 "
+"NavigationAgent 会陷入重新寻路的死循环,因为它在每次物理帧更新后都会超过或者到"
+"达不了下一个点。"
+
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final position. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
@@ -65458,6 +68106,59 @@ msgstr ""
"导航地图。"
msgid ""
+"The distance threshold before the final target point is considered to be "
+"reached. This allows agents to not have to hit the point of the final target "
+"exactly, but only to reach its general area. If this value is set too low, "
+"the NavigationAgent will be stuck in a repath loop because it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
+msgstr ""
+"距离阈值,用于确定是否已到达最终目标点。使用这个值,代理就不必精确地到达最终目"
+"标点,到达目标点的大致区域内即可。如果这个值设得太小,该 NavigationAgent 会陷"
+"入重新寻路的死循环,因为它在每次物理帧更新后都会超过或者到达不了最终目标点。"
+
+msgid ""
+"If set a new navigation path from the current agent position to the [member "
+"target_position] is requested from the NavigationServer."
+msgstr ""
+"设置后,会向 NavigationServer 请求一条新的从当前代理位置到 [member "
+"target_position] 的导航路径。"
+
+msgid ""
+"The minimal amount of time for which this agent's velocities, that are "
+"computed with the collision avoidance algorithm, are safe with respect to "
+"other agents. The larger the number, the sooner the agent will respond to "
+"other agents, but less freedom in choosing its velocities. A too high value "
+"will slow down agents movement considerably. Must be positive."
+msgstr ""
+"考虑其他代理的前提下,该代理的速度的最短安全时间,这个速度是通过碰撞躲避算法计"
+"算的。数值越大,代理响应其他代理的速度就越快,但选择速度的自由度也就越小。太高"
+"的取值会大大降低代理的移动速度。必须为正数。"
+
+msgid ""
+"The minimal amount of time for which this agent's velocities, that are "
+"computed with the collision avoidance algorithm, are safe with respect to "
+"static avoidance obstacles. The larger the number, the sooner the agent will "
+"respond to static avoidance obstacles, but less freedom in choosing its "
+"velocities. A too high value will slow down agents movement considerably. "
+"Must be positive."
+msgstr ""
+"考虑静态避障障碍物的前提下,该代理的速度的最短安全时间,这个速度是通过碰撞躲避"
+"算法计算的。数值越大,代理响应静态避障障碍物的速度就越快,但选择速度的自由度也"
+"就越小。太高的取值会大大降低代理的移动速度。必须为正数。"
+
+msgid ""
+"Sets the new wanted velocity for the agent. The avoidance simulation will try "
+"to fulfill this velocity if possible but will modify it to avoid collision "
+"with other agents and obstacles. When an agent is teleported to a new "
+"position, use [method set_velocity_forced] as well to reset the internal "
+"simulation velocity."
+msgstr ""
+"为代理设置新的需求速度。避障仿真会尽可能尝试满足这个速度,但为了躲避与其他代理"
+"和障碍物的碰撞也会对它进行修改。将代理传送至新的位置时,请使用 [method "
+"set_velocity_forced] 重置内部仿真速度。"
+
+msgid ""
"Notifies when a navigation link has been reached.\n"
"The details dictionary may contain the following keys depending on the value "
"of [member path_metadata_flags]:\n"
@@ -65496,6 +68197,14 @@ msgid "Notifies when the player-defined [member target_position] is reached."
msgstr "抵达玩家定义的目标位置 [member target_position] 时发出通知。"
msgid ""
+"Notifies when the collision avoidance velocity is calculated. Emitted when "
+"[member velocity] is set. Only emitted when [member avoidance_enabled] is "
+"true."
+msgstr ""
+"计算出避障速度时发出通知。设置了 [member velocity] 才会发出。仅在 [member "
+"avoidance_enabled] 为 true 时发出。"
+
+msgid ""
"Notifies when a waypoint along the path has been reached.\n"
"The details dictionary may contain the following keys depending on the value "
"of [member path_metadata_flags]:\n"
@@ -65543,10 +68252,109 @@ msgid ""
"[PackedVector3Array]."
msgstr "返回该代理当前位于导航路径 [PackedVector3Array] 中的哪一个索引。"
+msgid ""
+"Returns the reachable final position of the current navigation path in global "
+"coordinates. This position can change if the navigation path is altered in "
+"any way. Because of this, it would be best to check this each frame."
+msgstr ""
+"返回当前导航路径上可到达的最终位置的全局坐标。如果导航路径由于任何原因发生改"
+"变,这个位置也可能发生变化。因此,最好每一帧都检查一下。"
+
msgid "Returns the [RID] of this agent on the [NavigationServer3D]."
msgstr "返回这个代理在 [NavigationServer3D] 上的 [RID]。"
msgid ""
+"If [code]true[/code] the agent is registered for an RVO avoidance callback on "
+"the [NavigationServer3D]. When [member velocity] is set and the processing is "
+"completed a [code]safe_velocity[/code] Vector3 is received with a signal "
+"connection to [signal velocity_computed]. Avoidance processing with many "
+"registered agents has a significant performance cost and should only be "
+"enabled on agents that currently require it."
+msgstr ""
+"如果为 [code]true[/code],该代理会在 [NavigationServer3D] 上注册 RVO 避障回"
+"调。当设置 [member velocity] 并且处理完成时,会通过与 [signal "
+"velocity_computed] 的信号连接接收到安全速度 [code]safe_velocity[/code] "
+"Vector3。注册的代理过多会为避障处理带来显著的性能开销,应该仅在需要它的代理上"
+"启用。"
+
+msgid ""
+"A bitfield determining the avoidance layers for this NavigationAgent. Other "
+"agent's with a matching bit on the [member avoidance_mask] will avoid this "
+"agent."
+msgstr ""
+"决定该 NavigationAgent 避障层的位域。[member avoidance_mask] 中该位域存在交集"
+"的其他代理会躲避这个代理。"
+
+msgid ""
+"The height of the avoidance agent. Agents will ignore other agents or "
+"obstacles that are above or below their current position + height in 2D "
+"avoidance. Does nothing in 3D avoidance which uses radius spheres alone."
+msgstr ""
+"避障代理的高度。2D 避障时,代理会忽略位于其上方或低于当前位置 + 高度的其他代理"
+"或障碍物。3D 避障时只使用半径球体,该设置无效。"
+
+msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"allows agents to not have to hit a path point on the path exactly, but only "
+"to reach its general area. If this value is set too high, the NavigationAgent "
+"will skip points on the path, which can lead to leaving the navigation mesh. "
+"If this value is set too low, the NavigationAgent will be stuck in a repath "
+"loop because it will constantly overshoot or undershoot the distance to the "
+"next point on each physics frame update."
+msgstr ""
+"距离阈值,用于确定是否已到达某个路径点。使用这个值,代理就不必精确地到达某个路"
+"径点,到达该路径点的大致区域内即可。如果这个值设得太大,该 NavigationAgent 会"
+"跳过路径上的点,可能导致其离开该导航网格。如果这个值设得太小,该 "
+"NavigationAgent 会陷入重新寻路的死循环,因为它在每次物理帧更新后都会超过或者到"
+"达不了下一个点。"
+
+msgid ""
+"The height offset is subtracted from the y-axis value of any vector path "
+"position for this NavigationAgent. The NavigationAgent height offset does not "
+"change or influence the navigation mesh or pathfinding query result. "
+"Additional navigation maps that use regions with navigation meshes that the "
+"developer baked with appropriate agent radius or height values are required "
+"to support different-sized agents."
+msgstr ""
+"这个 NavigationAgent 的任何向量路径位置的 Y 坐标值都会减去这个高度偏移量。"
+"NavigationAgent 的高度偏移量既不会改变也不会影响导航网格和寻路结果。要支持不同"
+"大小的代理,需要提供其他使用了带有导航网格区块的导航地图,并且开发者使用合适的"
+"代理半径或高度对其进行了烘焙。"
+
+msgid ""
+"The distance threshold before the final target point is considered to be "
+"reached. This allows agents to not have to hit the point of the final target "
+"exactly, but only to reach its general. If this value is set too low, the "
+"NavigationAgent will be stuck in a repath loop because it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
+msgstr ""
+"距离阈值,用于确定是否已到达最终目标点。使用这个值,代理就不必精确地到达最终目"
+"标点,到达目标点的大致区域内即可。如果这个值设得太小,该 NavigationAgent 会陷"
+"入重新寻路的死循环,因为它在每次物理帧更新后都会超过或者到达不了最终目标点。"
+
+msgid ""
+"If [code]true[/code], the agent calculates avoidance velocities in 3D "
+"omnidirectionally, e.g. for games that take place in air, underwater or "
+"space. Agents using 3D avoidance only avoid other agents using 3D avoidance, "
+"and react to radius-based avoidance obstacles. They ignore any vertex-based "
+"obstacles.\n"
+"If [code]false[/code], the agent calculates avoidance velocities in 2D along "
+"the x and z-axes, ignoring the y-axis. Agents using 2D avoidance only avoid "
+"other agents using 2D avoidance, and react to radius-based avoidance "
+"obstacles or vertex-based avoidance obstacles. Other agents using 2D "
+"avoidance that are below or above their current position including [member "
+"height] are ignored."
+msgstr ""
+"如果为 [code]true[/code],则代理会在 3D 空间中计算全向的避障速度,例如发生在空"
+"中、水下、太空中的游戏。使用 3D 避障的代理只会躲避其他使用 3D 避障的代理、对基"
+"于半径的障碍物作出反应。会忽略基于顶点的障碍物。\n"
+"如果为 [code]false[/code],则代理会在 2D 空间中沿 X 和 Z 轴计算避障速度,忽略 "
+"Y 轴。使用 2D 避障的代理只会躲避其他使用 2D 避障的代理、对基于半径和基于顶点的"
+"障碍物作出反应。其他使用 2D 避障的代理如果在该代理之下,或者高于该代理当前位置"
+"与 [member height] 之和则会被忽略。"
+
+msgid ""
"Notifies when a navigation link has been reached.\n"
"The details dictionary may contain the following keys depending on the value "
"of [member path_metadata_flags]:\n"
@@ -65579,7 +68387,19 @@ msgid ""
"A link between two positions on [NavigationRegion2D]s that agents can be "
"routed through."
msgstr ""
-"连接两个位于 [NavigationRegion2D] 上的位置的链接,导航时代理能够通过这个链接。"
+"连接两个位于 [NavigationRegion2D] 上的位置的链接,导航时能够让代理走这个链接。"
+
+msgid ""
+"A link between two positions on [NavigationRegion2D]s that agents can be "
+"routed through. These positions can be on the same [NavigationRegion2D] or on "
+"two different ones. Links are useful to express navigation methods other than "
+"traveling along the surface of the navigation polygon, such as ziplines, "
+"teleporters, or gaps that can be jumped across."
+msgstr ""
+"连接两个位于 [NavigationRegion2D] 上的位置的链接,导航时能够让代理走这个链接。"
+"这两个位置可以在同一个 [NavigationRegion2D] 上,也可以是在两个不同的区块上。链"
+"接可以用来表达沿着导航多边形表面行进以外的导航方法,例如滑锁、传送、跳过沟壑等"
+"等。"
msgid "Using NavigationLinks"
msgstr "使用 NavigationLink"
@@ -65669,7 +68489,19 @@ msgid ""
"A link between two positions on [NavigationRegion3D]s that agents can be "
"routed through."
msgstr ""
-"连接两个位于 [NavigationRegion3D] 上的位置的链接,导航时代理能够通过这个链接。"
+"连接两个位于 [NavigationRegion3D] 上的位置的链接,导航时能够让代理走这个链接。"
+
+msgid ""
+"A link between two positions on [NavigationRegion3D]s that agents can be "
+"routed through. These positions can be on the same [NavigationRegion3D] or on "
+"two different ones. Links are useful to express navigation methods other than "
+"traveling along the surface of the navigation mesh, such as ziplines, "
+"teleporters, or gaps that can be jumped across."
+msgstr ""
+"连接两个位于 [NavigationRegion3D] 上的位置的链接,导航时能够让代理走这个链接。"
+"这两个位置可以在同一个 [NavigationRegion3D] 上,也可以是在两个不同的区块上。链"
+"接可以用来表达沿着导航网格表面行进以外的导航方法,例如滑锁、传送、跳过沟壑等"
+"等。"
msgid ""
"Whether this link is currently active. If [code]false[/code], [method "
@@ -65833,6 +68665,11 @@ msgid ""
msgstr "细节网格表面应偏离高度场的最大距离,以单元格为单位。"
msgid ""
+"The maximum distance a simplified contour's border edges should deviate the "
+"original raw contour."
+msgstr "简化轮廓的边界边缘偏离原始轮廓的最大距离。"
+
+msgid ""
"The maximum allowed length for contour edges along the border of the mesh.\n"
"[b]Note:[/b] While baking, this value will be rounded up to the nearest "
"multiple of [member cell_size]."
@@ -65932,12 +68769,12 @@ msgid ""
"Watershed partitioning. Generally the best choice if you precompute the "
"navigation mesh, use this if you have large open areas."
msgstr ""
-"分水岭分区。如果您预先计算导航网格,通常是最佳选择,如果您有大的开放区域,请使"
+"分水岭分区。如果你预先计算导航网格,通常是最佳选择,如果你有大的开放区域,请使"
"用它。"
msgid ""
"Monotone partitioning. Use this if you want fast navigation mesh generation."
-msgstr "单调分区。如果您想要快速生成导航网格,请使用此选项。"
+msgstr "单调分区。如果你想要快速生成导航网格,请使用此选项。"
msgid ""
"Layer partitioning. Good choice to use for tiled navigation mesh with medium "
@@ -66086,9 +68923,68 @@ msgid ""
msgstr "从提供的 [param navigation_mesh] 资源中移除所有多边形和顶点。"
msgid ""
+"Parses the [SceneTree] for source geometry according to the properties of "
+"[param navigation_mesh]. Updates the provided [param source_geometry_data] "
+"resource with the resulting data. The resource can then be used to bake a "
+"navigation mesh with [method bake_from_source_geometry_data]. After the "
+"process is finished the optional [param callback] will be called.\n"
+"[b]Note:[/b] This function needs to run on the main thread or with a deferred "
+"call as the SceneTree is not thread-safe.\n"
+"[b]Performance:[/b] While convenient, reading data arrays from [Mesh] "
+"resources can affect the frame rate negatively. The data needs to be received "
+"from the GPU, stalling the [RenderingServer] in the process. For performance "
+"prefer the use of e.g. collision shapes or creating the data arrays entirely "
+"in code."
+msgstr ""
+"根据 [param navigation_mesh] 的属性解析 [SceneTree] 中的源几何体。会使用解析的"
+"结果对提供的 [param source_geometry_data] 资源进行更新。后续可以在使用 "
+"[method bake_from_source_geometry_data] 烘焙导航网格时使用该资源。解析过程完成"
+"后,会调用可选的 [param callback]。\n"
+"[b]注意:[/b]因为 SceneTree 并不是线程安全的,所以这个函数需要在主线程执行或使"
+"用延迟调用。\n"
+"[b]注意:[/b]从 [Mesh] 资源读取数据数组虽然很方便,但会对帧率造成负面影响。这"
+"些数据需要从 GPU 获取,卡住正在处理的 [RenderingServer]。出于性能考量,请优先"
+"使用碰撞形状或在代码中创建完整的数据数组等方法。"
+
+msgid ""
"Container for parsed source geometry data used in navigation mesh baking."
msgstr "存放解析所得的源几何体数据的容器,用于导航网格的烘焙。"
+msgid ""
+"Adds an array of vertex positions to the geometry data for navigation mesh "
+"baking to form triangulated faces. For each face the array must have three "
+"vertex positions in clockwise winding order. Since [NavigationMesh] resource "
+"have no transform all vertex positions need to be offset by the node's "
+"transform using the [code]xform[/code] parameter."
+msgstr ""
+"向用于导航网格烘焙的几何体数据中添加顶点位置数组,形成三角形面。每个面必须在数"
+"组中有三个顶点位置,使用顺时针缠绕顺序。因为 [NavigationMesh] 资源本身没有变"
+"换,所有顶点位置都需要使用 [code]xform[/code] 参数使用节点的变换进行偏移。"
+
+msgid ""
+"Adds the geometry data of a [Mesh] resource to the navigation mesh baking "
+"data. The mesh must have valid triangulated mesh data to be considered. Since "
+"[NavigationMesh] resource have no transform all vertex positions need to be "
+"offset by the node's transform using the [code]xform[/code] parameter."
+msgstr ""
+"向导航网格烘焙数据中添加 [Mesh] 资源的几何体数据。网格中必须存在有效的三角形网"
+"格数据才会被使用。因为 [NavigationMesh] 资源本身没有变换,所有顶点位置都需要使"
+"用 [code]xform[/code] 参数使用节点的变换进行偏移。"
+
+msgid ""
+"Adds an [Array] the size of [constant Mesh.ARRAY_MAX] and with vertices at "
+"index [constant Mesh.ARRAY_VERTEX] and indices at index [constant Mesh."
+"ARRAY_INDEX] to the navigation mesh baking data. The array must have valid "
+"triangulated mesh data to be considered. Since [NavigationMesh] resource have "
+"no transform all vertex positions need to be offset by the node's transform "
+"using the [code]xform[/code] parameter."
+msgstr ""
+"向导航网格烘焙数据中添加一个 [Array],大小为 [constant Mesh.ARRAY_MAX],顶点数"
+"据位于索引 [constant Mesh.ARRAY_VERTEX],索引数据位于索引 [constant Mesh."
+"ARRAY_INDEX]。数组中必须存在有效的三角形网格数据才会被使用。因为 "
+"[NavigationMesh] 资源本身没有变换,所有顶点位置都需要使用 [code]xform[/code] "
+"参数使用节点的变换进行偏移。"
+
msgid "Clears the internal data."
msgstr "清除内部数据。"
@@ -66125,10 +69021,52 @@ msgid ""
msgstr ""
"用于导航的 2D 障碍物,能够将启用了避障处理的代理约束在某个区域之外或之内。"
+msgid ""
+"2D Obstacle used in navigation to constrain avoidance controlled agents "
+"outside or inside an area. The obstacle needs a navigation map and outline "
+"vertices defined to work correctly.\n"
+"If the obstacle's vertices are winded in clockwise order, avoidance agents "
+"will be pushed in by the obstacle, otherwise, avoidance agents will be pushed "
+"out. Outlines must not cross or overlap.\n"
+"Obstacles are [b]not[/b] a replacement for a (re)baked navigation mesh. "
+"Obstacles [b]don't[/b] change the resulting path from the pathfinding, "
+"obstacles only affect the navigation avoidance agent movement by altering the "
+"suggested velocity of the avoidance agent.\n"
+"Obstacles using vertices can warp to a new position but should not moved "
+"every frame as each move requires a rebuild of the avoidance map."
+msgstr ""
+"导航中使用的 2D 障碍物,能够将由避障控制的代理约束在某个区域之外或之内。障碍物"
+"定义导航地图和轮廓顶点后才能正常工作。\n"
+"如果障碍物的顶点使用顺时针顺序缠绕,则避障代理会被推入障碍物,否则避障代理就会"
+"被推出障碍物。轮廓必须不存在交叉和重叠。\n"
+"障碍物[b]不是[/b](重新)烘焙导航网格的替代品。障碍物[b]不会[/b]改变寻路的结"
+"果,障碍物只会修改避障代理的推荐速度,从而影响导航避障代理的移动。\n"
+"使用顶点的障碍物可以传送至新位置,但不应该每一帧都移动,因为每次移动都需要重新"
+"构建避障地图。"
+
msgid "Using NavigationObstacles"
msgstr "使用 NavigationObstacle"
msgid ""
+"Returns the [RID] of the navigation map for this NavigationObstacle node. "
+"This function returns always the map set on the NavigationObstacle node and "
+"not the map of the abstract obstacle on the NavigationServer. If the obstacle "
+"map is changed directly with the NavigationServer API the NavigationObstacle "
+"node will not be aware of the map change. Use [method set_navigation_map] to "
+"change the navigation map for the NavigationObstacle and also update the "
+"obstacle on the NavigationServer."
+msgstr ""
+"返回该 NavigationObstacle 节点的导航地图的 [RID]。该函数始终返回在 "
+"NavigationObstacle 节点上设置的地图,而不是 NavigationServer 上抽象障碍物所使"
+"用的地图。如果该障碍物地图使用 NavigationServer API 直接更改,则该 "
+"NavigationObstacle 节点将不会察觉该地图的更改。请使用 [method "
+"set_navigation_map] 更改 NavigationObstacle 的导航地图,也会更新 "
+"NavigationServer 上的障碍物。"
+
+msgid "Returns the [RID] of this obstacle on the [NavigationServer2D]."
+msgstr "返回这个障碍物在 [NavigationServer2D] 上的 [RID]。"
+
+msgid ""
"Sets the [RID] of the navigation map this NavigationObstacle node should use "
"and also updates the [code]obstacle[/code] on the NavigationServer."
msgstr ""
@@ -66173,9 +69111,59 @@ msgid ""
msgstr ""
"用于导航的 3D 障碍物,能够将启用了避障处理的代理约束在某个区域之外或之内。"
+msgid ""
+"3D Obstacle used in navigation to constrain avoidance controlled agents "
+"outside or inside an area. The obstacle needs a navigation map and outline "
+"vertices defined to work correctly.\n"
+"If the obstacle's vertices are winded in clockwise order, avoidance agents "
+"will be pushed in by the obstacle, otherwise, avoidance agents will be pushed "
+"out. Outlines must not cross or overlap.\n"
+"Obstacles are [b]not[/b] a replacement for a (re)baked navigation mesh. "
+"Obstacles [b]don't[/b] change the resulting path from the pathfinding, "
+"obstacles only affect the navigation avoidance agent movement by altering the "
+"suggested velocity of the avoidance agent.\n"
+"Obstacles using vertices can warp to a new position but should not moved "
+"every frame as each move requires a rebuild of the avoidance map."
+msgstr ""
+"导航中使用的 3D 障碍物,能够将由避障控制的代理约束在某个区域之外或之内。障碍物"
+"定义导航地图和轮廓顶点后才能正常工作。\n"
+"如果障碍物的顶点使用顺时针顺序缠绕,则避障代理会被推入障碍物,否则避障代理就会"
+"被推出障碍物。轮廓必须不存在交叉和重叠。\n"
+"障碍物[b]不是[/b](重新)烘焙导航网格的替代品。障碍物[b]不会[/b]改变寻路的结"
+"果,障碍物只会修改避障代理的推荐速度,从而影响导航避障代理的移动。\n"
+"使用顶点的障碍物可以传送至新位置,但不应该每一帧都移动,因为每次移动都需要重新"
+"构建避障地图。"
+
+msgid "Returns the [RID] of this obstacle on the [NavigationServer3D]."
+msgstr "返回这个障碍物在 [NavigationServer3D] 上的 [RID]。"
+
+msgid ""
+"Sets the obstacle height used in 2D avoidance. 2D avoidance using agent's "
+"ignore obstacles that are below or above them."
+msgstr ""
+"设置 2D 避障所使用的障碍物高度。使用 2D 避障的代理会忽略在其之上或之下的障碍"
+"物。"
+
+msgid ""
+"If [code]true[/code] the obstacle affects 3D avoidance using agent's with "
+"obstacle [member radius].\n"
+"If [code]false[/code] the obstacle affects 2D avoidance using agent's with "
+"both obstacle [member vertices] as well as obstacle [member radius]."
+msgstr ""
+"如果为 [code]true[/code],则该障碍物会影响 3D 避障,使用的是代理的障碍物半径 "
+"[member radius]。\n"
+"如果为 [code]false[/code],则该障碍物会影响 2D 避障,使用的是代理的障碍物顶点 "
+"[member vertices] 和障碍物半径 [member radius]。"
+
msgid "Provides parameters for 2D navigation path queries."
msgstr "为 2D 导航路径查询提供参数。"
+msgid ""
+"By changing various properties of this object, such as the start and target "
+"position, you can configure path queries to the [NavigationServer2D]."
+msgstr ""
+"更改该对象的起始和结束位置等属性可以配置对 [NavigationServer2D] 的路径查询。"
+
msgid "Using NavigationPathQueryObjects"
msgstr "使用 NavigationPathQueryObject"
@@ -66243,6 +69231,12 @@ msgstr "包含关于返回路径的所有可用元数据。"
msgid "Provides parameters for 3D navigation path queries."
msgstr "为 3D 导航路径查询提供参数。"
+msgid ""
+"By changing various properties of this object, such as the start and target "
+"position, you can configure path queries to the [NavigationServer3D]."
+msgstr ""
+"更改该对象的起始和结束位置等属性可以配置对 [NavigationServer3D] 的路径查询。"
+
msgid "Represents the result of a 2D pathfinding query."
msgstr "代表 2D 寻路查询的结果。"
@@ -66302,6 +69296,9 @@ msgstr ""
"导航查询的路径数组结果。所有的路径数组位置都使用全局坐标。未自定义查询参数时,"
"与 [method NavigationServer3D.map_get_path] 返回的路径相同。"
+msgid "A navigation polygon that defines traversable areas and obstacles."
+msgstr "定义可达区域和障碍物的导航多边形。"
+
msgid ""
"There are two ways to create polygons. Either by using the [method "
"add_outline] method, or using the [method add_polygon] method.\n"
@@ -66525,6 +69522,23 @@ msgstr ""
msgid "A bitfield determining all avoidance layers for the avoidance constrain."
msgstr "位域,确定避障约束的所有避障层。"
+msgid ""
+"If [code]true[/code] constraints avoidance agent's with an avoidance mask bit "
+"that matches with a bit of the [member avoidance_layers] to the navigation "
+"polygon. Due to each navigation polygon outline creating an obstacle and each "
+"polygon edge creating an avoidance line constrain keep the navigation polygon "
+"shape as simple as possible for performance.\n"
+"[b]Experimental:[/b] This is an experimental feature and should not be used "
+"in production as agent's can get stuck on the navigation polygon corners and "
+"edges especially at high frame rate."
+msgstr ""
+"如果为 [code]true[/code],则会将避障代理的避障掩码位与导航多边形的 [member "
+"avoidance_layers] 位相匹配。由于每个导航多边形轮廓都会创建一个障碍物,而每个多"
+"边形边缘都会创建一条避障线约束,因此为了提高性能,要尽量保持导航多边形的形状尽"
+"可能简单。\n"
+"[b]实验性:[/b]这是一个实验性功能,不应在生产中使用,因为代理在导航多边形的角"
+"和边缘,特别是在高帧率下,可能会被卡住。"
+
msgid "Determines if the [NavigationRegion2D] is enabled or disabled."
msgstr "决定该 [NavigationRegion2D] 是启用还是禁用。"
@@ -66556,6 +69570,14 @@ msgstr ""
"定最短路径。"
msgid ""
+"If enabled the navigation region will use edge connections to connect with "
+"other navigation regions within proximity of the navigation map edge "
+"connection margin."
+msgstr ""
+"如果启用,导航区块将使用边缘连接来与位于导航地图连接边距范围内的其他导航区块相"
+"连接。"
+
+msgid ""
"A traversable 3D region that [NavigationAgent3D]s can use for pathfinding."
msgstr "可达的 3D 地区,[NavigationAgent3D] 能够将其用于寻路。"
@@ -66635,6 +69657,56 @@ msgstr "导航网格烘焙操作完成时发出通知。"
msgid "Notifies when the [NavigationMesh] has changed."
msgstr "[NavigationMesh] 发生变化时发出通知。"
+msgid "A server interface for low-level 2D navigation access."
+msgstr "用于访问低阶 2D 导航的服务器接口。"
+
+msgid ""
+"NavigationServer2D is the server that handles navigation maps, regions and "
+"agents. It does not handle A* navigation from [AStar2D] or [AStarGrid2D].\n"
+"Maps are made up of regions, which are made of navigation polygons. Together, "
+"they define the traversable areas in the 2D world.\n"
+"[b]Note:[/b] Most [NavigationServer2D] changes take effect after the next "
+"physics frame and not immediately. This includes all changes made to maps, "
+"regions or agents by navigation-related nodes in the scene tree or made "
+"through scripts.\n"
+"For two regions to be connected to each other, they must share a similar "
+"edge. An edge is considered connected to another if both of its two vertices "
+"are at a distance less than [code]edge_connection_margin[/code] to the "
+"respective other edge's vertex.\n"
+"You may assign navigation layers to regions with [method NavigationServer2D."
+"region_set_navigation_layers], which then can be checked upon when requesting "
+"a path with [method NavigationServer2D.map_get_path]. This can be used to "
+"allow or deny certain areas for some objects.\n"
+"To use the collision avoidance system, you may use agents. You can set an "
+"agent's target velocity, then the servers will emit a callback with a "
+"modified velocity.\n"
+"[b]Note:[/b] The collision avoidance system ignores regions. Using the "
+"modified velocity directly may move an agent outside of the traversable area. "
+"This is a limitation of the collision avoidance system, any more complex "
+"situation may require the use of the physics engine.\n"
+"This server keeps tracks of any call and executes them during the sync phase. "
+"This means that you can request any change to the map, using any thread, "
+"without worrying."
+msgstr ""
+"NavigationServer2D 是负责处理导航地图、区块、代理的服务器。不负责处理 "
+"[AStar2D] 和 [AStarGrid2D] 的 A* 导航。\n"
+"地图由区块组成,区块由导航多边形组成。它们共同定义了 2D 空间中的可达区域。\n"
+"[b]注意:[/b]大多数 [NavigationServer2D] 的更改都是在下一个物理帧进行的,不会"
+"立即生效。包括所有对地图、区块、代理的更改,无论是通过场景树中导航相关的节点作"
+"出的更改,还是通过脚本作出的更改。\n"
+"两个区块必须共享一条相似的边才能相连。如果一条边的两个顶点与另一条边上相应顶点"
+"的距离都小于 [code]edge_connection_margin[/code],那么就会认为这两条边是相连"
+"的。\n"
+"可以使用 [method NavigationServer2D.region_set_navigation_layers] 为区块分配导"
+"航层,使用 [method NavigationServer2D.map_get_path] 请求路径时会对导航层进行检"
+"查。可用于允许或禁止某些对象进入特定的区域。\n"
+"使用碰撞躲避系统就需要使用代理。你可以为代理设置目标速度,然后服务器就会发出回"
+"调,提供修改后的速度。\n"
+"[b]注意:[/b]碰撞躲避系统并不考虑区块。直接使用修改后的速度可能会将代理移动到"
+"可达区域之外。这是碰撞躲避系统的缺陷,更复杂的场合可能需要使用物理引擎。\n"
+"服务器会对所有调用进行跟踪,并在同步阶段执行。这意味着你可以放心地从任何线程请"
+"求对地图作出任何修改。"
+
msgid "Using NavigationServer"
msgstr "使用 NavigationServer"
@@ -66656,6 +69728,21 @@ msgid "Returns true if the map got changed the previous frame."
msgstr "如果该地图在上一帧发生了改变,则返回 true。"
msgid ""
+"Sets the callback [Callable] that gets called after each avoidance processing "
+"step for the [param agent]. The calculated [code]safe_velocity[/code] will be "
+"dispatched with a signal to the object just before the physics calculations.\n"
+"[b]Note:[/b] Created callbacks are always processed independently of the "
+"SceneTree state as long as the agent is on a navigation map and not freed. To "
+"disable the dispatch of a callback from an agent use [method "
+"agent_set_avoidance_callback] again with an empty [Callable]."
+msgstr ""
+"设置在 [param agent] 的每个避障处理步骤之后调用的回调 [Callable]。计算出的 "
+"[code]safe_velocity[/code] 将在物理计算之前通过信号发送。\n"
+"[b]注意:[/b]只要代理还在导航地图上且未被释放,创建的回调就会始终独立于 "
+"SceneTree 状态进行处理。要为某个代理禁用回调的发送,请再次使用一个空的 "
+"[Callable] 来调用 [method agent_set_avoidance_callback]。"
+
+msgid ""
"If [param enabled] is [code]true[/code] the specified [param agent] uses "
"avoidance."
msgstr ""
@@ -66667,6 +69754,20 @@ msgstr "设置该代理的 [code]avoidance_layers[/code] 位掩码。"
msgid "Set the agent's [code]avoidance_mask[/code] bitmask."
msgstr "设置该代理的 [code]avoidance_mask[/code] 位掩码。"
+msgid ""
+"Set the agent's [code]avoidance_priority[/code] with a [param priority] "
+"between 0.0 (lowest priority) to 1.0 (highest priority).\n"
+"The specified [param agent] does not adjust the velocity for other agents "
+"that would match the [code]avoidance_mask[/code] but have a lower [code] "
+"avoidance_priority[/code]. This in turn makes the other agents with lower "
+"priority adjust their velocities even more to avoid collision with this agent."
+msgstr ""
+"设置该代理的 [code]avoidance_priority[/code],优先级 [param priority] 在 0.0"
+"(最低优先级)到 1.0(最高优先级)之间。\n"
+"[param agent] 指定的代理不会针对 [code]avoidance_mask[/code] 存在匹配但 "
+"[code] avoidance_priority[/code] 更低的代理调整速度。相应地,优先级更低的代理"
+"则会对其速度进行更大的调整,从而避免与这个代理发生碰撞。"
+
msgid "Puts the agent in the map."
msgstr "将代理放入地图中。"
@@ -66702,6 +69803,51 @@ msgstr "设置该代理在世界空间中的位置。"
msgid "Sets the radius of the agent."
msgstr "设置该代理的半径。"
+msgid ""
+"The minimal amount of time for which the agent's velocities that are computed "
+"by the simulation are safe with respect to other agents. The larger this "
+"number, the sooner this agent will respond to the presence of other agents, "
+"but the less freedom this agent has in choosing its velocities. A too high "
+"value will slow down agents movement considerably. Must be positive."
+msgstr ""
+"考虑其他代理的前提下,该代理的速度的最短安全时间,这个速度是通过仿真得到的。数"
+"值越大,代理响应其他代理的速度就越快,但该代理选择速度的自由度也就越小。太高的"
+"取值会大大降低代理的移动速度。必须为正数。"
+
+msgid ""
+"The minimal amount of time for which the agent's velocities that are computed "
+"by the simulation are safe with respect to static avoidance obstacles. The "
+"larger this number, the sooner this agent will respond to the presence of "
+"static avoidance obstacles, but the less freedom this agent has in choosing "
+"its velocities. A too high value will slow down agents movement considerably. "
+"Must be positive."
+msgstr ""
+"考虑其他静态避障障碍物的前提下,该代理的速度的最短安全时间,这个速度是通过仿真"
+"得到的。数值越大,代理响应存在的静态避障障碍物的速度就越快,但该代理选择速度的"
+"自由度也就越小。太高的取值会大大降低代理的移动速度。必须为正数。"
+
+msgid ""
+"Sets [param velocity] as the new wanted velocity for the specified [param "
+"agent]. The avoidance simulation will try to fulfill this velocity if "
+"possible but will modify it to avoid collision with other agent's and "
+"obstacles. When an agent is teleported to a new position far away use [method "
+"agent_set_velocity_forced] instead to reset the internal velocity state."
+msgstr ""
+"将 [param velocity] 设置为指定代理 [param agent] 的新的需求速度。避障仿真会尽"
+"可能尝试满足这个速度,但为了躲避与其他代理和障碍物的碰撞也会对它进行修改。将代"
+"理传送至新的较远的位置时,请改用 [method agent_set_velocity_forced] 重置内部速"
+"度状态。"
+
+msgid ""
+"Replaces the internal velocity in the collision avoidance simulation with "
+"[param velocity] for the specified [param agent]. When an agent is teleported "
+"to a new position far away this function should be used in the same frame. If "
+"called frequently this function can get agents stuck."
+msgstr ""
+"将指定代理 [param agent] 的避障仿真内部速度替换为 [param velocity]。将代理传送"
+"至新的较远的位置时,应该在同一帧里使用这个函数。频繁调用这个函数可能让代理卡"
+"住。"
+
msgid "Destroys the given RID."
msgstr "销毁给定的 RID。"
@@ -66719,9 +69865,17 @@ msgstr ""
msgid "Create a new link between two positions on a map."
msgstr "在地图上新建两个地点之间的链接。"
+msgid "Returns the ending position of this [param link]."
+msgstr "返回链接 [param link] 的结束位置。"
+
msgid "Returns the enter cost of this [param link]."
msgstr "返回 [param link] 链接的进入消耗。"
+msgid ""
+"Returns the navigation map [RID] the requested [param link] is currently "
+"assigned to."
+msgstr "返回请求的导航链接 [param link] 当前分配的导航地图的 [RID]。"
+
msgid "Returns the navigation layers for this [param link]."
msgstr "返回 [param link] 的导航层。"
@@ -66842,6 +69996,16 @@ msgstr ""
"围。"
msgid ""
+"Returns all navigation link [RID]s that are currently assigned to the "
+"requested navigation [param map]."
+msgstr "返回当前分配给请求的导航地图 [param map] 的所有导航链接的 [RID]。"
+
+msgid ""
+"Returns all navigation obstacle [RID]s that are currently assigned to the "
+"requested navigation [param map]."
+msgstr "返回当前分配给请求的导航地图 [param map] 的所有导航障碍物的 [RID]。"
+
+msgid ""
"Returns the navigation path to reach the destination from the origin. [param "
"navigation_layers] is a bitmask of all region navigation layers that are "
"allowed to be in the path."
@@ -66854,6 +70018,14 @@ msgid ""
"requested navigation [param map]."
msgstr "返回当前分配给所请求的导航 [param map] 的所有导航区块的 [RID]。"
+msgid ""
+"Returns whether the navigation [param map] allows navigation regions to use "
+"edge connections to connect with other navigation regions within proximity of "
+"the navigation map edge connection margin."
+msgstr ""
+"返回是否允许导航地图 [param map] 使用边缘连接与位于导航地图边缘连接边距范围内"
+"的其他导航区块相连接。"
+
msgid "Returns true if the map is active."
msgstr "如果地图处于活动状态,则返回 true。"
@@ -66861,6 +70033,13 @@ msgid "Sets the map active."
msgstr "设置地图的激活态。"
msgid ""
+"Sets the map cell size used to rasterize the navigation mesh vertices. Must "
+"match with the cell size of the used navigation meshes."
+msgstr ""
+"设置用于栅格化导航网格顶点的地图单元格大小。必须与所使用的导航网格单元格大小相"
+"匹配。"
+
+msgid ""
"Set the map edge connection margin used to weld the compatible region edges."
msgstr "设置用于焊接兼容地区边界的地图边界连接边距。"
@@ -66869,6 +70048,15 @@ msgid ""
"polygons."
msgstr "设置该地图用于连接链接和导航多边形的链接连接半径。"
+msgid ""
+"Set the navigation [param map] edge connection use. If [param enabled] the "
+"navigation map allows navigation regions to use edge connections to connect "
+"with other navigation regions within proximity of the navigation map edge "
+"connection margin."
+msgstr ""
+"设置导航地图 [param map] 的边缘连接使用情况。如果 [param enabled],则导航地图"
+"允许导航区块使用边缘连接与位于导航地图边缘连接边距范围内的其他导航区块相连接。"
+
msgid "Creates a new navigation obstacle."
msgstr "新建导航障碍物。"
@@ -66877,8 +70065,19 @@ msgid ""
"enabled."
msgstr "如果给定的 [param obstacle] 启用了避障,则返回 [code]true[/code]。"
+msgid ""
+"Returns the navigation map [RID] the requested [param obstacle] is currently "
+"assigned to."
+msgstr "返回请求的障碍物 [param obstacle] 当前分配的导航地图 [RID]。"
+
msgid "Returns [code]true[/code] if the specified [param obstacle] is paused."
-msgstr "如果指定的 [enum obstacle] 被暂停,则返回 [code]true[/code]。"
+msgstr "如果指定的 [param obstacle] 被暂停,则返回 [code]true[/code]。"
+
+msgid ""
+"If [param enabled] the provided [param obstacle] affects avoidance using "
+"agents."
+msgstr ""
+"如果 [param enabled],则提供的障碍物 [param obstacle] 会影响代理的避障。"
msgid "Set the obstacles's [code]avoidance_layers[/code] bitmask."
msgstr "设置障碍物的避障层 [code]avoidance_layers[/code] 位掩码。"
@@ -66886,6 +70085,13 @@ msgstr "设置障碍物的避障层 [code]avoidance_layers[/code] 位掩码。"
msgid "Sets the navigation map [RID] for the obstacle."
msgstr "为障碍物设置导航地图 [RID]。"
+msgid ""
+"If [param paused] is true the specified [param obstacle] will not be "
+"processed, e.g. affect avoidance velocities."
+msgstr ""
+"如果 [param paused] 为 true,则不会处理指定的障碍物 [param obstacle],例如不会"
+"影响避障速度。"
+
msgid "Sets the position of the obstacle in world space."
msgstr "设置障碍物在世界空间中的位置。"
@@ -66893,6 +70099,22 @@ msgid "Sets the radius of the dynamic obstacle."
msgstr "设置动态障碍物的半径。"
msgid ""
+"Sets [param velocity] of the dynamic [param obstacle]. Allows other agents to "
+"better predict the movement of the dynamic obstacle. Only works in "
+"combination with the radius of the obstacle."
+msgstr ""
+"将动态障碍物 [param obstacle] 的速度设置为 [param velocity]。能够让其他代理更"
+"好地预测该动态障碍物的移动。仅在与障碍物半径一同使用时有效。"
+
+msgid ""
+"Sets the outline vertices for the obstacle. If the vertices are winded in "
+"clockwise order agents will be pushed in by the obstacle, else they will be "
+"pushed out."
+msgstr ""
+"设置障碍物的轮廓顶点。如果顶点顺时针缠绕,则障碍物会将代理向内部推挤,否则向外"
+"推挤。"
+
+msgid ""
"Queries a path in a given navigation map. Start and target position and other "
"parameters are defined through [NavigationPathQueryParameters2D]. Updates the "
"provided [NavigationPathQueryResult2D] result object with the path among "
@@ -66943,6 +70165,14 @@ msgid "Returns the travel cost of this [param region]."
msgstr "返回 [param region] 地区的移动消耗。"
msgid ""
+"Returns whether the navigation [param region] is set to use edge connections "
+"to connect with other navigation regions within proximity of the navigation "
+"map edge connection margin."
+msgstr ""
+"返回导航区块 [param region] 是否被设置为使用边缘连接与位于导航地图边缘连接边距"
+"范围内的其他导航区块相连接。"
+
+msgid ""
"Returns [code]true[/code] if the provided [param point] in world space is "
"currently owned by the provided navigation [param region]. Owned in this "
"context means that one of the region's navigation mesh polygon faces has a "
@@ -66991,6 +70221,14 @@ msgstr "设置该地区的全局变换。"
msgid "Sets the [param travel_cost] for this [param region]."
msgstr "设置 [param region] 地区的移动消耗 [param travel_cost]。"
+msgid ""
+"If [param enabled] the navigation [param region] will use edge connections to "
+"connect with other navigation regions within proximity of the navigation map "
+"edge connection margin."
+msgstr ""
+"如果 [param enabled],导航区块 [param region] 将使用边缘连接来与位于导航地图边"
+"缘连接边距范围内的其他导航区块相连接。"
+
msgid "If [code]true[/code] enables debug mode on the NavigationServer."
msgstr "如果为 [code]true[/code],则该 NavigationServer 启用了调试模式。"
@@ -67003,6 +70241,123 @@ msgid ""
"builds."
msgstr "当导航调试设置更改时发出。仅在调试版本中可用。"
+msgid "A server interface for low-level 3D navigation access."
+msgstr "用于访问低阶 3D 导航的服务器接口。"
+
+msgid ""
+"NavigationServer2D is the server that handles navigation maps, regions and "
+"agents. It does not handle A* navigation from [AStar3D].\n"
+"Maps are made up of regions, which are made of navigation meshes. Together, "
+"they define the navigable areas in the 3D world.\n"
+"[b]Note:[/b] Most [NavigationServer3D] changes take effect after the next "
+"physics frame and not immediately. This includes all changes made to maps, "
+"regions or agents by navigation-related nodes in the scene tree or made "
+"through scripts.\n"
+"For two regions to be connected to each other, they must share a similar "
+"edge. An edge is considered connected to another if both of its two vertices "
+"are at a distance less than [code]edge_connection_margin[/code] to the "
+"respective other edge's vertex.\n"
+"You may assign navigation layers to regions with [method NavigationServer3D."
+"region_set_navigation_layers], which then can be checked upon when requesting "
+"a path with [method NavigationServer3D.map_get_path]. This can be used to "
+"allow or deny certain areas for some objects.\n"
+"To use the collision avoidance system, you may use agents. You can set an "
+"agent's target velocity, then the servers will emit a callback with a "
+"modified velocity.\n"
+"[b]Note:[/b] The collision avoidance system ignores regions. Using the "
+"modified velocity directly may move an agent outside of the traversable area. "
+"This is a limitation of the collision avoidance system, any more complex "
+"situation may require the use of the physics engine.\n"
+"This server keeps tracks of any call and executes them during the sync phase. "
+"This means that you can request any change to the map, using any thread, "
+"without worrying."
+msgstr ""
+"NavigationServer3D 是负责处理导航地图、区块、代理的服务器。不负责处理 "
+"[AStar3D] 的 A* 导航。\n"
+"地图由区块组成,区块由导航网格组成。它们共同定义了 3D 空间中的可达区域。\n"
+"[b]注意:[/b]大多数 [NavigationServer3D] 的更改都是在下一个物理帧进行的,不会"
+"立即生效。包括所有对地图、区块、代理的更改,无论是通过场景树中导航相关的节点作"
+"出的更改,还是通过脚本作出的更改。\n"
+"两个区块必须共享一条相似的边才能相连。如果一条边的两个顶点与另一条边上相应顶点"
+"的距离都小于 [code]edge_connection_margin[/code],那么就会认为这两条边是相连"
+"的。\n"
+"可以使用 [method NavigationServer3D.region_set_navigation_layers] 为区块分配导"
+"航层,使用 [method NavigationServer3D.map_get_path] 请求路径时会对导航层进行检"
+"查。可用于允许或禁止某些对象进入特定的区域。\n"
+"使用碰撞躲避系统就需要使用代理。你可以为代理设置目标速度,然后服务器就会发出回"
+"调,提供修改后的速度。\n"
+"[b]注意:[/b]碰撞躲避系统并不考虑区块。直接使用修改后的速度可能会将代理移动到"
+"可达区域之外。这是碰撞躲避系统的缺陷,更复杂的场合可能需要使用物理引擎。\n"
+"服务器会对所有调用进行跟踪,并在同步阶段执行。这意味着你可以放心地从任何线程请"
+"求对地图作出任何修改。"
+
+msgid ""
+"Returns [code]true[/code] if the provided [param agent] has avoidance enabled."
+msgstr "如果指定代理 [param agent] 启用了避障,则返回 [code]true[/code]。"
+
+msgid ""
+"Returns [code]true[/code] if the provided [param agent] uses avoidance in 3D "
+"space Vector3(x,y,z) instead of horizontal 2D Vector2(x,y) / Vector3(x,0.0,z)."
+msgstr ""
+"如果指定代理 [param agent] 使用 3D 空间 Vector3(x,y,z) 的避障而不是水平 2D "
+"Vector2(x,y) / Vector3(x,0.0,z) 避障,则返回 [code]true[/code]。"
+
+msgid "If [param enabled] the provided [param agent] calculates avoidance."
+msgstr "如果 [param enabled],指定代理 [param agent] 会计算避障。"
+
+msgid "Updates the provided [param agent] [param height]."
+msgstr "更新指定代理 [param agent] 的高度 [param height]。"
+
+msgid ""
+"Sets if the agent uses the 2D avoidance or the 3D avoidance while avoidance "
+"is enabled.\n"
+"If [code]true[/code] the agent calculates avoidance velocities in 3D for the "
+"xyz-axis, e.g. for games that take place in air, unterwater or space. The 3D "
+"using agent only avoids other 3D avoidance using agent's. The 3D using agent "
+"only reacts to radius based avoidance obstacles. The 3D using agent ignores "
+"any vertices based obstacles. The 3D using agent only avoids other 3D using "
+"agent's.\n"
+"If [code]false[/code] the agent calculates avoidance velocities in 2D along "
+"the xz-axis ignoring the y-axis. The 2D using agent only avoids other 2D "
+"avoidance using agent's. The 2D using agent reacts to radius avoidance "
+"obstacles. The 2D using agent reacts to vertices based avoidance obstacles. "
+"The 2D using agent only avoids other 2D using agent's. 2D using agents will "
+"ignore other 2D using agents or obstacles that are below their current "
+"position or above their current position including the agents height in 2D "
+"avoidance."
+msgstr ""
+"设置该代理在启用避障时使用 2D 避障还是 3D 避障。\n"
+"如果为 [code]true[/code],则代理会为 XYZ 轴计算 3D 避障速度,例如在空中、水"
+"中、太空中进行的游戏。使用 3D 的代理只会躲避其他使用 3D 避障的代理。使用 3D 的"
+"代理只会响应基于半径的避障障碍物。使用 3D 的代理会忽略基于顶点的障碍物。使用 "
+"3D 的代理只会躲避其他使用 3D 的代理。\n"
+"如果为 [code]false[/code],则代理会沿 XZ 轴计算 2D 避障速度,忽略 Y 轴。使用 "
+"2D 的代理只会躲避其他使用 2D 避障的代理。使用 2D 的代理会响应基于半径的避障障"
+"碍物。使用 2D 的代理会响应基于顶点的避障障碍物。使用 2D 的代理只会躲避其他使"
+"用 2D 的代理。在 2D 避障时,使用 2D 的代理会忽略它们位于当前位置之下或者位于当"
+"前位置与代理高度之和之上的其他使用 2D 的代理和障碍物。"
+
+msgid ""
+"Sets [param velocity] as the new wanted velocity for the specified [param "
+"agent]. The avoidance simulation will try to fulfill this velocity if "
+"possible but will modify it to avoid collision with other agent's and "
+"obstacles. When an agent is teleported to a new position use [method "
+"agent_set_velocity_forced] as well to reset the internal simulation velocity."
+msgstr ""
+"将 [param velocity] 设置为指定代理 [param agent] 的新的需求速度。避障仿真会尽"
+"可能尝试满足这个速度,但为了躲避与其他代理和障碍物的碰撞也会对它进行修改。将代"
+"理传送至新的位置时,请使用 [method agent_set_velocity_forced] 重置内部仿真速"
+"度。"
+
+msgid ""
+"Replaces the internal velocity in the collision avoidance simulation with "
+"[param velocity] for the specified [param agent]. When an agent is teleported "
+"to a new position this function should be used in the same frame. If called "
+"frequently this function can get agents stuck."
+msgstr ""
+"将指定代理 [param agent] 的避障仿真内部速度替换为 [param velocity]。将代理传送"
+"至新的位置时,应该在同一帧里使用这个函数。频繁调用这个函数可能让代理卡住。"
+
msgid ""
"Returns information about the current state of the NavigationServer. See "
"[enum ProcessInfo] for a list of available states."
@@ -67018,6 +70373,16 @@ msgstr ""
"NavigationServer3D.map_get_path] 时)。"
msgid ""
+"Returns the map cell height used to rasterize the navigation mesh vertices on "
+"the Y axis."
+msgstr "返回在 Y 轴上栅格化导航网格顶点所使用的地图单元格高度。"
+
+msgid ""
+"Returns the map cell size used to rasterize the navigation mesh vertices on "
+"the XZ plane."
+msgstr "返回在 XZ 平面上栅格化导航网格顶点所使用的地图单元格大小。"
+
+msgid ""
"Returns the normal for the point returned by [method map_get_closest_point]."
msgstr "返回 [method map_get_closest_point] 所返回的点的法线。"
@@ -67034,9 +70399,60 @@ msgstr ""
msgid "Returns the map's up direction."
msgstr "返回地图的上方向。"
+msgid ""
+"Returns true if the navigation [param map] allows navigation regions to use "
+"edge connections to connect with other navigation regions within proximity of "
+"the navigation map edge connection margin."
+msgstr ""
+"如果导航地图 [param map] 允许导航区块使用边缘连接与位于导航地图边缘连接边距范"
+"围内的其他导航区块相连接,则返回 true。"
+
+msgid ""
+"Sets the map cell height used to rasterize the navigation mesh vertices on "
+"the Y axis. Must match with the cell height of the used navigation meshes."
+msgstr ""
+"设置在 Y 轴上栅格化导航网格顶点所使用的地图单元格高度。必须与所使用的导航网格"
+"的单元格高度相匹配。"
+
+msgid ""
+"Sets the map cell size used to rasterize the navigation mesh vertices on the "
+"XZ plane. Must match with the cell size of the used navigation meshes."
+msgstr ""
+"设置在 XZ 平面上栅格化导航网格顶点所使用的地图单元格大小。必须与所使用的导航网"
+"格的单元格大小相匹配。"
+
msgid "Sets the map up direction."
msgstr "设置地图的上方向。"
+msgid "Creates a new obstacle."
+msgstr "新建障碍物。"
+
+msgid ""
+"Returns [code]true[/code] if the provided [param obstacle] uses avoidance in "
+"3D space Vector3(x,y,z) instead of horizontal 2D Vector2(x,y) / Vector3(x,0.0,"
+"z)."
+msgstr ""
+"如果提供的 [param obstacle] 使用 3D 空间的 Vector3(x,y,z),不使用水平 2D "
+"Vector2(x,y) / Vector3(x,0.0,z),则返回 [code]true[/code]。"
+
+msgid ""
+"Sets the [param height] for the [param obstacle]. In 3D agents will ignore "
+"obstacles that are above or below them while using 2D avoidance."
+msgstr ""
+"设置 [param obstacle] 的高度 [param height]。3D 代理会忽略位于其上方和下方的障"
+"碍物,使用 2D 避障。"
+
+msgid "Assigns the [param obstacle] to a navigation map."
+msgstr "将 [param obstacle] 分配给导航地图。"
+
+msgid "Updates the [param position] in world space for the [param obstacle]."
+msgstr "为 [param obstacle] 更新世界空间中的位置 [param position]。"
+
+msgid ""
+"Sets if the [param obstacle] uses the 2D avoidance or the 3D avoidance while "
+"avoidance is enabled."
+msgstr "设置 [param obstacle] 在启用避障时使用 2D 避障还是 3D 避障。"
+
msgid ""
"Queries a path in a given navigation map. Start and target position and other "
"parameters are defined through [NavigationPathQueryParameters3D]. Updates the "
@@ -67055,6 +70471,14 @@ msgstr ""
"navigation_mesh]。"
msgid ""
+"Returns true if the navigation [param region] is set to use edge connections "
+"to connect with other navigation regions within proximity of the navigation "
+"map edge connection margin."
+msgstr ""
+"如果导航区块 [param region] 被设置为使用边缘连接与位于导航地图边缘连接边距范围"
+"内的其他导航区块相连接,则返回 true。"
+
+msgid ""
"Set the region's navigation layers. This allows selecting regions from a path "
"request (when using [method NavigationServer3D.map_get_path])."
msgstr ""
@@ -67067,6 +70491,11 @@ msgstr "设置该地图的导航网格。"
msgid "Control activation of this server."
msgstr "控制这个服务器是否激活。"
+msgid ""
+"Emitted when avoidance debug settings are changed. Only available in debug "
+"builds."
+msgstr "当避障调试设置更改时发出。仅在调试版本中可用。"
+
msgid "Constant to get the number of active navigation maps."
msgstr "常量,用于获取活动导航地图的数量。"
@@ -67102,6 +70531,21 @@ msgid ""
msgstr ""
"常量,用于获取无法合并但仍可通过边接近或链接连接的导航网格多边形的边的数量。"
+msgid ""
+"A control that displays a texture by keeping its corners intact, but tiling "
+"its edges and center."
+msgstr "显示纹理的控件,会保持角落不变,但平铺边缘和中心。"
+
+msgid ""
+"Also known as 9-slice panels, [NinePatchRect] produces clean panels of any "
+"size based on a small texture. To do so, it splits the texture in a 3×3 grid. "
+"When you scale the node, it tiles the texture's edges horizontally or "
+"vertically, tiles the center on both axes, and leaves the corners unchanged."
+msgstr ""
+"也叫 9 片式面板,[NinePatchRect] 能够根据较小的纹理,生成任何大小的干净面板。"
+"为了做到这一点,它将纹理分割成 3×3 的网格。当你缩放节点时,它会在水平或垂直方"
+"向上平铺纹理的侧边,在两个轴上平铺中心,但不会缩放或平铺角落。"
+
msgid "Returns the size of the margin on the specified [enum Side]."
msgstr "返回指定 [enum Side] 的边距大小。"
@@ -67445,7 +70889,7 @@ msgstr ""
"[method set_process] 来开关。\n"
"对应于 [method Object._notification] 中的 [constant NOTIFICATION_PROCESS] 通"
"知。\n"
-"[b]注意:[/b] 这个方法只有在节点存在于场景树中时才会被调用(也就是说,如果它不"
+"[b]注意:[/b]这个方法只有在节点存在于场景树中时才会被调用(也就是说,如果它不"
"是“孤儿”)。"
msgid ""
@@ -67470,7 +70914,7 @@ msgstr ""
"请参阅用于变量的 [code]@onready[/code] 注解。\n"
"通常用于初始化。对于更早的初始化,可以使用 [method Object._init]。另见 "
"[method _enter_tree]。\n"
-"[b]注意:[/b] 对于每个节点可能仅调用一次 [method _ready]。从场景树中移除一个节"
+"[b]注意:[/b]对于每个节点可能仅调用一次 [method _ready]。从场景树中移除一个节"
"点后,并再次添加该节点时,将不会第二次调用 [code]_ready[/code]。这时可以通过使"
"用 [method request_ready],它可以在再次添加节点之前的任何地方被调用。"
@@ -67494,7 +70938,7 @@ msgstr ""
"要消耗输入事件,并阻止它进一步传播到其他节点,可以调用 [method Viewport."
"set_input_as_handled]。\n"
"此方法可用于处理快捷键。\n"
-"[b]注意:[/b] 仅当该节点存在于场景树中(即它不是一个孤儿节点)时,此方法才会被"
+"[b]注意:[/b]仅当该节点存在于场景树中(即它不是一个孤儿节点)时,此方法才会被"
"调用。"
msgid ""
@@ -67692,6 +71136,28 @@ msgstr ""
"为它可能因项目运行而异。"
msgid ""
+"This function is similar to [method Object.call_deferred] except that the "
+"call will take place when the node thread group is processed. If the node "
+"thread group processes in sub-threads, then the call will be done on that "
+"thread, right before [constant NOTIFICATION_PROCESS] or [constant "
+"NOTIFICATION_PHYSICS_PROCESS], the [method _process] or [method "
+"_physics_process] or their internal versions are called."
+msgstr ""
+"这个函数类似于 [method Object.call_deferred],但是会在处理节点线程组时进行调"
+"用。如果节点线程组在子线程中处理,那么调用就会在该线程中进行,时机为 "
+"[constant NOTIFICATION_PROCESS] 和 [constant NOTIFICATION_PHYSICS_PROCESS]、"
+"[method _process] 和 [method _physics_process],或者对应的内部版本之前。"
+
+msgid ""
+"This function ensures that the calling of this function will succeed, no "
+"matter whether it's being done from a thread or not. If called from a thread "
+"that is not allowed to call the function, the call will become deferred. "
+"Otherwise, the call will go through directly."
+msgstr ""
+"这个函数能够确保调用成功,无论是否从线程中调用。如果是从不允许调用该函数的线程"
+"中调用的,那么调用就会变成延迟调用。否则就会直接调用。"
+
+msgid ""
"Returns [code]true[/code] if the node can process while the scene tree is "
"paused (see [member process_mode]). Always returns [code]true[/code] if the "
"scene tree is not paused, and [code]false[/code] if the node is not in the "
@@ -68096,8 +71562,8 @@ msgid ""
"Similar to [method get_node], but does not log an error if [param path] does "
"not point to a valid [Node]."
msgstr ""
-"类似于 [method get_node],但在 [code]path[/code] 没有指向有效的 [Node] 时不会"
-"记录错误。"
+"类似于 [method get_node],但在 [param path] 没有指向有效的 [Node] 时不会记录错"
+"误。"
msgid ""
"Returns the parent node of the current node, or [code]null[/code] if the node "
@@ -68547,6 +72013,28 @@ msgstr ""
"具。"
msgid ""
+"Sets the node's multiplayer authority to the peer with the given peer ID. The "
+"multiplayer authority is the peer that has authority over the node on the "
+"network. Useful in conjunction with [method rpc_config] and the "
+"[MultiplayerAPI]. Inherited from the parent node by default, which ultimately "
+"defaults to peer ID 1 (the server). If [param recursive], the given peer is "
+"recursively set as the authority for all children of this node.\n"
+"[b]Warning:[/b] This does [b]not[/b] automatically replicate the new "
+"authority to other peers. It is developer's responsibility to do so. You can "
+"propagate the information about the new authority using [member "
+"MultiplayerSpawner.spawn_function], an RPC, or using a "
+"[MultiplayerSynchronizer]."
+msgstr ""
+"将该节点的多人游戏控制方设置为具有给定对等体 ID 的对等体。多人游戏控制方是对网"
+"络上的节点具有控制权限的对等体。可以与 [method rpc_config] 和 "
+"[MultiplayerAPI] 结合使用。默认从父节点继承,最终默认为对等体 ID 1(服务器)。"
+"如果 [param recursive],则给定的对等体会被递归设置为该节点所有子节点的控制"
+"方。\n"
+"[b]警告:[/b]这样做[b]不会[/b]自动将新的控制方复制给其他对等体。开发者需要自己"
+"负责。你可以使用 [member MultiplayerSpawner.spawn_function]、RPC、"
+"[MultiplayerSynchronizer] 等方法将这个信息传播出去。"
+
+msgid ""
"Enables or disables physics (i.e. fixed framerate) processing. When a node is "
"being processed, it will receive a [constant NOTIFICATION_PHYSICS_PROCESS] at "
"a fixed (usually 60 FPS, see [member Engine.physics_ticks_per_second] to "
@@ -68647,6 +72135,9 @@ msgid ""
"Sets whether this is an instance load placeholder. See [InstancePlaceholder]."
msgstr "设置这是否是实例加载占位符。见 [InstancePlaceholder]。"
+msgid "Similar to [method call_thread_safe], but for setting properties."
+msgstr "类似于 [method call_thread_safe],但用于设置属性。"
+
msgid ""
"Updates the warning displayed for this node in the Scene Dock.\n"
"Use [method _get_configuration_warnings] to setup the warning message to "
@@ -68684,6 +72175,33 @@ msgstr ""
"code]。"
msgid ""
+"The node owner. A node can have any ancestor node as owner (i.e. a parent, "
+"grandparent, etc. node ascending in the tree). This implies that [method "
+"add_child] should be called before setting the owner, so that this "
+"relationship of parenting exists. When saving a node (using [PackedScene]), "
+"all the nodes it owns will be saved with it. This allows for the creation of "
+"complex scene trees, with instancing and subinstancing.\n"
+"[b]Note:[/b] If you want a child to be persisted to a [PackedScene], you must "
+"set [member owner] in addition to calling [method add_child]. This is "
+"typically relevant for [url=$DOCS_URL/tutorials/plugins/"
+"running_code_in_the_editor.html]tool scripts[/url] and [url=$DOCS_URL/"
+"tutorials/plugins/editor/index.html]editor plugins[/url]. If a new node is "
+"added to the tree without setting its owner as an ancestor in that tree, it "
+"will be visible in the 2D/3D view, but not in the scene tree (and not "
+"persisted when packing or saving)."
+msgstr ""
+"该节点的所有者。节点的所有者可以是任何祖先节点(即父节点、祖父节点等沿场景树向"
+"上的节点)。也就是说,应该在设置所有者之前调用 [method add_child],这样才能存"
+"在父子关系。(通过 [PackedScene])保存节点时,它拥有的所有节点也会随之保存。这"
+"样就可以创建复杂的场景树,能够进行实例化和子实例化。\n"
+"[b]注意:[/b]如果想要将子节点持久化进 [PackedScene],除了调用 [method "
+"add_child] 之外还必须设置 [member owner]。通常在[url=$DOCS_URL/tutorials/"
+"plugins/running_code_in_the_editor.html]工具脚本[/url]和[url=$DOCS_URL/"
+"tutorials/plugins/editor/index.html]编辑器插件[/url]中会用到。如果将新节点添加"
+"到了场景树中但没有将场景树中的祖先设置为所有者,那么这个节点在 2D/3D 视图中可"
+"见,但在场景树中不可见(也不会在打包或保存时进行持久化)。"
+
+msgid ""
"Can be used to pause or unpause the node, or make the node paused based on "
"the [SceneTree], or make it inherit the process mode from its parent "
"(default)."
@@ -68711,6 +72229,50 @@ msgstr ""
"值[i]较低[/i]的节点将首先执行其处理回调。"
msgid ""
+"Set the process thread group for this node (basically, whether it receives "
+"[constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS], "
+"[method _process] or [method _physics_process] (and the internal versions) on "
+"the main thread or in a sub-thread.\n"
+"By default, the thread group is [constant PROCESS_THREAD_GROUP_INHERIT], "
+"which means that this node belongs to the same thread group as the parent "
+"node. The thread groups means that nodes in a specific thread group will "
+"process together, separate to other thread groups (depending on [member "
+"process_thread_group_order]). If the value is set is [constant "
+"PROCESS_THREAD_GROUP_SUB_THREAD], this thread group will occur on a sub "
+"thread (not the main thread), otherwise if set to [constant "
+"PROCESS_THREAD_GROUP_MAIN_THREAD] it will process on the main thread. If "
+"there is not a parent or grandparent node set to something other than "
+"inherit, the node will belong to the [i]default thread group[/i]. This "
+"default group will process on the main thread and its group order is 0.\n"
+"During processing in a sub-thread, accessing most functions in nodes outside "
+"the thread group is forbidden (and it will result in an error in debug mode). "
+"Use [method Object.call_deferred], [method call_thread_safe], [method "
+"call_deferred_thread_group] and the likes in order to communicate from the "
+"thread groups to the main thread (or to other thread groups).\n"
+"To better understand process thread groups, the idea is that any node set to "
+"any other value than [constant PROCESS_THREAD_GROUP_INHERIT] will include any "
+"children (and grandchildren) nodes set to inherit into its process thread "
+"group. this means that the processing of all the nodes in the group will "
+"happen together, at the same time as the node including them."
+msgstr ""
+"设置这个节点的处理线程组(基本上就是在主线程还是子线程中接收 [constant "
+"NOTIFICATION_PROCESS]、[constant NOTIFICATION_PHYSICS_PROCESS]、[method "
+"_process]、[method _physics_process] 以及这些回调的内部版本)。\n"
+"默认情况下线程组为 [constant PROCESS_THREAD_GROUP_INHERIT],表示这个节点属于和"
+"父节点一样的线程组。同一线程组中的节点会一起处理,独立于其他线程组(由 "
+"[member process_thread_group_order] 决定)。如果设为 [constant "
+"PROCESS_THREAD_GROUP_SUB_THREAD],则该线程组会在子线程(非主线程)中执行,否则"
+"设为 [constant PROCESS_THREAD_GROUP_MAIN_THREAD] 就会在主线程中处理。如果父节"
+"点和先祖节点都没有设置为非继承,则该节点属于[i]默认线程组[/i]。默认分组在主线"
+"程中处理,分组顺序为 0。\n"
+"在子线程中处理时,线程组之外的大多数函数都禁止访问(调试模式下会报错)。请使"
+"用 [method Object.call_deferred]、[method call_thread_safe]、[method "
+"call_deferred_thread_group] 等方法与主线程(或其他线程组)通信。\n"
+"线程组更好的理解方式是,非 [constant PROCESS_THREAD_GROUP_INHERIT] 的节点都会"
+"将设为继承的子节点(以及后续子孙节点)纳入它的处理线程组。这样该分组中的节点就"
+"会一起处理,包括包含它们的节点。"
+
+msgid ""
"Change the process thread group order. Groups with a lesser order will "
"process before groups with a greater order. This is useful when a large "
"amount of nodes process in sub thread and, afterwards, another group wants to "
@@ -68788,6 +72350,17 @@ msgid "Emitted when the node is renamed."
msgstr "当该节点被重命名时触发。"
msgid ""
+"Emitted when this node is being replaced by the [param node], see [method "
+"replace_by].\n"
+"This signal is emitted [i]after[/i] [param node] has been added as a child of "
+"the original parent node, but [i]before[/i] all original child nodes have "
+"been reparented to [param node]."
+msgstr ""
+"当该节点被 [param node] 替换时触发,见 [method replace_by]。\n"
+"这个信号的触发时机在 [param node] 被添加为原父节点的子节点[i]之后[/i],但是在"
+"所有原子节点重设父节点为 [param node] [i]之前[/i]。"
+
+msgid ""
"Emitted when the node enters the tree.\n"
"This signal is emitted [i]after[/i] the related [constant "
"NOTIFICATION_ENTER_TREE] notification."
@@ -68894,6 +72467,12 @@ msgstr ""
"一个父节点时,[i]不会[/i]收到此通知。"
msgid ""
+"Notification received when the list of children is changed. This happens when "
+"child nodes are added, moved or removed."
+msgstr ""
+"子节点列表发生更改时收到的通知。子节点发生添加、移动、删除时列表会发生更改。"
+
+msgid ""
"Notification received every frame when the internal process flag is set (see "
"[method set_process_internal])."
msgstr ""
@@ -69128,15 +72707,6 @@ msgstr "所有 2D 演示"
msgid "Multiplies the current scale by the [param ratio] vector."
msgstr "将当前缩放乘以比例向量 [param ratio]。"
-msgid ""
-"Returns the angle between the node and the [param point] in radians.\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"node2d_get_angle_to.png]Illustration of the returned angle.[/url]"
-msgstr ""
-"返回该节点和 [param point] 之间的夹角,单位为弧度。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"node2d_get_angle_to.png]返回夹角的示意图。[/url]"
-
msgid "Returns the [Transform2D] relative to this node's parent."
msgstr "返回相对于此节点的父节点的 [Transform2D]。"
@@ -69222,7 +72792,7 @@ msgid ""
"to use degrees in a script, use [member rotation_degrees]."
msgstr ""
"以弧度为单位的旋转,相对于该节点的父节点。\n"
-"[b]注意:[/b] 这个属性在检查器中是以度数编辑的。如果你想在脚本中使用度数,请使"
+"[b]注意:[/b]这个属性在检查器中是以度数编辑的。如果你想在脚本中使用度数,请使"
"用 [member rotation_degrees]。"
msgid ""
@@ -69719,7 +73289,7 @@ msgstr ""
"径中其他命名节点的一个子节点。\n"
"通常只需将一个字符串传递给 [method Node.get_node],它将会被自动转换,但可能偶"
"尔想要使用 [NodePath] 或文字语法 [code]^\"path\"[/code] 提前解析路径。导出 "
-"[NodePath] 变量会在编辑器的属性面板中,为您提供一个节点选择小部件,这通常很有"
+"[NodePath] 变量会在编辑器的属性面板中,为你提供一个节点选择小部件,这通常很有"
"用。\n"
"[NodePath] 由斜线分隔的节点名称列表(如文件系统路径)和可选的冒号分隔的“子名"
"称”列表组成,这些“子名称”可以是资源或属性。\n"
@@ -69734,8 +73304,8 @@ msgstr ""
"^\"../..\" # 祖父节点。\n"
"# 前导斜杠意味着它是来自 SceneTree 的绝对路径。\n"
"^\"/root\" # 等同于 get_tree().get_root()。\n"
-"^\"/root/Main\" # 如果您的主场景的根节点被命名为“Main”。\n"
-"^\"/root/MyAutoload\" # 如果您有一个自动加载的节点或场景。\n"
+"^\"/root/Main\" # 如果你的主场景的根节点被命名为“Main”。\n"
+"^\"/root/MyAutoload\" # 如果你有一个自动加载的节点或场景。\n"
"[/codeblock]\n"
"另见 [StringName],它是通用字符串的类似概念。\n"
"[b]注意:[/b]在编辑器中,[NodePath] 属性在场景树中移动、重命名或删除节点时会自"
@@ -70016,7 +73586,7 @@ msgstr ""
"为不提供无缝噪声的库提供一个默认的 get_seamless_noise() 实现。该函数从 "
"get_image() 请求更大的图像,反转该图像的象限,然后使用额外宽度的条带在接缝处混"
"合。\n"
-"继承的噪声类可以选择性地重写该函数,以提供更优化的算法。"
+"继承的噪声类可以选择性地覆盖该函数,以提供更优化的算法。"
msgid ""
"Returns an [Image] containing 2D noise values.\n"
@@ -70121,6 +73691,19 @@ msgid ""
"value."
msgstr "[Gradient],用于将每个像素的亮度映射到一个颜色值。"
+msgid ""
+"Determines whether mipmaps are generated for this texture. Enabling this "
+"results in less texture aliasing in the distance, at the cost of increasing "
+"memory usage by roughly 33% and making the noise texture generation take "
+"longer.\n"
+"[b]Note:[/b] [member generate_mipmaps] requires mipmap filtering to be "
+"enabled on the material using the [NoiseTexture2D] to have an effect."
+msgstr ""
+"决定是否为该纹理生成 mipmap。启用该属性可减少纹理锯齿,但会增加约 33% 的内存占"
+"用,生成噪声纹理也可能需要更长的时间。\n"
+"[b]注意:[/b]使用该 [NoiseTexture2D] 的材质需要启用 mipmap 过滤才能让 [member "
+"generate_mipmaps] 生效。"
+
msgid "Height of the generated texture (in pixels)."
msgstr "生成的纹理的高度(单位为像素)。"
@@ -70401,7 +73984,7 @@ msgid ""
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
-"重写该方法以自定义 [method get] 的行为。应该返回给定的 [param property] 的值,"
+"覆盖该方法以自定义 [method get] 的行为。应该返回给定的 [param property] 的值,"
"或者 [param property] 应该被正常处理时返回 [code]null[/code]。\n"
"结合 [method _set] 和 [method _get_property_list],该方法允许定义自定义属性,"
"这对编辑器插件特别有用。请注意,属性必须存在于 [method get_property_list] 中,"
@@ -70535,7 +74118,7 @@ msgid ""
"[b]Note:[/b] If the object's script is not [annotation @GDScript.@tool], this "
"method will not be called in the editor."
msgstr ""
-"重写该方法以自定义引擎处理脚本属性的方式。\n"
+"覆盖该方法以自定义引擎处理脚本属性的方式。\n"
"应该返回一个属性列表,作为字典的 [Array]。该结果被添加到 [method "
"get_property_list] 的数组中,并且应该以相同的方式进行格式化。每个 "
"[Dictionary] 必须至少包含 [code]name[/code] 和 [code]type[/code] 条目。\n"
@@ -70694,7 +74277,7 @@ msgid ""
"[b]Note:[/b] This method must return consistently, regardless of the current "
"value of the [param property]."
msgstr ""
-"重写该方法以自定义给定 [param property] 的还原行为。如果 [param property] 可以"
+"覆盖该方法以自定义给定 [param property] 的还原行为。如果 [param property] 可以"
"在检查器停靠面板中恢复,则应该返回 [code]true[/code]。使用 [method "
"_property_get_revert] 来指定 [param property] 的默认值。\n"
"[b]注意:[/b]无论 [param property] 的当前值如何,该方法都必须始终如一地返回。"
@@ -70707,10 +74290,10 @@ msgid ""
"[b]Note:[/b] [method _property_can_revert] must also be overridden for this "
"method to be called."
msgstr ""
-"重写该方法以自定义给定 [param property] 的还原行为。应返回 [param property] 的"
+"覆盖该方法以自定义给定 [param property] 的还原行为。应返回 [param property] 的"
"默认值。如果默认值与 [param property] 的当前值不同,则检查器停靠面板中会显示一"
"个还原图标。\n"
-"[b]注意:[/b][method _property_can_revert] 也必须被重写,该方法才能被调用。"
+"[b]注意:[/b][method _property_can_revert] 也必须被覆盖,该方法才能被调用。"
msgid ""
"Override this method to customize the behavior of [method set]. Should set "
@@ -70760,7 +74343,7 @@ msgid ""
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
-"重写该方法以自定义 [method set] 的行为。应将 [param property] 设置为 [param "
+"覆盖该方法以自定义 [method set] 的行为。应将 [param property] 设置为 [param "
"value] 并返回 [code]true[/code],如果 [param property] 正常处理则返回 "
"[code]false[/code]。设置 [param property] 的[i]确切[/i]方式取决于该方法的实"
"现。\n"
@@ -70817,7 +74400,7 @@ msgid ""
" var a = str(self) # a is \"Welcome to Godot 4!\"\n"
"[/codeblock]"
msgstr ""
-"重写该方法以自定义 [method to_string] 的返回值,从而将对象表示为一个 "
+"覆盖该方法以自定义 [method to_string] 的返回值,从而将对象表示为一个 "
"[String]。\n"
"[codeblock]\n"
"func _to_string():\n"
@@ -72270,6 +75853,37 @@ msgstr ""
"是将它们移动到一个单独的可视层,并在 [member bake_mask] 中排除该层。"
msgid ""
+"The simplification distance to use for simplifying the generated occluder "
+"polygon (in 3D units). Higher values result in a less detailed occluder mesh, "
+"which improves performance but reduces culling accuracy.\n"
+"The occluder geometry is rendered on the CPU, so it is important to keep its "
+"geometry as simple as possible. Since the buffer is rendered at a low "
+"resolution, less detailed occluder meshes generally still work well. The "
+"default value is fairly aggressive, so you may have to decrease it if you run "
+"into false negatives (objects being occluded even though they are visible by "
+"the camera). A value of [code]0.01[/code] will act conservatively, and will "
+"keep geometry [i]perceptually[/i] unaffected in the occlusion culling buffer. "
+"Depending on the scene, a value of [code]0.01[/code] may still simplify the "
+"mesh noticeably compared to disabling simplification entirely.\n"
+"Setting this to [code]0.0[/code] disables simplification entirely, but "
+"vertices in the exact same position will still be merged. The mesh will also "
+"be re-indexed to reduce both the number of vertices and indices.\n"
+"[b]Note:[/b] This uses the [url=https://meshoptimizer.org/]meshoptimizer[/"
+"url] library under the hood, similar to LOD generation."
+msgstr ""
+"用于简化生成的遮挡物多边形的简化距离(单位为 3D 单位)。更高的值会导致遮挡物网"
+"格的细节更少,这会提高性能但会降低剔除精度。\n"
+"遮挡物几何体是在 CPU 上渲染的,因此保持其几何体尽可能简单很重要。由于缓冲区以"
+"低分辨率渲染,因此细节较少的遮挡网格通常仍能正常工作。默认值相当激进,因此如果"
+"遇到误报(即使相机可见的对象也被遮挡),可能必须降低该属性。[code]0.01[/code] "
+"的值将保守地起作用,并将保持几何体[i]感知[/i]在遮挡剔除缓冲区中不受影响。根据"
+"场景的不同,与完全禁用简化相比,[code]0.01[/code] 的值仍能显著简化网格。\n"
+"将该属性设置为 [code]0.0[/code] 将会完全禁用简化,但仍会合并位置完全相同的顶"
+"点。网格也将被重新索引以减少顶点和索引的数量。\n"
+"[b]注意:[/b]这在底层使用了 [url=https://meshoptimizer.org/]meshoptimizer[/"
+"url] 库,类似于 LOD 生成。"
+
+msgid ""
"The occluder resource for this [OccluderInstance3D]. You can generate an "
"occluder resource by selecting an [OccluderInstance3D] node then using the "
"[b]Bake Occluders[/b] button at the top of the editor.\n"
@@ -73669,7 +77283,7 @@ msgstr ""
"List_of_ISO_639-1_codes]语言代码[/url]作为字符串返回,该字符串应在所有平台上保"
"持一致。这相当于提取 [method get_locale] 字符串的 [code]language[/code] 部"
"分。\n"
-"当您不需要有关国家/地区代码或变体的附加信息时,这可用于将完全指定的区域设置字"
+"当你不需要有关国家/地区代码或变体的附加信息时,这可用于将完全指定的区域设置字"
"符串缩小为“通用”语言代码。例如,对于使用 [code]fr_CA[/code] 语言环境的加拿大法"
"语用户,这将返回 [code]fr[/code]。"
@@ -73952,7 +77566,7 @@ msgid ""
"application restarts."
msgstr ""
"返回当前线程的 ID。这可用于日志,以简化多线程应用程序的调试。\n"
-"[b]注意:[/b] 线程 ID 不是确定的,也许会在应用程序重新启动时被重复使用。"
+"[b]注意:[/b]线程 ID 不是确定的,也许会在应用程序重新启动时被重复使用。"
msgid ""
"Returns a string that is unique to the device.\n"
@@ -74077,6 +77691,28 @@ msgstr ""
"外的所有平台上都区分大小写。"
msgid ""
+"Returns [code]true[/code] if the feature for the given feature tag is "
+"supported in the currently running instance, depending on the platform, "
+"build, etc. Can be used to check whether you're currently running a debug "
+"build, on a certain platform or arch, etc. Refer to the [url=$DOCS_URL/"
+"tutorials/export/feature_tags.html]Feature Tags[/url] documentation for more "
+"details.\n"
+"[b]Note:[/b] Tag names are case-sensitive.\n"
+"[b]Note:[/b] On the web platform, one of the following additional tags is "
+"defined to indicate host platform: [code]web_android[/code], [code]web_ios[/"
+"code], [code]web_linuxbsd[/code], [code]web_macos[/code], or "
+"[code]web_windows[/code]."
+msgstr ""
+"如果当前运行的实例支持给定功能标签的功能,则返回 [code]true[/code],具体取决于"
+"平台、构建等。可用于检查当前是否正在运行调试构建,是否在某个平台或架构上,等"
+"等。请参阅[url=$DOCS_URL/tutorials/export/feature_tags.html]《功能标签》[/url]"
+"文档以了解更多详细信息。\n"
+"[b]注意:[/b]标签名称区分大小写。\n"
+"[b]注意:[/b]在 Web 平台上,会定义 [code]web_android[/code]、[code]web_ios[/"
+"code]、[code]web_linuxbsd[/code]、[code]web_macos[/code]、[code]web_windows[/"
+"code] 的其中之一,表示宿主平台。"
+
+msgid ""
"Returns [code]true[/code] if the Godot binary used to run the project is a "
"[i]debug[/i] export template, or when running in the editor.\n"
"Returns [code]false[/code] if the Godot binary used to run the project is a "
@@ -74217,6 +77853,16 @@ msgstr ""
"[code]RECORD_AUDIO[/code] 的权限。"
msgid ""
+"With this function, you can request dangerous permissions since normal "
+"permissions are automatically granted at install time in Android "
+"applications.\n"
+"[b]Note:[/b] This method is implemented only on Android."
+msgstr ""
+"你可以通过这个函数申请危险的权限,因为在 Android 应用程序中,正常的权限会在安"
+"装时自动授予。\n"
+"[b]注意:[/b]该方法仅在 Android 上实现。"
+
+msgid ""
"Sets the value of the environment variable [param variable] to [param value]. "
"The environment variable will be set for the Godot process and any process "
"executed with [method execute] after running [method set_environment]. The "
@@ -74309,6 +77955,29 @@ msgstr ""
"现。"
msgid ""
+"Requests the OS to open the file manager, then navigate to the given [param "
+"file_or_dir_path] and select the target file or folder.\n"
+"If [param file_or_dir_path] is a valid directory path, and [param "
+"open_folder] is [code]true[/code], the method will open the file manager and "
+"enter the target folder without selecting anything.\n"
+"Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] "
+"or [code]user://[/code] path into a system path for use with this method.\n"
+"[b]Note:[/b] Currently this method is only implemented on Windows and macOS. "
+"On other platforms, it will fallback to [method shell_open] with a directory "
+"path of [param file_or_dir_path] with prefix [code]file://[/code]."
+msgstr ""
+"请求操作系统打开文件管理器,然后导航至给定的文件或目录路径 [param "
+"file_or_dir_path] 并选中目标文件或文件夹。\n"
+"如果 [param file_or_dir_path] 为有效的目录路径,并且 [param open_folder] 为 "
+"[code]true[/code],则该方法会打开文件管理器并进入目标文件夹,不会选中任何东"
+"西。\n"
+"请使用 [method ProjectSettings.globalize_path] 将 [code]res://[/code] 和 "
+"[code]user://[/code] 路径转换为能够用于这个方法的文件系统路径。\n"
+"[b]注意:[/b]目前该方法仅在 Windows 和 macOS 上实现。在其他平台上会回退至使用"
+"前缀 [code]file://[/code] 的 [param file_or_dir_path] 目录路径调用 [method "
+"shell_open]。"
+
+msgid ""
"Removes the environment [param variable] from the current environment, if it "
"exists. The environment variable will be removed for the Godot process and "
"any process executed with [method execute] after running [method "
@@ -74531,6 +78200,30 @@ msgstr ""
"返回新的 [PackedByteArray],其中的数据已解压。请将 [param buffer_size] 设置为"
"数据解压后的大小。请将压缩模式设置为 [enum FileAccess.CompressionMode] 常量。"
+msgid ""
+"Returns a new [PackedByteArray] with the data decompressed. Set the "
+"compression mode using one of [enum FileAccess.CompressionMode]'s constants. "
+"[b]This method only accepts brotli, gzip, and deflate compression modes.[/b]\n"
+"This method is potentially slower than [code]decompress[/code], as it may "
+"have to re-allocate its output buffer multiple times while decompressing, "
+"whereas [code]decompress[/code] knows it's output buffer size from the "
+"beginning.\n"
+"GZIP has a maximal compression ratio of 1032:1, meaning it's very possible "
+"for a small compressed payload to decompress to a potentially very large "
+"output. To guard against this, you may provide a maximum size this function "
+"is allowed to allocate in bytes via [param max_output_size]. Passing -1 will "
+"allow for unbounded output. If any positive value is passed, and the "
+"decompression exceeds that amount in bytes, then an error will be returned."
+msgstr ""
+"返回新的 [PackedByteArray],其中的数据已解压。请将压缩模式设置为 [enum "
+"FileAccess.CompressionMode] 常量。[b]这个方法只接受 brotli、gzip 和 deflate 压"
+"缩模式。[/b]\n"
+"这个方法可能比 [code]decompress[/code] 慢,因为在解压时可能需要多次重新分配输"
+"出缓冲区,而 [code]decompress[/code] 则在一开始就知道输出缓冲区的大小。\n"
+"GZIP 的最大压缩率为 1032:1,这意味着较小的压缩后负载很有可能解压出非常巨大的输"
+"出。为了防止这种情况,你可以通过 [param max_output_size] 提供允许这个函数分配"
+"的最大字节数。传入 -1 则不限制输出。传入正数且解压超过该字节数时,会返回错误。"
+
msgid "Creates a copy of the array, and returns it."
msgstr "创建该数组的副本,并将该副本返回。"
@@ -75321,7 +79014,7 @@ msgstr ""
"[b]注意:[/b]该类型存储的是 32 位有符号整数,也就是说它可以取区间 [code]"
"[-2^31, 2^31 - 1][/code] 内的值,即 [code][-2147483648, 2147483647][/code]。超"
"过这些界限将环绕往复。相比之下,[int] 使用带符号的 64 位整数,可以容纳更大的"
-"值。如果您需要紧密存放 64 位整数,请参阅 [PackedInt64Array]。"
+"值。如果你需要紧密存放 64 位整数,请参阅 [PackedInt64Array]。"
msgid "Constructs an empty [PackedInt32Array]."
msgstr "构造空的 [PackedInt32Array]。"
@@ -75564,7 +79257,7 @@ msgstr ""
"场景文件的简化接口。提供可以对场景资源本身进行的操作和检查。\n"
"可以用来将某个节点保存到文件中。保存时,会将该节点和它所拥有的所有节点一起保存"
"(见 [member Node.owner] 属性)。\n"
-"[b]注意:[/b] 该节点不必自我拥有。\n"
+"[b]注意:[/b]该节点不必自我拥有。\n"
"[b]加载保存场景的示例:[/b]\n"
"[codeblocks]\n"
"[gdscript]\n"
@@ -76270,7 +79963,7 @@ msgstr ""
"包始终发送到连接的地址(不允许将来调用 [method set_dest_address])。该方法不会"
"向远程对等体发送任何数据,要发送数据,请像往常一样使用 [method PacketPeer."
"put_var] 或 [method PacketPeer.put_packet]。另请参阅 [UDPServer]。\n"
-"[b]注意:[/b]连接到远程对等体并不能防止 IP 欺骗等恶意攻击。如果您觉得您的应用"
+"[b]注意:[/b]连接到远程对等体并不能防止 IP 欺骗等恶意攻击。如果你觉得你的应用"
"程序正在传输敏感信息,可以考虑使用 TLS 或 DTLS 等加密技术。"
msgid ""
@@ -76344,6 +80037,76 @@ msgstr ""
"[b]注意:[/b]在向广播地址(例如:[code]255.255.255.255[/code])发送数据包之"
"前,必须启用 [method set_broadcast_enabled]。"
+msgid ""
+"Waits for a packet to arrive on the bound address. See [method bind].\n"
+"[b]Note:[/b] [method wait] can't be interrupted once it has been called. This "
+"can be worked around by allowing the other party to send a specific \"death "
+"pill\" packet like this:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"socket = PacketPeerUDP.new()\n"
+"# Server\n"
+"socket.set_dest_address(\"127.0.0.1\", 789)\n"
+"socket.put_packet(\"Time to stop\".to_ascii_buffer())\n"
+"\n"
+"# Client\n"
+"while socket.wait() == OK:\n"
+" var data = socket.get_packet().get_string_from_ascii()\n"
+" if data == \"Time to stop\":\n"
+" return\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var socket = new PacketPeerUDP();\n"
+"// Server\n"
+"socket.SetDestAddress(\"127.0.0.1\", 789);\n"
+"socket.PutPacket(\"Time to stop\".ToAsciiBuffer());\n"
+"\n"
+"// Client\n"
+"while (socket.Wait() == OK)\n"
+"{\n"
+" string data = socket.GetPacket().GetStringFromASCII();\n"
+" if (data == \"Time to stop\")\n"
+" {\n"
+" return;\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"等待数据包到达绑定的地址。见 [method bind]。\n"
+"[b]注意:[/b][method wait] 一旦被调用就无法中断。解决方法是让对方发送一个特定"
+"的“毒药”数据包,如下所示:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"socket = PacketPeerUDP.new()\n"
+"# 服务端\n"
+"socket.set_dest_address(\"127.0.0.1\", 789)\n"
+"socket.put_packet(\"Time to stop\".to_ascii_buffer())\n"
+"\n"
+"# 客户端\n"
+"while socket.wait() == OK:\n"
+" var data = socket.get_packet().get_string_from_ascii()\n"
+" if data == \"Time to stop\":\n"
+" return\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"var socket = new PacketPeerUDP();\n"
+"// 服务端\n"
+"socket.SetDestAddress(\"127.0.0.1\", 789);\n"
+"socket.PutPacket(\"Time to stop\".ToAsciiBuffer());\n"
+"\n"
+"// 客户端\n"
+"while (socket.Wait() == OK)\n"
+"{\n"
+" string data = socket.GetPacket().GetStringFromASCII();\n"
+" if (data == \"Time to stop\")\n"
+" {\n"
+" return;\n"
+" }\n"
+"}\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid "A GUI control that displays a [StyleBox]."
msgstr "显示 [StyleBox] 的 GUI 控件。"
@@ -76780,6 +80543,23 @@ msgid ""
msgstr "每个粒子的切向加速度将沿着这个 [CurveTexture] 变化。"
msgid ""
+"If [code]true[/code], enables turbulence for the particle system. Turbulence "
+"can be used to vary particle movement according to its position (based on a "
+"3D noise pattern). In 3D, [GPUParticlesAttractorVectorField3D] with "
+"[NoiseTexture3D] can be used as an alternative to turbulence that works in "
+"world space and with multiple particle systems reacting in the same way.\n"
+"[b]Note:[/b] Enabling turbulence has a high performance cost on the GPU. Only "
+"enable turbulence on a few particle systems at once at most, and consider "
+"disabling it when targeting mobile/web platforms."
+msgstr ""
+"如果为 [code]true[/code],则为粒子系统启用湍流。湍流可以(基于 3D 噪声图案)根"
+"据粒子的位置来改变粒子的移动。在 3D 中,可以用 "
+"[GPUParticlesAttractorVectorField3D] 和 [NoiseTexture3D] 作为世界空间湍流的平"
+"替,能够让不同粒子系统作出相同的反应。\n"
+"[b]注意:[/b]启用湍流对于 GPU 有较高的性能消耗。请最多只对少量粒子系统启用湍"
+"流,以移动/Web 平台作为目标时请考虑禁用湍流。"
+
+msgid ""
"Maximum turbulence influence on each particle.\n"
"The actual amount of turbulence influence on each particle is calculated as a "
"random value between [member turbulence_influence_min] and [member "
@@ -76809,6 +80589,30 @@ msgid ""
msgstr "每个粒子的湍流量,将在其生命周期内沿这条 [CurveTexture] 受到影响。"
msgid ""
+"Maximum displacement of each particle's spawn position by the turbulence.\n"
+"The actual amount of displacement will be a factor of the underlying "
+"turbulence multiplied by a random value between [member "
+"turbulence_initial_displacement_min] and [member "
+"turbulence_initial_displacement_max]."
+msgstr ""
+"湍流对每个粒子出生位置的最大位移。\n"
+"实际位移量将是基础湍流乘以一个介于 [member "
+"turbulence_initial_displacement_min] 和 [member "
+"turbulence_initial_displacement_max] 之间的随机值的系数。"
+
+msgid ""
+"Minimum displacement of each particle's spawn position by the turbulence.\n"
+"The actual amount of displacement will be a factor of the underlying "
+"turbulence multiplied by a random value between [member "
+"turbulence_initial_displacement_min] and [member "
+"turbulence_initial_displacement_max]."
+msgstr ""
+"湍流对每个粒子出生位置的最小位移。\n"
+"实际位移量将是基础湍流乘以一个介于 [member "
+"turbulence_initial_displacement_min] 和 [member "
+"turbulence_initial_displacement_max] 之间的随机值的系数。"
+
+msgid ""
"This value controls the overall scale/frequency of the turbulence noise "
"pattern.\n"
"A small scale will result in smaller features with more detail while a high "
@@ -76819,6 +80623,27 @@ msgstr ""
"声。"
msgid ""
+"A scrolling velocity for the turbulence field. This sets a directional trend "
+"for the pattern to move in over time.\n"
+"The default value of [code]Vector3(0, 0, 0)[/code] turns off the scrolling."
+msgstr ""
+"湍流场的滚动速度。设置的是图案随时间移动的方向趋势。\n"
+"默认值 [code]Vector3(0, 0, 0)[/code] 会将滚动关闭。"
+
+msgid ""
+"The in-place rate of change of the turbulence field. This defines how quickly "
+"the noise pattern varies over time.\n"
+"A value of 0.0 will result in a fixed pattern."
+msgstr ""
+"湍流场的原地变化率。会决定噪声图案随时间变化的快慢。\n"
+"值为 0.0 时得到的是固定的图案。"
+
+msgid ""
+"The turbulence noise strength. Increasing this will result in a stronger, "
+"more contrasting, flow pattern."
+msgstr "湍流噪声强度。增加此值将导致更强烈、对比度更高的噪声图案。"
+
+msgid ""
"Use with [method set_param_min], [method set_param_max], and [method "
"set_param_texture] to set initial velocity properties."
msgstr ""
@@ -77690,6 +81515,10 @@ msgid "The index of the [Bone2D] that this [PhysicalBone2D] should simulate."
msgstr "该 [PhysicalBone2D] 节点所模拟的 [Bone2D] 节点的索引。"
msgid ""
+"The [NodePath] to the [Bone2D] that this [PhysicalBone2D] should simulate."
+msgstr "该 [PhysicalBone2D] 所模拟的 [Bone2D] 的 [NodePath]。"
+
+msgid ""
"If [code]true[/code], the [PhysicalBone2D] will keep the transform of the "
"bone it is bound to when simulating physics."
msgstr ""
@@ -78850,6 +82679,29 @@ msgstr ""
"提供能够覆盖的虚方法,用于创建自定义的 [PhysicsDirectSpaceState3D] 实现。"
msgid ""
+"This class extends [PhysicsDirectSpaceState3D] by providing additional "
+"virtual methods that can be overridden. When these methods are overridden, "
+"they will be called instead of the internal methods of the physics server.\n"
+"Intended for use with GDExtension to create custom implementations of "
+"[PhysicsDirectSpaceState3D]."
+msgstr ""
+"这个类扩展自 [PhysicsDirectSpaceState3D],额外提供了可覆盖的虚方法。调用时会使"
+"用这些覆盖后的方法代替物理服务器中的内部方法。\n"
+"旨在用于 GDExtension,用于创建 [PhysicsDirectSpaceState3D] 的自定义实现。"
+
+msgid ""
+"Holds physics-related properties of a surface, namely its roughness and "
+"bounciness."
+msgstr "存放与表面的物理相关的属性,也就是粗糙度和反弹度。"
+
+msgid ""
+"Holds physics-related properties of a surface, namely its roughness and "
+"bounciness. This class is used to apply these properties to a physics body."
+msgstr ""
+"存放与表面的物理相关的属性,也就是粗糙度和反弹度。这个类用于将这些属性应用至物"
+"理体。"
+
+msgid ""
"If [code]true[/code], subtracts the bounciness from the colliding object's "
"bounciness instead of adding it."
msgstr ""
@@ -78877,6 +82729,14 @@ msgid ""
msgstr "为 [method PhysicsDirectSpaceState2D.intersect_point] 提供参数。"
msgid ""
+"By changing various properties of this object, such as the point position, "
+"you can configure the parameters for [method PhysicsDirectSpaceState2D."
+"intersect_point]."
+msgstr ""
+"通过修改这个对象的点位置等属性,你可以为 [method PhysicsDirectSpaceState2D."
+"intersect_point] 配置参数。"
+
+msgid ""
"If different from [code]0[/code], restricts the query to a specific canvas "
"layer specified by its instance ID. See [method Object.get_instance_id].\n"
"If [code]0[/code], restricts the query to the Viewport's default canvas layer."
@@ -78916,6 +82776,14 @@ msgid ""
"Provides parameters for [method PhysicsDirectSpaceState3D.intersect_point]."
msgstr "为 [method PhysicsDirectSpaceState3D.intersect_point] 提供参数。"
+msgid ""
+"By changing various properties of this object, such as the point position, "
+"you can configure the parameters for [method PhysicsDirectSpaceState3D."
+"intersect_point]."
+msgstr ""
+"通过修改这个对象的点位置等属性,你可以为 [method PhysicsDirectSpaceState3D."
+"intersect_point] 配置参数。"
+
msgid "If [code]true[/code], the query will take [Area3D]s into account."
msgstr "如果为 [code]true[/code],则查询将考虑 [Area3D]。"
@@ -78935,6 +82803,14 @@ msgid ""
msgstr "为 [method PhysicsDirectSpaceState2D.intersect_ray] 提供参数。"
msgid ""
+"By changing various properties of this object, such as the ray position, you "
+"can configure the parameters for [method PhysicsDirectSpaceState2D."
+"intersect_ray]."
+msgstr ""
+"通过修改这个对象的射线位置等属性,你可以为 [method PhysicsDirectSpaceState2D."
+"intersect_ray] 配置参数。"
+
+msgid ""
"Returns a new, pre-configured [PhysicsRayQueryParameters2D] object. Use it to "
"quickly create query parameters using the most common options.\n"
"[codeblock]\n"
@@ -78970,6 +82846,14 @@ msgid ""
msgstr "为 [method PhysicsDirectSpaceState3D.intersect_ray] 提供参数。"
msgid ""
+"By changing various properties of this object, such as the ray position, you "
+"can configure the parameters for [method PhysicsDirectSpaceState3D."
+"intersect_ray]."
+msgstr ""
+"通过修改这个对象的射线位置等属性,你可以为 [method PhysicsDirectSpaceState3D."
+"intersect_ray] 配置参数。"
+
+msgid ""
"Returns a new, pre-configured [PhysicsRayQueryParameters3D] object. Use it to "
"quickly create query parameters using the most common options.\n"
"[codeblock]\n"
@@ -79001,6 +82885,69 @@ msgstr ""
"如果为 [code]true[/code],查询会在从形状内部开始时检测到命中。在此情况下,碰撞"
"法线将为 [code]Vector3(0, 0, 0)[/code]。不会影响凹多边形形状和高度图形状。"
+msgid "A server interface for low-level 2D physics access."
+msgstr "用于访问低阶 2D 物理的服务器接口。"
+
+msgid ""
+"PhysicsServer2D is the server responsible for all 2D physics. It can directly "
+"create and manipulate all physics objects:\n"
+"- A [i]space[/i] is a self-contained world for a physics simulation. It "
+"contains bodies, areas, and joints. Its state can be queried for collision "
+"and intersection information, and several parameters of the simulation can be "
+"modified.\n"
+"- A [i]shape[/i] is a geometric shape such as a circle, a rectangle, a "
+"capsule, or a polygon. It can be used for collision detection by adding it to "
+"a body/area, possibly with an extra transformation relative to the body/"
+"area's origin. Bodies/areas can have multiple (transformed) shapes added to "
+"them, and a single shape can be added to bodies/areas multiple times with "
+"different local transformations.\n"
+"- A [i]body[/i] is a physical object which can be in static, kinematic, or "
+"rigid mode. Its state (such as position and velocity) can be queried and "
+"updated. A force integration callback can be set to customize the body's "
+"physics.\n"
+"- An [i]area[/i] is a region in space which can be used to detect bodies and "
+"areas entering and exiting it. A body monitoring callback can be set to "
+"report entering/exiting body shapes, and similarly an area monitoring "
+"callback can be set. Gravity and damping can be overridden within the area by "
+"setting area parameters.\n"
+"- A [i]joint[/i] is a constraint, either between two bodies or on one body "
+"relative to a point. Parameters such as the joint bias and the rest length of "
+"a spring joint can be adjusted.\n"
+"Physics objects in [PhysicsServer2D] may be created and manipulated "
+"independently; they do not have to be tied to nodes in the scene tree.\n"
+"[b]Note:[/b] All the 2D physics nodes use the physics server internally. "
+"Adding a physics node to the scene tree will cause a corresponding physics "
+"object to be created in the physics server. A rigid body node registers a "
+"callback that updates the node's transform with the transform of the "
+"respective body object in the physics server (every physics update). An area "
+"node registers a callback to inform the area node about overlaps with the "
+"respective area object in the physics server. The raycast node queries the "
+"direct state of the relevant space in the physics server."
+msgstr ""
+"PhysicsServer2D 是负责所有 2D 物理的服务器。它可以直接创建和操作所有物理对"
+"象:\n"
+"- [i]Space(空间)[/i]是用于物理仿真的自包含世界。它包含实体、区域和关节。可以"
+"对其状态进行查询,获取碰撞和相交信息,并且可以修改部分仿真参数。\n"
+"- [i]Shape(形状)[/i]是圆形、矩形、胶囊形、多边形等几何形状。加入到实体/区域"
+"中就可以用来进行碰撞检测,还可以带有相对于实体/区域原点的额外变换。实体/区域中"
+"可以添加多个(变换后的)形状,同一个形状可以使用不同的局部变换添加到实体/区域"
+"中。\n"
+"- [i]Body(实体)[/i]是物理对象,可以处于静态、运动学或刚性模式。可以对其状态"
+"进行查询和更新(例如位置、速度等)。可以设置力的集成回调,自定义实体的物理特"
+"性。\n"
+"- [i]Area(区域)[/i]是空间中的区块,可用于检测进入和离开它的实体和区域。可以"
+"设置实体的监视回调,报告进入/离开的实体形状,同样可以设置区域的监视回调。通过"
+"设置区域参数,可以在区域内覆盖重力和阻尼。\n"
+"- [i]Joint(关节)[/i]是两个实体之间或一个实体相对于某个点的约束。可以调整关节"
+"偏置和弹簧关节的放松长度等参数。\n"
+"[PhysicsServer2D] 中的物理对象可以独立创建和操作;不必将它们绑定到场景树中的节"
+"点。\n"
+"[b]注意:[/b]所有 2D 物理节点都在内部使用这个物理服务器。将物理节点添加到场景"
+"树,就会导致在物理服务器中创建相应的物理对象。刚体节点会注册回调,该回调会(在"
+"每次物理更新时)使用物理服务器中相应实体对象的变换更新该节点的变换。区域节点会"
+"注册回调,用来通知区域节点与物理服务器中相应区域对象的重叠。射线投射节点会查询"
+"物理服务器中相关空间的直接状态。"
+
msgid ""
"Adds a shape to the area, with the given local transform. The shape (together "
"with its [param transform] and [param disabled] properties) is added to an "
@@ -79846,6 +83793,62 @@ msgid "Returns the shape's type (see [enum ShapeType])."
msgstr "返回该形状的类型(见 [enum ShapeType])。"
msgid ""
+"Sets the shape data that defines the configuration of the shape. The [param "
+"data] to be passed depends on the shape's type (see [method "
+"shape_get_type]):\n"
+"- [constant SHAPE_WORLD_BOUNDARY]: an array of length two containing a "
+"[Vector2] [code]normal[/code] direction and a [code]float[/code] distance "
+"[code]d[/code],\n"
+"- [constant SHAPE_SEPARATION_RAY]: a dictionary containing the key "
+"[code]length[/code] with a [code]float[/code] value and the key "
+"[code]slide_on_slope[/code] with a [code]bool[/code] value,\n"
+"- [constant SHAPE_SEGMENT]: a [Rect2] [code]rect[/code] containing the first "
+"point of the segment in [code]rect.position[/code] and the second point of "
+"the segment in [code]rect.size[/code],\n"
+"- [constant SHAPE_CIRCLE]: a [code]float[/code] [code]radius[/code],\n"
+"- [constant SHAPE_RECTANGLE]: a [Vector2] [code]half_extents[/code],\n"
+"- [constant SHAPE_CAPSULE]: an array of length two (or a [Vector2]) "
+"containing a [code]float[/code] [code]height[/code] and a [code]float[/code] "
+"[code]radius[/code],\n"
+"- [constant SHAPE_CONVEX_POLYGON]: either a [PackedVector2Array] of points "
+"defining a convex polygon in counterclockwise order (the clockwise outward "
+"normal of each segment formed by consecutive points is calculated "
+"internally), or a [PackedFloat32Array] of length divisible by four so that "
+"every 4-tuple of [code]float[/code]s contains the coordinates of a point "
+"followed by the coordinates of the clockwise outward normal vector to the "
+"segment between the current point and the next point,\n"
+"- [constant SHAPE_CONCAVE_POLYGON]: a [PackedVector2Array] of length "
+"divisible by two (each pair of points forms one segment).\n"
+"[b]Warning:[/b] In the case of [constant SHAPE_CONVEX_POLYGON], this method "
+"does not check if the points supplied actually form a convex polygon (unlike "
+"the [member CollisionPolygon2D.polygon] property)."
+msgstr ""
+"设置定义形状配置的形状数据。要传递的 [param data] 取决于形状的类型(参见 "
+"[method shape_get_type]):\n"
+"- [constant SHAPE_WORLD_BOUNDARY]:长度为 2 的数组,包含 [Vector2] 类型的 "
+"[code]normal[/code] 方向和 [code]float[/code] 类型的距离 [code]d[/code],\n"
+"- [constant SHAPE_SEPARATION_RAY]:字典,包含键 [code]length[/code] 和 "
+"[code]float[/code] 值、以及键 [code]slide_on_slope[/code] 和 [code]bool[/"
+"code] 值,\n"
+"- [constant SHAPE_SEGMENT]:[Rect2] 类型的 [code]rect[/code],以 [code]rect."
+"position[/code] 表示线段中的第一个点,并以 [code]rect.size[/code] 表示线段中的"
+"第二个点,\n"
+"- [constant SHAPE_CIRCLE]:[code]float[/code] 类型的 [code]radius[/code],\n"
+"- [constant SHAPE_RECTANGLE]:[Vector2] 类型的 [code]half_extents[/code],\n"
+"- [constant SHAPE_CAPSULE]:长度为 2 的数组(或一个 [Vector2]),包含一个 "
+"[code]float[/code] 类型的 [code]height[/code] 和一个 [code]float[/code] 类型"
+"的 [code]radius[/code],\n"
+"- [constant SHAPE_CONVEX_POLYGON]:按逆时针顺序定义凸多边形的点的 "
+"[PackedVector2Array](在内部使用由连续点形成的每个线段的顺时针向外法线计算);"
+"或一个长度可被 4 整除的 [PackedFloat32Array],以便每个 4 元组的 [code]float[/"
+"code] 包含一个点的坐标,后跟一个向量的坐标表示,该向量是当前点和下一个点之间的"
+"线段的顺时针向外法向量,\n"
+"- [constant SHAPE_CONCAVE_POLYGON]:长度可被 2 整除的 [PackedVector2Array](每"
+"对点形成一个线段)。\n"
+"[b]警告:[/b]在 [constant SHAPE_CONVEX_POLYGON] 的情况下,该方法不检查提供的点"
+"是否能够形成凸多边形(与 [member CollisionPolygon2D.polygon] 属性不同)。"
+
+msgid ""
"Creates a 2D space in the physics server, and returns the [RID] that "
"identifies it. A space contains bodies and areas, and controls the stepping "
"of the physics simulation of the objects in it."
@@ -80412,10 +84415,38 @@ msgid ""
"Constant to get the number of space regions where a collision could occur."
msgstr "常量,用以获取可能发生碰撞的空间区域数。"
+msgid ""
+"Provides virtual methods that can be overridden to create custom "
+"[PhysicsServer2D] implementations."
+msgstr "提供覆盖后可以用来创建自定义 [PhysicsServer2D] 实现的虚方法。"
+
+msgid ""
+"This class extends [PhysicsServer2D] by providing additional virtual methods "
+"that can be overridden. When these methods are overridden, they will be "
+"called instead of the internal methods of the physics server.\n"
+"Intended for use with GDExtension to create custom implementations of "
+"[PhysicsServer2D]."
+msgstr ""
+"这个类扩展自 [PhysicsServer2D],提供可额外的可覆盖虚方法。覆盖这些方法后,就不"
+"会调用物理服务器内部方法,而是调用这些覆盖后的方法。\n"
+"旨在用于 GDExtension,用于创建自定义 [PhysicsServer2D] 实现。"
+
msgid "A singleton for managing [PhysicsServer2D] implementations."
msgstr "用于管理 [PhysicsServer2D] 实现的单例。"
msgid ""
+"[PhysicsServer2DManager] is the API for registering [PhysicsServer2D] "
+"implementations and for setting the default implementation.\n"
+"[b]Note:[/b] It is not possible to switch physics servers at runtime. This "
+"class is only used on startup at the server initialization level, by Godot "
+"itself and possibly by GDExtensions."
+msgstr ""
+"[PhysicsServer2DManager] 是用于注册 [PhysicsServer2D] 实现、设置默认实现的 "
+"API。\n"
+"[b]注意:[/b]无法在运行时切换物理服务器。这个类只在启动时在服务器初始化级别使"
+"用,可能由 Godot 本身使用,也可能由 GDExtension 使用。"
+
+msgid ""
"Register a [PhysicsServer2D] implementation by passing a [param name] and a "
"[Callable] that returns a [PhysicsServer2D] object."
msgstr ""
@@ -80430,11 +84461,74 @@ msgstr ""
"如果优先级 [param priority] 比当前默认实现的优先级高,则将由名称 [param name] "
"标识的 [PhysicsServer2D] 实现设置为默认实现。"
+msgid "A server interface for low-level 3D physics access."
+msgstr "用于访问低阶 3D 物理的服务器接口。"
+
+msgid ""
+"PhysicsServer2D is the server responsible for all 2D physics. It can directly "
+"create and manipulate all physics objects:\n"
+"- A [i]space[/i] is a self-contained world for a physics simulation. It "
+"contains bodies, areas, and joints. Its state can be queried for collision "
+"and intersection information, and several parameters of the simulation can be "
+"modified.\n"
+"- A [i]shape[/i] is a geometric shape such as a sphere, a box, a cylinder, or "
+"a polygon. It can be used for collision detection by adding it to a body/"
+"area, possibly with an extra transformation relative to the body/area's "
+"origin. Bodies/areas can have multiple (transformed) shapes added to them, "
+"and a single shape can be added to bodies/areas multiple times with different "
+"local transformations.\n"
+"- A [i]body[/i] is a physical object which can be in static, kinematic, or "
+"rigid mode. Its state (such as position and velocity) can be queried and "
+"updated. A force integration callback can be set to customize the body's "
+"physics.\n"
+"- An [i]area[/i] is a region in space which can be used to detect bodies and "
+"areas entering and exiting it. A body monitoring callback can be set to "
+"report entering/exiting body shapes, and similarly an area monitoring "
+"callback can be set. Gravity and damping can be overridden within the area by "
+"setting area parameters.\n"
+"- A [i]joint[/i] is a constraint, either between two bodies or on one body "
+"relative to a point. Parameters such as the joint bias and the rest length of "
+"a spring joint can be adjusted.\n"
+"Physics objects in [PhysicsServer3D] may be created and manipulated "
+"independently; they do not have to be tied to nodes in the scene tree.\n"
+"[b]Note:[/b] All the 3D physics nodes use the physics server internally. "
+"Adding a physics node to the scene tree will cause a corresponding physics "
+"object to be created in the physics server. A rigid body node registers a "
+"callback that updates the node's transform with the transform of the "
+"respective body object in the physics server (every physics update). An area "
+"node registers a callback to inform the area node about overlaps with the "
+"respective area object in the physics server. The raycast node queries the "
+"direct state of the relevant space in the physics server."
+msgstr ""
+"PhysicsServer3D 是负责所有 3D 物理的服务器。它可以直接创建和操作所有物理对"
+"象:\n"
+"- [i]Space(空间)[/i]是用于物理仿真的自包含世界。它包含实体、区域和关节。可以"
+"对其状态进行查询,获取碰撞和相交信息,并且可以修改部分仿真参数。\n"
+"- [i]Shape(形状)[/i]是球形、盒形、圆柱形、多边形等几何形状。加入到实体/区域"
+"中就可以用来进行碰撞检测,还可以带有相对于实体/区域原点的额外变换。实体/区域中"
+"可以添加多个(变换后的)形状,同一个形状可以使用不同的局部变换添加到实体/区域"
+"中。\n"
+"- [i]Body(实体)[/i]是物理对象,可以处于静态、运动学或刚性模式。可以对其状态"
+"进行查询和更新(例如位置、速度等)。可以设置力的集成回调,自定义实体的物理特"
+"性。\n"
+"- [i]Area(区域)[/i]是空间中的区块,可用于检测进入和离开它的实体和区域。可以"
+"设置实体的监视回调,报告进入/离开的实体形状,同样可以设置区域的监视回调。通过"
+"设置区域参数,可以在区域内覆盖重力和阻尼。\n"
+"- [i]Joint(关节)[/i]是两个实体之间或一个实体相对于某个点的约束。可以调整关节"
+"偏置和弹簧关节的放松长度等参数。\n"
+"[PhysicsServer3D] 中的物理对象可以独立创建和操作;不必将它们绑定到场景树中的节"
+"点。\n"
+"[b]注意:[/b]所有 3D 物理节点都在内部使用这个物理服务器。将物理节点添加到场景"
+"树,就会导致在物理服务器中创建相应的物理对象。刚体节点会注册回调,该回调会(在"
+"每次物理更新时)使用物理服务器中相应实体对象的变换更新该节点的变换。区域节点会"
+"注册回调,用来通知区域节点与物理服务器中相应区域对象的重叠。射线投射节点会查询"
+"物理服务器中相关空间的直接状态。"
+
msgid ""
"Adds a shape to the area, along with a transform matrix. Shapes are usually "
"referenced by their index, so you should track which shape has a given index."
msgstr ""
-"向区域添加一个形状,以及一个变换矩阵。形状通常通过它们的索引来引用,因此您应该"
+"向区域添加一个形状,以及一个变换矩阵。形状通常通过它们的索引来引用,因此你应该"
"跟踪哪个形状具有给定的索引。"
msgid ""
@@ -80549,7 +84643,7 @@ msgid ""
"Adds a shape to the body, along with a transform matrix. Shapes are usually "
"referenced by their index, so you should track which shape has a given index."
msgstr ""
-"添加一个形状到物体,以及一个变换矩阵。形状通常通过它们的索引来引用,因此您应该"
+"添加一个形状到物体,以及一个变换矩阵。形状通常通过它们的索引来引用,因此你应该"
"跟踪哪个形状具有给定的索引。"
msgid ""
@@ -81004,8 +85098,8 @@ msgstr "一旦超过极限,应用于滑块轴上移动的系数。越低,运
msgid ""
"The amount of restitution once the limits are surpassed. The lower, the more "
-"velocityenergy gets lost."
-msgstr "超过极限后的补偿。越低,动能损失越多。"
+"velocity-energy gets lost."
+msgstr "超出限制后的补偿。数值越低,损失的速度能量越多。"
msgid "The amount of damping once the slider limits are surpassed."
msgstr "一旦超过滑块的极限,阻尼的数量。"
@@ -81326,10 +85420,38 @@ msgstr ""
"常量,用于设置/获取接触和约束的求解器迭代次数。迭代次数越多,碰撞和约束就越准"
"确。然而,更多的迭代需要更多的 CPU 能力,这会降低性能。"
+msgid ""
+"Provides virtual methods that can be overridden to create custom "
+"[PhysicsServer3D] implementations."
+msgstr "提供覆盖后可以用来创建自定义 [PhysicsServer3D] 实现的虚方法。"
+
+msgid ""
+"This class extends [PhysicsServer3D] by providing additional virtual methods "
+"that can be overridden. When these methods are overridden, they will be "
+"called instead of the internal methods of the physics server.\n"
+"Intended for use with GDExtension to create custom implementations of "
+"[PhysicsServer3D]."
+msgstr ""
+"这个类扩展自 [PhysicsServer3D],提供可额外的可覆盖虚方法。覆盖这些方法后,就不"
+"会调用物理服务器内部方法,而是调用这些覆盖后的方法。\n"
+"旨在用于 GDExtension,用于创建自定义 [PhysicsServer3D] 实现。"
+
msgid "A singleton for managing [PhysicsServer3D] implementations."
msgstr "用于管理 [PhysicsServer3D] 实现的单例。"
msgid ""
+"[PhysicsServer3DManager] is the API for registering [PhysicsServer3D] "
+"implementations and for setting the default implementation.\n"
+"[b]Note:[/b] It is not possible to switch physics servers at runtime. This "
+"class is only used on startup at the server initialization level, by Godot "
+"itself and possibly by GDExtensions."
+msgstr ""
+"[PhysicsServer3DManager] 是用于注册 [PhysicsServer3D] 实现、设置默认实现的 "
+"API。\n"
+"[b]注意:[/b]无法在运行时切换物理服务器。这个类只在启动时在服务器初始化级别使"
+"用,可能由 Godot 本身使用,也可能由 GDExtension 使用。"
+
+msgid ""
"Register a [PhysicsServer3D] implementation by passing a [param name] and a "
"[Callable] that returns a [PhysicsServer3D] object."
msgstr ""
@@ -81345,6 +85467,13 @@ msgstr ""
"标识的 [PhysicsServer3D] 实现设置为默认实现。"
msgid ""
+"A class used to provide [method PhysicsServer3DExtension."
+"_soft_body_update_rendering_server] with a rendering handler for soft bodies."
+msgstr ""
+"用于为 [method PhysicsServer3DExtension._soft_body_update_rendering_server] 提"
+"供柔体渲染处理器的类。"
+
+msgid ""
"Provides parameters for [method PhysicsDirectSpaceState2D.intersect_shape]."
msgstr "为 [method PhysicsDirectSpaceState2D.intersect_shape] 提供参数。"
@@ -81527,6 +85656,13 @@ msgid "Provides parameters for [method PhysicsServer2D.body_test_motion]."
msgstr "为 [method PhysicsServer2D.body_test_motion] 提供参数。"
msgid ""
+"By changing various properties of this object, such as the motion, you can "
+"configure the parameters for [method PhysicsServer2D.body_test_motion]."
+msgstr ""
+"更改该对象的运动等属性可以配置 [method PhysicsServer2D.body_test_motion] 的参"
+"数。"
+
+msgid ""
"If set to [code]true[/code], shapes of type [constant PhysicsServer2D."
"SHAPE_SEPARATION_RAY] are used to detect collisions and can stop the motion. "
"Can be useful when snapping to the ground.\n"
@@ -81585,6 +85721,13 @@ msgid "Provides parameters for [method PhysicsServer3D.body_test_motion]."
msgstr "为 [method PhysicsServer3D.body_test_motion] 提供参数。"
msgid ""
+"By changing various properties of this object, such as the motion, you can "
+"configure the parameters for [method PhysicsServer3D.body_test_motion]."
+msgstr ""
+"更改该对象的运动等属性可以配置 [method PhysicsServer3D.body_test_motion] 的参"
+"数。"
+
+msgid ""
"If set to [code]true[/code], shapes of type [constant PhysicsServer3D."
"SHAPE_SEPARATION_RAY] are used to detect collisions and can stop the motion. "
"Can be useful when snapping to the ground.\n"
@@ -81633,6 +85776,11 @@ msgstr ""
"[CharacterBody3D] 提升地面吸附阶段的地面检测。\n"
"如果设置为 [code]false[/code],则只会汇报移动造成的碰撞,一般符合预期行为。"
+msgid ""
+"Describes the motion and collision result from [method PhysicsServer2D."
+"body_test_motion]."
+msgstr "描述 [method PhysicsServer2D.body_test_motion] 的运动和碰撞结果。"
+
msgid "Returns the colliding body's attached [Object], if a collision occurred."
msgstr "如果发生了碰撞,则返回相撞物体所附加的 [Object]。"
@@ -81687,6 +85835,11 @@ msgstr ""
"code] 之间。"
msgid ""
+"Describes the motion and collision result from [method PhysicsServer3D."
+"body_test_motion]."
+msgstr "描述 [method PhysicsServer3D.body_test_motion] 的运动和碰撞结果。"
+
+msgid ""
"Returns the colliding body's attached [Object] given a collision index (the "
"deepest collision by default), if a collision occurred."
msgstr ""
@@ -82659,7 +86812,7 @@ msgstr ""
"[param id],将从索引中创建一个。如果未提供 [param accel],则默认值 0(对应于 "
"[constant @GlobalScope.KEY_NONE])将被分配给该项(这意味着它不会有任何加速"
"器)。有关加速器的更多信息,请参阅 [method get_item_accelerator]。\n"
-"[b]注意:[/b] 可勾选项只显示一个勾选标记,但没有任何内置的勾选行为,必须手动勾"
+"[b]注意:[/b]可勾选项只显示一个勾选标记,但没有任何内置的勾选行为,必须手动勾"
"选/取消勾选。有关如何控制它的更多信息,请参阅 [method set_item_checked]。"
msgid ""
@@ -82926,7 +87079,7 @@ msgid ""
"with [method get_item_metadata], which provides a simple way of assigning "
"context data to items."
msgstr ""
-"设置项的元数据,该项可以是任何类型。稍后您可以使用[method get_item_metadata]获"
+"设置项的元数据,该项可以是任何类型。稍后你可以使用[method get_item_metadata]获"
"取它,它提供了一种将上下文数据分配给项的简单方法。"
msgid ""
@@ -84251,8 +88404,8 @@ msgstr ""
"项目名称。会在项目管理器和导出器中使用。可以通过翻译本地化文件中的值来翻译项目"
"名称。窗口标题将设置为在启动时自动匹配项目名称。\n"
"[b]注意:[/b]如果 [member application/config/use_custom_user_dir] 为 "
-"[code]false[/code],更改此值也会更改用户数据文件夹的路径。重命名项目后,您将无"
-"法再访问 [code]user://[/code] 中的现有数据,除非您重命名旧文件夹以匹配新项目名"
+"[code]false[/code],更改此值也会更改用户数据文件夹的路径。重命名项目后,你将无"
+"法再访问 [code]user://[/code] 中的现有数据,除非你重命名旧文件夹以匹配新项目名"
"称。有关更多信息,请参阅文档中的 [url=$DOCS_URL/tutorials/io/data_paths.html]"
"《数据路径》[/url]。"
@@ -84411,7 +88564,7 @@ msgid ""
"Forces a delay between frames in the main loop (in milliseconds). This may be "
"useful if you plan to disable vertical synchronization."
msgstr ""
-"强制主循环中帧之间的延迟(以毫秒为单位)。如果您计划禁用垂直同步,这可能很有"
+"强制主循环中帧之间的延迟(以毫秒为单位)。如果你计划禁用垂直同步,这可能很有"
"用。"
msgid ""
@@ -85164,7 +89317,7 @@ msgstr ""
msgid ""
"Color of the avoidance obstacles radius, visible when \"Visible Avoidance\" "
"is enabled in the Debug menu."
-msgstr "静态障碍物半径的颜色,在调试菜单中启用“显示避障”时可见。"
+msgstr "避障障碍物半径的颜色,在调试菜单中启用“显示避障”时可见。"
msgid ""
"Color of the static avoidance obstacles edges when their vertices are winded "
@@ -88795,7 +92948,7 @@ msgid ""
msgstr ""
"如果为 [code]true[/code],则启用空间过滤器以限制具有高频细节的区域的粗糙度。这"
"可以在一定程度上帮助减少镜面反射锯齿,尽管不如启用 [member rendering/"
-"anti_aliasing/quality/use_taa]。 该过滤器的性能成本很小,因此如果它对您的场景"
+"anti_aliasing/quality/use_taa]。 该过滤器的性能成本很小,因此如果它对你的场景"
"没有明显好处,请考虑禁用它。\n"
"[b]注意:[/b]屏幕空间粗糙度限制器只支持 Forward+ 和 Mobile 渲染方式,不支持 "
"Compatibility。\n"
@@ -89019,6 +93172,36 @@ msgstr ""
"ssil/adaptive_target] 设置。"
msgid ""
+"Scales the depth over which the subsurface scattering effect is applied. A "
+"high value may allow light to scatter into a part of the mesh or another mesh "
+"that is close in screen space but far in depth. See also [member rendering/"
+"environment/subsurface_scattering/subsurface_scattering_scale].\n"
+"[b]Note:[/b] This property is only read when the project starts. To set the "
+"subsurface scattering depth scale at runtime, call [method RenderingServer."
+"sub_surface_scattering_set_scale] instead."
+msgstr ""
+"对次表面散射效果应用深度进行缩放。较高的取值能够让灯光散射进网格的某些部分或者"
+"在屏幕空间中距离较近但深度更远的其他网格。另见 [member rendering/environment/"
+"subsurface_scattering/subsurface_scattering_scale]。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时设置次表面散射深度缩放,请"
+"改为调用 [method RenderingServer.sub_surface_scattering_set_scale]。"
+
+msgid ""
+"Sets the quality of the subsurface scattering effect. Higher values are "
+"slower but look nicer. This affects the rendering of materials that have "
+"[member BaseMaterial3D.subsurf_scatter_enabled] set to [code]true[/code], "
+"along with [ShaderMaterial]s that set [code]SSS_STRENGTH[/code].\n"
+"[b]Note:[/b] This property is only read when the project starts. To set the "
+"subsurface scattering quality at runtime, call [method RenderingServer."
+"sub_surface_scattering_set_quality] instead."
+msgstr ""
+"设置次表面散射效果的质量。值越高越慢,但视觉效果更佳。影响 [member "
+"BaseMaterial3D.subsurf_scatter_enabled] 为 [code]true[/code] 以及设置了 "
+"[code]SSS_STRENGTH[/code] 的 [ShaderMaterial] 的材质的渲染。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时设置次表面散射质量,请改为"
+"调用 [method RenderingServer.sub_surface_scattering_set_quality]。"
+
+msgid ""
"Scales the distance over which samples are taken for subsurface scattering "
"effect. Changing this does not impact performance, but higher values will "
"result in significant artifacts as the samples will become obviously spread "
@@ -89133,6 +93316,84 @@ msgstr ""
"为调用 [method RenderingServer.gi_set_use_half_resolution]。"
msgid ""
+"The number of frames to use for converging signed distance field global "
+"illumination. Higher values lead to a less noisy result, at the cost of "
+"taking a longer time to fully converge. This means the scene's global "
+"illumination will be too dark for a longer period of time, especially when "
+"the camera moves fast. The actual convergence speed depends on rendered "
+"framerate. For example, with the default setting of 30 frames, rendering at "
+"60 FPS will make SDFGI fully converge after 0.5 seconds. See also [member "
+"rendering/global_illumination/sdfgi/frames_to_update_lights] and [member "
+"rendering/global_illumination/sdfgi/probe_ray_count].\n"
+"[b]Note:[/b] This property is only read when the project starts. To control "
+"SDFGI convergence speed at runtime, call [method RenderingServer."
+"environment_set_sdfgi_frames_to_converge] instead."
+msgstr ""
+"用于收敛带符号距离场全局光照的帧数。值越高,得到的噪点越少,但完全收敛所需的时"
+"间也就越长。这意味着场景的全局光照处于过暗状态的时间可能更长,在相机快速移动时"
+"尤为明显。实际的收敛速度取决于渲染帧率。例如,默认设置为 30 帧,则 60 FPS 的渲"
+"染会让 SDFGI 在 0.5 秒后完全收敛。另见 [member rendering/global_illumination/"
+"sdfgi/frames_to_update_lights] 和 [member rendering/global_illumination/sdfgi/"
+"probe_ray_count]。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时控制 SDFGI 的收敛速度,请改"
+"为调用 [method RenderingServer.environment_set_sdfgi_frames_to_converge]。"
+
+msgid ""
+"The number of frames over which dynamic lights should be updated in signed "
+"distance field global illumination. Higher values take more time to update "
+"indirect lighting coming from dynamic lights, but result in better "
+"performance when many dynamic lights are present. See also [member rendering/"
+"global_illumination/sdfgi/frames_to_converge] and [member rendering/"
+"global_illumination/sdfgi/probe_ray_count].\n"
+"[b]Note:[/b] This only affects [Light3D] nodes whose [member Light3D."
+"light_bake_mode] is [constant Light3D.BAKE_DYNAMIC] (which is the default). "
+"Consider making non-moving lights use the [constant Light3D.BAKE_STATIC] bake "
+"mode to improve performance.\n"
+"[b]Note:[/b] This property is only read when the project starts. To control "
+"SDFGI light update speed at runtime, call [method RenderingServer."
+"environment_set_sdfgi_frames_to_update_light] instead."
+msgstr ""
+"带符号距离场全局光照中动态光照更新所需的帧数。值越高,动态灯光造成的间接光照就"
+"会花费更多的时间来更新,但动态灯光数量较多时性能会更好。另见 [member "
+"rendering/global_illumination/sdfgi/frames_to_converge] 和 [member rendering/"
+"global_illumination/sdfgi/probe_ray_count]。\n"
+"[b]注意:[/b]仅影响 [member Light3D.light_bake_mode] 为 [constant Light3D."
+"BAKE_DYNAMIC](默认值)的 [Light3D] 节点。让不会移动的灯光使用 [constant "
+"Light3D.BAKE_STATIC] 烘焙模式能够提升性能。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时控制 SDFGI 的灯光更新速度,"
+"请改为调用 [method RenderingServer."
+"environment_set_sdfgi_frames_to_update_light]。"
+
+msgid ""
+"The number of rays to throw per frame when computing signed distance field "
+"global illumination. Higher values lead to a less noisy result, at the cost "
+"of performance. See also [member rendering/global_illumination/sdfgi/"
+"frames_to_converge] and [member rendering/global_illumination/sdfgi/"
+"frames_to_update_lights].\n"
+"[b]Note:[/b] This property is only read when the project starts. To control "
+"SDFGI quality at runtime, call [method RenderingServer."
+"environment_set_sdfgi_ray_count] instead."
+msgstr ""
+"计算带符号距离场全局光照时每帧发出的射线。值越高,得到的噪点越少,但性能消耗也"
+"越大。另见 [member rendering/global_illumination/sdfgi/frames_to_converge] 和 "
+"[member rendering/global_illumination/sdfgi/frames_to_update_lights]。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时控制 SDFGI 的质量,请改为调"
+"用 [method RenderingServer.environment_set_sdfgi_ray_count]。"
+
+msgid ""
+"The VoxelGI quality to use. High quality leads to more precise lighting and "
+"better reflections, but is slower to render. This setting does not affect the "
+"baked data and doesn't require baking the [VoxelGI] again to apply.\n"
+"[b]Note:[/b] This property is only read when the project starts. To control "
+"VoxelGI quality at runtime, call [method RenderingServer."
+"voxel_gi_set_quality] instead."
+msgstr ""
+"要使用的 VoxelGI 质量。高质量下的光照更精确、反射质量更好,但渲染速度较慢。这"
+"个设置不影响烘焙数据,应用时不需要重新烘焙 [VoxelGI]。\n"
+"[b]注意:[/b]这个属性仅在项目启动时读取。要在运行时控制 VoxelGI 的质量,请改为"
+"调用 [method RenderingServer.voxel_gi_set_quality]。"
+
+msgid ""
"The maximum number of rays that can be thrown per pass when baking lightmaps "
"with [LightmapGI]. Depending on the scene, adjusting this value may result in "
"higher GPU utilization when baking lightmaps, leading to faster bake times."
@@ -89232,6 +93493,22 @@ msgstr ""
"照,但代价是当对象从明亮区域移动到阴影区域时可能会出现闪烁。"
msgid ""
+"Use 16 bits for the directional shadow depth map. Enabling this results in "
+"shadows having less precision and may result in shadow acne, but can lead to "
+"performance improvements on some devices."
+msgstr ""
+"使用 16 位的平行光阴影深度贴图。启用后,阴影的精度会降低,可能造成阴影失真,但"
+"能够在部分设备上提升性能。"
+
+msgid ""
+"The directional shadow's size in pixels. Higher values will result in sharper "
+"shadows, at the cost of performance. The value is rounded up to the nearest "
+"power of 2."
+msgstr ""
+"方向阴影的大小,单位为像素。值越高,得到的阴影越清晰,但会以性能为代价。取值将"
+"舍入到最接近的 2 次幂。"
+
+msgid ""
"Lower-end override for [member rendering/lights_and_shadows/"
"directional_shadow/size] on mobile devices, due to performance concerns or "
"driver support."
@@ -89272,6 +93549,14 @@ msgstr ""
"directional_shadow/soft_shadow_filter_quality] 以低配数值覆盖。"
msgid ""
+"Use 16 bits for the omni/spot shadow depth map. Enabling this results in "
+"shadows having less precision and may result in shadow acne, but can lead to "
+"performance improvements on some devices."
+msgstr ""
+"使用 16 位的全向灯/聚光灯阴影深度贴图。启用后,阴影的精度会降低,可能造成阴影"
+"失真,但能够在部分设备上提升性能。"
+
+msgid ""
"Subdivision quadrant size for shadow mapping. See shadow mapping "
"documentation."
msgstr "阴影贴图的细分象限大小。请参阅阴影映射文档。"
@@ -89618,6 +93903,11 @@ msgid "Windows override for [member rendering/rendering_device/driver]."
msgstr "[member rendering/rendering_device/driver] 在 Windows 的覆盖项。"
msgid ""
+"Determines at which interval pipeline cache is saved to disk. The lower the "
+"value, the more often it is saved."
+msgstr "决定管线缓存保存到磁盘的间隔。值越低,保存地越频繁。"
+
+msgid ""
"Determines how sharp the upscaled image will be when using the FSR upscaling "
"mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) "
"to 2.0. Values above 2.0 won't make a visible difference."
@@ -89832,6 +94122,55 @@ msgstr ""
"WebP。"
msgid ""
+"If [code]true[/code], the texture importer will import VRAM-compressed "
+"textures using the Ericsson Texture Compression 2 algorithm for lower quality "
+"textures and normal maps and Adaptable Scalable Texture Compression algorithm "
+"for high quality textures (in 4x4 block size).\n"
+"[b]Note:[/b] This setting is an override. The texture importer will always "
+"import the format the host platform needs, even if this is set to "
+"[code]false[/code].\n"
+"[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were "
+"already imported before. To make this setting apply to textures that were "
+"already imported, exit the editor, remove the [code].godot/imported/[/code] "
+"folder located inside the project folder then restart the editor (see [member "
+"application/config/use_hidden_project_data_directory])."
+msgstr ""
+"如果为 [code]true[/code],则纹理导入器,将使用 Ericsson 纹理压缩 2 算法导入 "
+"VRAM 压缩纹理以获取较低质量的纹理和法线贴图,并使用自适应可缩放纹理压缩算法导"
+"入高质量纹理(4x4 块大小)。\n"
+"[b]注意:[/b]这是设置覆盖项。即便设为 [code]false[/code],纹理导入器也始终会导"
+"入宿主平台所需的格式。\n"
+"[b]注意:[/b]更改该设置[i]不会[/i]影响之前已经导入的纹理。要使该设置应用于已导"
+"入的纹理,请退出编辑器,移除位于项目文件夹内的 [code].godot/imported/[/code] "
+"文件夹,然后重新启动编辑器(请参阅 [member application/config/"
+"use_hidden_project_data_directory])。"
+
+msgid ""
+"If [code]true[/code], the texture importer will import VRAM-compressed "
+"textures using the S3 Texture Compression algorithm (DXT1-5) for lower "
+"quality textures and the BPTC algorithm (BC6H and BC7) for high quality "
+"textures. This algorithm is only supported on PC desktop platforms and "
+"consoles.\n"
+"[b]Note:[/b] This setting is an override. The texture importer will always "
+"import the format the host platform needs, even if this is set to "
+"[code]false[/code].\n"
+"[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were "
+"already imported before. To make this setting apply to textures that were "
+"already imported, exit the editor, remove the [code].godot/imported/[/code] "
+"folder located inside the project folder then restart the editor (see [member "
+"application/config/use_hidden_project_data_directory])."
+msgstr ""
+"如果为 [code]true[/code],纹理导入器将使用 S3 纹理压缩算法(DXT1-5)导入 VRAM "
+"压缩纹理以获得较低质量的纹理;并使用 BPTC 算法(BC6H 和 BC7)导入高质量纹理。"
+"该算法仅在 PC 桌面平台和主机平台上受支持。\n"
+"[b]注意:[/b]这是设置覆盖项。即便设为 [code]false[/code],纹理导入器也始终会导"
+"入宿主平台所需的格式。\n"
+"[b]注意:[/b]更改该设置[i]不会[/i]影响之前已经导入的纹理。要使该设置应用于已导"
+"入的纹理,请退出编辑器,移除位于项目文件夹内的 [code].godot/imported/[/code] "
+"文件夹,然后重新启动编辑器(请参阅 [member application/config/"
+"use_hidden_project_data_directory])。"
+
+msgid ""
"The default compression method for WebP. Affects both lossy and lossless "
"WebP. A higher value results in smaller files at the cost of compression "
"speed. Decompression speed is mostly unaffected by the compression method. "
@@ -90316,6 +94655,9 @@ msgstr ""
"返回该 [Quaternion] 的负值。和写 [code]Quaternion(-q.x, -q.y, -q.z, -q.w)[/"
"code] 相同。这个操作得到的是代表相同旋转的四元数。"
+msgid "Provides methods for generating pseudo-random numbers."
+msgstr "提供生成伪随机数的方法。"
+
msgid ""
"RandomNumberGenerator is a class for generating pseudo-random numbers. It "
"currently uses [url=https://www.pcg-random.org/]PCG32[/url].\n"
@@ -90568,6 +94910,32 @@ msgid ""
msgstr "2D 空间中的射线,用于查找第一个相交的 [CollisionObject2D]。"
msgid ""
+"A raycast represents a ray from its origin to its [member target_position] "
+"that finds the closest [CollisionObject2D] along its path, if it intersects "
+"any. This is useful for a lot of things, such as\n"
+"[RayCast2D] can ignore some objects by adding them to an exception list, by "
+"making its detection reporting ignore [Area2D]s ([member collide_with_areas]) "
+"or [PhysicsBody2D]s ([member collide_with_bodies]), or by configuring physics "
+"layers.\n"
+"[RayCast2D] calculates intersection every physics frame, and it holds the "
+"result until the next physics frame. For an immediate raycast, or if you want "
+"to configure a [RayCast2D] multiple times within the same physics frame, use "
+"[method force_raycast_update].\n"
+"To sweep over a region of 2D space, you can approximate the region with "
+"multiple [RayCast2D]s or use [ShapeCast2D]."
+msgstr ""
+"Raycast 代表的是从它的原点到 [member target_position] 的射线,如果与碰撞对象相"
+"交,就能找到路径上距离最近的 [CollisionObject2D]。可以用来做很多事情,例如\n"
+"要让 [RayCast2D] 忽略某些对象,可以将它们加入例外列表,也可以让检测汇报忽略 "
+"[Area2D]([member collide_with_areas])或 [PhysicsBody2D]([member "
+"collide_with_bodies]),还可以配置物理层。\n"
+"[RayCast2D] 每一个物理帧都会计算是否相交,计算结果会保留到下一个物理帧。如果要"
+"立即执行射线投射,或者你想要在同一个物理帧内多次配置 [RayCast2D],请使用 "
+"[method force_raycast_update]。\n"
+"要扫描 2D 空间中的某个区域,可以使用多个 [RayCast2D] 去近似,也可以使用 "
+"[ShapeCast2D]。"
+
+msgid ""
"Adds a collision exception so the ray does not report collisions with the "
"specified [CollisionObject2D] node."
msgstr "添加碰撞例外,这样射线就不会报告与指定 [CollisionObject2D] 节点的碰撞。"
@@ -90687,6 +95055,32 @@ msgid ""
msgstr "3D 空间中的射线,用于查找第一个相交的 [CollisionObject3D]。"
msgid ""
+"A raycast represents a ray from its origin to its [member target_position] "
+"that finds the closest [CollisionObject3D] along its path, if it intersects "
+"any. This is useful for a lot of things, such as\n"
+"[RayCast3D] can ignore some objects by adding them to an exception list, by "
+"making its detection reporting ignore [Area3D]s ([member collide_with_areas]) "
+"or [PhysicsBody3D]s ([member collide_with_bodies]), or by configuring physics "
+"layers.\n"
+"[RayCast3D] calculates intersection every physics frame, and it holds the "
+"result until the next physics frame. For an immediate raycast, or if you want "
+"to configure a [RayCast3D] multiple times within the same physics frame, use "
+"[method force_raycast_update].\n"
+"To sweep over a region of 3D space, you can approximate the region with "
+"multiple [RayCast3D]s or use [ShapeCast3D]."
+msgstr ""
+"Raycast 代表的是从它的原点到 [member target_position] 的射线,如果与碰撞对象相"
+"交,就能找到路径上距离最近的 [CollisionObject3D]。可以用来做很多事情,例如\n"
+"要让 [RayCast3D] 忽略某些对象,可以将它们加入例外列表,也可以让检测汇报忽略 "
+"[Area3D]([member collide_with_areas])或 [PhysicsBody3D]([member "
+"collide_with_bodies]),还可以配置物理层。\n"
+"[RayCast3D] 每一个物理帧都会计算是否相交,计算结果会保留到下一个物理帧。如果要"
+"立即执行射线投射,或者你想要在同一个物理帧内多次配置 [RayCast3D],请使用 "
+"[method force_raycast_update]。\n"
+"要扫描 3D 空间中的某个区域,可以使用多个 [RayCast3D] 去近似,也可以使用 "
+"[ShapeCast3D]。"
+
+msgid ""
"Adds a collision exception so the ray does not report collisions with the "
"specified [CollisionObject3D] node."
msgstr "添加碰撞例外,这样射线就不会报告与指定 [CollisionObject3D] 节点的碰撞。"
@@ -90986,6 +95380,12 @@ msgstr ""
"BLEND_FACTOR_SRC_ALPHA],将 [member dst_alpha_blend_factor] 设为 [constant "
"RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA]。"
+msgid "The blend mode to use for the alpha channel."
+msgstr "Alpha 通道使用的混合模式。"
+
+msgid "The blend mode to use for the red/green/blue color channels."
+msgstr "红、绿、蓝通道使用的混合模式。"
+
msgid ""
"Controls how the blend factor for the alpha channel is determined based on "
"the destination's fragments."
@@ -90997,6 +95397,21 @@ msgid ""
msgstr "控制如何根据目标片段确定颜色通道的混合系数。"
msgid ""
+"If [code]true[/code], performs blending between the source and destination "
+"according to the factors defined in [member src_color_blend_factor], [member "
+"dst_color_blend_factor], [member src_alpha_blend_factor] and [member "
+"dst_alpha_blend_factor]. The blend modes [member color_blend_op] and [member "
+"alpha_blend_op] are also taken into account, with [member write_r], [member "
+"write_g], [member write_b] and [member write_a] controlling the output."
+msgstr ""
+"如果为 [code]true[/code],则会根据 [member src_color_blend_factor]、[member "
+"dst_color_blend_factor]、[member src_alpha_blend_factor] 和 [member "
+"dst_alpha_blend_factor] 中定义的系数对来源和目标进行混合。同时也会考虑 "
+"[member color_blend_op] 和 [member alpha_blend_op] 混合模式,[member "
+"write_r]、[member write_g]、[member write_b] 和 [member write_a] 则控制的是输"
+"出。"
+
+msgid ""
"Controls how the blend factor for the alpha channel is determined based on "
"the source's fragments."
msgstr "控制如何根据来源片段确定 Alpha 通道的混合系数。"
@@ -91031,6 +95446,17 @@ msgstr ""
"[RDPipelineDepthStencilState] 控制的是在使用 [RenderingDevice] 对深度和模板进"
"行采样时,如何进行深度和模板的比较。"
+msgid ""
+"If [code]true[/code], enables depth testing which allows objects to be "
+"automatically occluded by other objects based on their depth. This also "
+"allows objects to be partially occluded by other objects. If [code]false[/"
+"code], objects will appear in the order they were drawn (like in Godot's 2D "
+"renderer)."
+msgstr ""
+"如果为 [code]true[/code],则会启用深度测试,能够让对象根据深度自动被其他对象遮"
+"挡。这样对象就能够被其他对象部分遮挡。如果为 [code]false[/code],则会按照绘制"
+"顺序显示(类似 Godot 的 2D 渲染器)。"
+
msgid "Pipeline multisample state (used by [RenderingDevice])."
msgstr "管线的多重采样状态(由 [RenderingDevice] 使用)。"
@@ -91043,6 +95469,55 @@ msgstr ""
"进行多重采样和超采样抗锯齿。"
msgid ""
+"If [code]true[/code], alpha to coverage is enabled. This generates a "
+"temporary coverage value based on the alpha component of the fragment's first "
+"color output. This allows alpha transparency to make use of multisample "
+"antialiasing."
+msgstr ""
+"如果为 [code]true[/code],则启用 Alpha 为覆盖面。此时会根据片段的第一个颜色输"
+"出的 Alpha 分量生成临时的覆盖值。这样就能够让 Alpha 透明使用多重采样抗锯齿。"
+
+msgid ""
+"If [code]true[/code], alpha is forced to either [code]0.0[/code] or "
+"[code]1.0[/code]. This allows hardening the edges of antialiased alpha "
+"transparencies. Only relevant if [member enable_alpha_to_coverage] is "
+"[code]true[/code]."
+msgstr ""
+"如果为 [code]true[/code],则会将 Alpha 强制为 [code]0.0[/code] 或 [code]1.0[/"
+"code]。这样就能够让 Alpha 透明抗锯齿后的边缘更锐利。仅在 [member "
+"enable_alpha_to_coverage] 为 [code]true[/code] 时有效。"
+
+msgid ""
+"If [code]true[/code], enables per-sample shading which replaces MSAA by SSAA. "
+"This provides higher quality antialiasing that works with transparent (alpha "
+"scissor) edges. This has a very high performance cost. See also [member "
+"min_sample_shading]. See the [url=https://registry.khronos.org/vulkan/"
+"specs/1.3-extensions/html/vkspec.html#primsrast-sampleshading]per-sample "
+"shading Vulkan documentation[/url] for more details."
+msgstr ""
+"如果为 [code]true[/code],则会启用逐样本着色,使用 SSAA 代替 MSAA。这样能够提"
+"供更高质量的抗锯齿,支持透明边缘(Alpha 裁剪)。性能消耗很高。另见 [member "
+"min_sample_shading]。详见[url=https://registry.khronos.org/vulkan/specs/1.3-"
+"extensions/html/vkspec.html#primsrast-sampleshading]逐样本着色 Vulkan 文档[/"
+"url]。"
+
+msgid ""
+"The multiplier of [member sample_count] that determines how many samples are "
+"performed for each fragment. Must be between [code]0.0[/code] and [code]1.0[/"
+"code] (inclusive). Only effective if [member enable_sample_shading] is "
+"[code]true[/code]. If [member min_sample_shading] is [code]1.0[/code], "
+"fragment invocation must only read from the coverage index sample. Tile image "
+"access must not be used if [member enable_sample_shading] is [i]not[/i] "
+"[code]1.0[/code]."
+msgstr ""
+"[member sample_count] 的乘数,决定每个片段执行多少次采样。必须在 [code]0.0[/"
+"code] 和 [code]1.0[/code] 之间(含端点)。仅在 [member enable_sample_shading] "
+"为 [code]true[/code] 时有效。如果 [member min_sample_shading] 为 [code]1.0[/"
+"code],则片段调用必须仅从覆盖索引样本中读取。如果 [member "
+"enable_sample_shading] [i]不是[/i] [code]1.0[/code],则不能对平铺图像进行访"
+"问。"
+
+msgid ""
"The number of MSAA samples (or SSAA samples if [member enable_sample_shading] "
"is [code]true[/code]) to perform. Higher values result in better "
"antialiasing, at the cost of performance."
@@ -91081,6 +95556,19 @@ msgid ""
"supported on all hardware."
msgstr "绘制线段时使用的线宽(单位为像素)。可能不是所有硬件都支持粗线段。"
+msgid ""
+"The number of control points to use when drawing a patch with tessellation "
+"enabled. Higher values result in higher quality at the cost of performance."
+msgstr ""
+"启用曲面细分绘制面片时,使用的控制点的数量。值越高,质量越高,但是性能开销也越"
+"高。"
+
+msgid ""
+"If [code]true[/code], performs wireframe rendering for triangles instead of "
+"flat or textured rendering."
+msgstr ""
+"如果为 [code]true[/code],则会为三角形进行线框渲染,不进行平面或纹理渲染。"
+
msgid "Pipeline specialization constant (used by [RenderingDevice])."
msgstr "管线特化常量(由 [RenderingDevice] 使用)。"
@@ -91097,15 +95585,89 @@ msgstr ""
"与此同时保持着色器能够在不同场合灵活运用。\n"
"这个对象由 [RenderingDevice] 使用。"
+msgid ""
+"The identifier of the specialization constant. This is a value starting from "
+"[code]0[/code] and that increments for every different specialization "
+"constant for a given shader."
+msgstr ""
+"特化常量的标识符。这个值从 [code]0[/code] 开始,给定着色器中每一个不同的特化常"
+"量都会将其递增。"
+
+msgid ""
+"The specialization constant's value. Only [bool], [int] and [float] types are "
+"valid for specialization constants."
+msgstr "特化常量的值。只有 [bool]、[int]、[float] 类型是有效的特化常量。"
+
msgid "Sampler state (used by [RenderingDevice])."
msgstr "采样器状态(由 [RenderingDevice] 使用)。"
msgid ""
+"Maximum anisotropy that can be used when sampling. Only effective if [member "
+"use_anisotropy] is [code]true[/code]. Higher values result in a sharper "
+"sampler at oblique angles, at the cost of performance (due to memory "
+"bandwidth). This value may be limited by the graphics hardware in use. Most "
+"graphics hardware only supports values up to [code]16.0[/code].\n"
+"If [member anisotropy_max] is [code]1.0[/code], forcibly disables anisotropy "
+"even if [member use_anisotropy] is [code]true[/code]."
+msgstr ""
+"采样时能够使用的最大各向异性。仅在 [member use_anisotropy] 为 [code]true[/"
+"code] 时有效。值越高,倾斜角度下得到的采样越锐利,但性能开销也越大(由于显存带"
+"宽的原因)。这个值可能受到使用的图形硬件的限制。大多数图形硬件最多仅支持 "
+"[code]16.0[/code]。\n"
+"如果 [member anisotropy_max] 为 [code]1.0[/code],则会强制禁用各向异性,即便 "
+"[member use_anisotropy] 为 [code]true[/code]。"
+
+msgid ""
+"The border color that will be returned when sampling outside the sampler's "
+"bounds and the [member repeat_u], [member repeat_v] or [member repeat_w] "
+"modes have repeating disabled."
+msgstr ""
+"对采样器范围外进行采样,并且 [member repeat_u]、[member repeat_v] 或 [member "
+"repeat_w] 的模式禁用了重复时,返回的边框颜色。"
+
+msgid ""
"The compare operation to use. Only effective if [member enable_compare] is "
"[code]true[/code]."
msgstr ""
"要使用的比较运算。仅在 [member enable_compare] 为 [code]true[/code] 时有效。"
+msgid ""
+"If [code]true[/code], returned values will be based on the comparison "
+"operation defined in [member compare_op]. This is a hardware-based approach "
+"and is therefore faster than performing this manually in a shader. For "
+"example, compare operations are used for shadow map rendering by comparing "
+"depth values from a shadow sampler."
+msgstr ""
+"如果为 [code]true[/code],则返回值基于 [member compare_op] 定义的比较运算。这"
+"种做法基于硬件,因此比手动在着色器中执行要快。例如,渲染阴影贴图时就会对阴影采"
+"样器的深度值进行比较运算。"
+
+msgid ""
+"The mipmap LOD bias to use. Positive values will make the sampler blurrier at "
+"a given distance, while negative values will make the sampler sharper at a "
+"given distance (at the risk of looking grainy). Recommended values are "
+"between [code]-0.5[/code] and [code]0.0[/code]. Only effective if the sampler "
+"has mipmaps available."
+msgstr ""
+"要使用的 mipmap LOD 偏置。正值会让采样器在给定距离处更模糊,而负值会让采样器在"
+"给定距离处更锐利(有可能看上去会很颗粒化)。推荐值在 [code]-0.5[/code] 到 "
+"[code]0.0[/code] 之间。仅在采样器的 mipmap 可用时有效。"
+
+msgid "The sampler's magnification filter."
+msgstr "采样器的放大过滤器。"
+
+msgid ""
+"The maximum mipmap LOD bias to display (lowest resolution). Only effective if "
+"the sampler has mipmaps available."
+msgstr ""
+"用于显示的最大 mipmap LOD 偏置(最低分辨率)。仅在采样器有 mipmap 可用时有效。"
+
+msgid ""
+"The minimum mipmap LOD bias to display (highest resolution). Only effective "
+"if the sampler has mipmaps available."
+msgstr ""
+"用于显示的最小 mipmap LOD 偏置(最高分辨率)。仅在采样器有 mipmap 可用时有效。"
+
msgid "The filtering method to use for mipmaps."
msgstr "Mipmap 使用的过滤方法。"
@@ -91165,6 +95727,14 @@ msgid ""
msgstr ""
"设置指定着色器版本 [param version] 要编译的 SPIR-V 字节码 [param bytecode]。"
+msgid ""
+"The base compilation error message, which indicates errors not related to a "
+"specific shader stage if non-empty. If empty, shader compilation is not "
+"necessarily successful (check [RDShaderSPIRV]'s error message members)."
+msgstr ""
+"基础编译错误消息,如果非空,表示与特定着色器阶段无关的错误。如果为空,着色器编"
+"译也不一定成功(请检查 [RDShaderSPIRV] 的各种错误消息成员)。"
+
msgid "Shader source code (used by [RenderingDevice])."
msgstr "着色器源代码(由 [RenderingDevice] 使用)。"
@@ -91227,6 +95797,22 @@ msgstr ""
"SPIR-V 中间表示,是 [RDShaderFile] 的一部分(由 [RenderingDevice] 使用)。"
msgid ""
+"[RDShaderSPIRV] represents a [RDShaderFile]'s [url=https://www.khronos.org/"
+"spir/]SPIR-V[/url] code for various shader stages, as well as possible "
+"compilation error messages. SPIR-V a low-level intermediate shader "
+"representation. This intermediate representation is not used directly by GPUs "
+"for rendering, but it can be compiled into binary shaders that GPUs can "
+"understand. Unlike compiled shaders, SPIR-V is portable across GPU models and "
+"driver versions.\n"
+"This object is used by [RenderingDevice]."
+msgstr ""
+"[RDShaderSPIRV] 代表 [RDShaderFile] 不同着色器阶段的 [url=https://www.khronos."
+"org/spir/]SPIR-V[/url] 代码,以及可能的编译错误消息。SPIR-V 是一种低阶着色器中"
+"间表示。这种中间表示无法用于 GPU 渲染,但可以编译为 GPU 能够理解的二进制着色"
+"器。与编译后的着色器不同,SPIR-V 可以在不同 GPU 型号以及驱动版本之间移植。\n"
+"这个对象由 [RenderingDevice] 使用。"
+
+msgid ""
"Equivalent to getting one of [member bytecode_compute], [member "
"bytecode_fragment], [member bytecode_tesselation_control], [member "
"bytecode_tesselation_evaluation], [member bytecode_vertex]."
@@ -91360,6 +95946,14 @@ msgstr "纹理的宽度(单位为像素)。"
msgid "Texture view (used by [RenderingDevice])."
msgstr "纹理视图(由 [RenderingDevice] 使用)。"
+msgid ""
+"Optional override for the data format to return sampled values in. The "
+"default value of [constant RenderingDevice.DATA_FORMAT_MAX] does not override "
+"the format."
+msgstr ""
+"对返回采样值数据格式的可选覆盖。默认值 [constant RenderingDevice."
+"DATA_FORMAT_MAX] 不会对格式进行覆盖。"
+
msgid "The channel to sample when sampling the alpha channel."
msgstr "对 Alpha 通道进行采样时采样的通道。"
@@ -91801,6 +96395,17 @@ msgstr ""
"内部引用减量计数器。只有在你真的知道你在做什么的时候才使用这个。\n"
"如果减量成功,返回 [code]true[/code],否则返回 [code]false[/code]。"
+msgid "A rectangle hint for designing UIs."
+msgstr "设计 UI 使用的矩形提示。"
+
+msgid ""
+"A rectangle box that displays only a colored border around its rectangle. It "
+"is used to visualize the extents of a [Control]."
+msgstr "仅在对应矩形周围上显示彩色边框的矩形框。用于将 [Control] 的范围可视化。"
+
+msgid "Sets the border color of the [ReferenceRect]."
+msgstr "设置该 [ReferenceRect] 的边框颜色。"
+
msgid ""
"Sets the border width of the [ReferenceRect]. The border grows both inwards "
"and outwards with respect to the rectangle box."
@@ -91857,7 +96462,7 @@ msgstr ""
"cull_mask] 内的所有对象,因此更新它们可能会非常昂贵。最好仅用重要的静态对象更"
"新一次,然后保持原样。\n"
"[b]注意:[/b]与 [VoxelGI] 和 SDFGI 不同,[ReflectionProbe] 仅从一个 "
-"[WorldEnvironment] 节点获取环境。如果您在一个 [Camera3D] 节点中指定了一个 "
+"[WorldEnvironment] 节点获取环境。如果你在一个 [Camera3D] 节点中指定了一个 "
"[Environment] 资源,它将被该 [ReflectionProbe] 忽略。这可能会导致 "
"[ReflectionProbe] 内的照明不正确。\n"
"[b]注意:[/b]反射探针仅支持 Forward+ 和 Mobile 渲染方法,不支持 "
@@ -91873,6 +96478,32 @@ msgid "Reflection probes"
msgstr "反射探针"
msgid ""
+"The custom ambient color to use within the [ReflectionProbe]'s box defined by "
+"its [member size]. Only effective if [member ambient_mode] is [constant "
+"AMBIENT_COLOR]."
+msgstr ""
+"[ReflectionProbe] 的大小为 [member size] 的框中使用的自定义环境光颜色。仅在 "
+"[member ambient_mode] 为 [constant AMBIENT_COLOR] 时有效。"
+
+msgid ""
+"The custom ambient color energy to use within the [ReflectionProbe]'s box "
+"defined by its [member size]. Only effective if [member ambient_mode] is "
+"[constant AMBIENT_COLOR]."
+msgstr ""
+"[ReflectionProbe] 的大小为 [member size] 的框中使用的自定义环境光颜色能量。仅"
+"在 [member ambient_mode] 为 [constant AMBIENT_COLOR] 时有效。"
+
+msgid ""
+"The ambient color to use within the [ReflectionProbe]'s box defined by its "
+"[member size]. The ambient color will smoothly blend with other "
+"[ReflectionProbe]s and the rest of the scene (outside the [ReflectionProbe]'s "
+"box defined by its [member size])."
+msgstr ""
+"[ReflectionProbe] 的大小为 [member size] 的框中使用的环境光颜色。环境光颜色会"
+"和其他 [ReflectionProbe] 和场景([ReflectionProbe] 的大小为 [member size] 的框"
+"之外)的其他部分进行平滑混合。"
+
+msgid ""
"If [code]true[/code], enables box projection. This makes reflections look "
"more correct in rectangle-shaped rooms by offsetting the reflection center "
"depending on the camera's location.\n"
@@ -91911,6 +96542,21 @@ msgid "If [code]true[/code], reflections will ignore sky contribution."
msgstr "如果为 [code]true[/code],则反射将忽略天空的贡献。"
msgid ""
+"The maximum distance away from the [ReflectionProbe] an object can be before "
+"it is culled. Decrease this to improve performance, especially when using the "
+"[constant UPDATE_ALWAYS] [member update_mode].\n"
+"[b]Note:[/b] The maximum reflection distance is always at least equal to the "
+"probe's extents. This means that decreasing [member max_distance] will not "
+"always cull objects from reflections, especially if the reflection probe's "
+"box defined by its [member size] is already large."
+msgstr ""
+"对象在被剔除之前可以距该 [ReflectionProbe] 的最大距离。减少它可以提高性能,尤"
+"其是在使用 [constant UPDATE_ALWAYS] 作为 [member update_mode] 时。\n"
+"[b]注意:[/b]最大反射距离始终至少等于探针的范围。这意味着减少 [member "
+"max_distance] 并不总是会从反射中剔除对象,尤其是在反射探针由 [member size] 定"
+"义的框已经很大的情况下。"
+
+msgid ""
"The automatic LOD bias to use for meshes rendered within the "
"[ReflectionProbe] (this is analog to [member Viewport.mesh_lod_threshold]). "
"Higher values will use less detailed versions of meshes that have LOD "
@@ -91984,6 +96630,25 @@ msgstr ""
"性能消耗也是显著的。因此,建议同一个场景中最多只使用一个 [constant "
"UPDATE_ALWAYS] 的 ReflectionProbe。其他用途请使用 [constant UPDATE_ONCE]。"
+msgid ""
+"Do not apply any ambient lighting inside the [ReflectionProbe]'s box defined "
+"by its [member size]."
+msgstr "不在 [ReflectionProbe] 的大小为 [member size] 的框内部应用环境光照。"
+
+msgid ""
+"Apply automatically-sourced environment lighting inside the "
+"[ReflectionProbe]'s box defined by its [member size]."
+msgstr ""
+"在 [ReflectionProbe] 的大小为 [member size] 的框内部应用自动来源的环境光照。"
+
+msgid ""
+"Apply custom ambient lighting inside the [ReflectionProbe]'s box defined by "
+"its [member size]. See [member ambient_color] and [member "
+"ambient_color_energy]."
+msgstr ""
+"在 [ReflectionProbe] 的大小为 [member size] 的框内部应用自定义环境光照。见 "
+"[member ambient_color] 和 [member ambient_color_energy]。"
+
msgid "Class for searching text for patterns using regular expressions."
msgstr "使用正则表达式搜索文本的类。"
@@ -92347,6 +97012,55 @@ msgstr "到远程节点的 [NodePath],相对于 RemoteTransform3D 在场景中
msgid "Abstraction for working with modern low-level graphics APIs."
msgstr "用于处理现代低阶图形 API 的抽象。"
+msgid ""
+"[RenderingDevice] is an abstraction for working with modern low-level "
+"graphics APIs such as Vulkan. Compared to [RenderingServer] (which works with "
+"Godot's own rendering subsystems), [RenderingDevice] is much lower-level and "
+"allows working more directly with the underlying graphics APIs. "
+"[RenderingDevice] is used in Godot to provide support for several modern low-"
+"level graphics APIs while reducing the amount of code duplication required. "
+"[RenderingDevice] can also be used in your own projects to perform things "
+"that are not exposed by [RenderingServer] or high-level nodes, such as using "
+"compute shaders.\n"
+"On startup, Godot creates a global [RenderingDevice] which can be retrieved "
+"using [method RenderingServer.get_rendering_device]. This global "
+"[RenderingDevice] performs drawing to the screen.\n"
+"[b]Local RenderingDevices:[/b] Using [method RenderingServer."
+"create_local_rendering_device], you can create \"secondary\" rendering "
+"devices to perform drawing and GPU compute operations on separate threads.\n"
+"[b]Note:[/b] [RenderingDevice] assumes intermediate knowledge of modern "
+"graphics APIs such as Vulkan, Direct3D 12, Metal or WebGPU. These graphics "
+"APIs are lower-level than OpenGL or Direct3D 11, requiring you to perform "
+"what was previously done by the graphics driver itself. If you have "
+"difficulty understanding the concepts used in this class, follow the "
+"[url=https://vulkan-tutorial.com/]Vulkan Tutorial[/url] or [url=https://"
+"vkguide.dev/]Vulkan Guide[/url]. It's recommended to have existing modern "
+"OpenGL or Direct3D 11 knowledge before attempting to learn a low-level "
+"graphics API.\n"
+"[b]Note:[/b] [RenderingDevice] is not available when running in headless mode "
+"or when using the Compatibility rendering method."
+msgstr ""
+"[RenderingDevice] 是用来使用 Vulkan 等现代低阶图形 API 的抽象。与(适用于 "
+"Godot 自有渲染子系统的)[RenderingServer] 相比,[RenderingDevice] 所处的层级更"
+"低,能够更加直接地使用底层图形 API。Godot 使用 [RenderingDevice] 来支持部分现"
+"代低阶图形 API,能够减少所需的重复代码。你也可以在自己的项目中使用 "
+"[RenderingDevice],从而执行 [RenderingServer] 和高阶节点未暴露的功能,例如使用"
+"计算着色器。\n"
+"启动时,Godot 会创建一个全局的 [RenderingDevice],可以使用 [method "
+"RenderingServer.get_rendering_device] 获取。这个全局的 [RenderingDevice] 进行"
+"的是屏幕绘图。\n"
+"[b]局部 RenderingDevice:[/b]你可以使用 [method RenderingServer."
+"create_local_rendering_device] 创建“次级”渲染设备,在单独的线程中进行渲染和 "
+"GPU 计算操作。\n"
+"[b]注意:[/b]使用 [RenderingDevice] 需要对 Vulkan、Direct3D 12、Metal 或 "
+"WebGPU 有中等水平的知识。这些图形 API 比 OpenGL 和 Direct3D 所处的层级更低,能"
+"够执行原本由图形驱动自己实现的功能。如果这个类中所使用的概念你理解起来有困难,"
+"请学习 [url=https://vulkan-tutorial.com/]Vulkan 教程[/url]或 [url=https://"
+"vkguide.dev/]Vulkan 指南[/url]。在尝试学习低阶图形 API 之前,建议先学习现代 "
+"OpenGL 或 Direct3D 11 相关的知识。\n"
+"[b]注意:[/b]使用无头模式运行或使用 Compatibility 渲染方法时,"
+"[RenderingDevice] 不可用。"
+
msgid "Using compute shaders"
msgstr "使用计算着色器"
@@ -92365,6 +97079,231 @@ msgstr ""
"返回指定 [param buffer] 中数据的副本,还可以设置 [param offset_bytes] 和 "
"[param size_bytes],仅复制缓冲区的某一部分。"
+msgid ""
+"Creates a timestamp marker with the specified [param name]. This is used for "
+"performance reporting with the [method get_captured_timestamp_cpu_time], "
+"[method get_captured_timestamp_gpu_time] and [method "
+"get_captured_timestamp_name] methods."
+msgstr ""
+"使用指定的名称 [param name] 创建时间戳标记。用于 [method "
+"get_captured_timestamp_cpu_time]、[method get_captured_timestamp_gpu_time]、"
+"[method get_captured_timestamp_name] 等方法的性能汇报。"
+
+msgid ""
+"Starts a list of compute commands created with the [code]compute_*[/code] "
+"methods. The returned value should be passed to other [code]compute_list_*[/"
+"code] functions.\n"
+"If [param allow_draw_overlap] is [code]true[/code], you may have one draw "
+"list running at the same time as one compute list. Multiple compute lists "
+"cannot be created at the same time; you must finish the previous compute list "
+"first using [method compute_list_end].\n"
+"A simple compute operation might look like this (code is not a complete "
+"example):\n"
+"[codeblock]\n"
+"var rd = RenderingDevice.new()\n"
+"var compute_list = rd.compute_list_begin()\n"
+"\n"
+"rd.compute_list_bind_compute_pipeline(compute_list, "
+"compute_shader_dilate_pipeline)\n"
+"rd.compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0)\n"
+"rd.compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1)\n"
+"\n"
+"for i in atlas_slices:\n"
+" rd.compute_list_set_push_constant(compute_list, push_constant, "
+"push_constant.size())\n"
+" rd.compute_list_dispatch(compute_list, group_size.x, group_size.y, "
+"group_size.z)\n"
+" # No barrier, let them run all together.\n"
+"\n"
+"rd.compute_list_end()\n"
+"[/codeblock]"
+msgstr ""
+"开始由 [code]compute_*[/code] 方法创建的计算命令列表。应该将返回值传递给其他 "
+"[code]compute_list_*[/code] 函数。\n"
+"如果 [param allow_draw_overlap] 为 [code]true[/code],就可以在执行绘图列表的同"
+"时执行计算列表。无法同时创建多个计算列表;你必须先使用 [method "
+"compute_list_end] 把之前的计算列表完成。\n"
+"简易的计算操作类似于下面这样(代码不是完整的示例):\n"
+"[codeblock]\n"
+"var rd = RenderingDevice.new()\n"
+"var compute_list = rd.compute_list_begin()\n"
+"\n"
+"rd.compute_list_bind_compute_pipeline(compute_list, "
+"compute_shader_dilate_pipeline)\n"
+"rd.compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0)\n"
+"rd.compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1)\n"
+"\n"
+"for i in atlas_slices:\n"
+" rd.compute_list_set_push_constant(compute_list, push_constant, "
+"push_constant.size())\n"
+" rd.compute_list_dispatch(compute_list, group_size.x, group_size.y, "
+"group_size.z)\n"
+" # 没有屏障,一起执行。\n"
+"\n"
+"rd.compute_list_end()\n"
+"[/codeblock]"
+
+msgid ""
+"Submits the compute list for processing on the GPU. This is the compute "
+"equivalent to [method draw_list_draw]."
+msgstr "将计算列表提交给 GPU 处理。相当于是计算版本的 [method draw_list_draw]。"
+
+msgid ""
+"Finishes a list of compute commands created with the [code]compute_*[/code] "
+"methods."
+msgstr "结束由 [code]compute_*[/code] 方法创建的计算命令列表。"
+
+msgid ""
+"Sets the push constant data to [param buffer] for the specified [param "
+"compute_list]. The shader determines how this binary data is used. The "
+"buffer's size in bytes must also be specified in [param size_bytes] (this can "
+"be obtained by calling the [method PackedByteArray.size] method on the passed "
+"[param buffer])."
+msgstr ""
+"为指定的 [param compute_list] 设置 [param buffer] 的推送常量数据。如何使用这个"
+"二进制数据由着色器决定。另外还必须在 [param size_bytes] 中指定缓冲的字节大小"
+"(可以通过对 [param buffer] 调用 [method PackedByteArray.size] 获取)。"
+
+msgid ""
+"Creates a new compute pipeline. It can be accessed with the RID that is "
+"returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"新建计算管线。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Returns [code]true[/code] if the compute pipeline specified by the [param "
+"compute_pipeline] RID is valid, [code]false[/code] otherwise."
+msgstr ""
+"如果由 [param compute_pipeline] RID 指定的计算管线有效,则返回 [code]true[/"
+"code],否则返回 [code]false[/code]。"
+
+msgid ""
+"Create a new local [RenderingDevice]. This is most useful for performing "
+"compute operations on the GPU independently from the rest of the engine."
+msgstr ""
+"新建局部 [RenderingDevice]。主要用于在 GPU 上执行计算操作,独立于引擎的其他部"
+"分。"
+
+msgid ""
+"Create a command buffer debug label region that can be displayed in third-"
+"party tools such as [url=https://renderdoc.org/]RenderDoc[/url]. All regions "
+"must be ended with a [method draw_command_end_label] call. When viewed from "
+"the linear series of submissions to a single queue, calls to [method "
+"draw_command_begin_label] and [method draw_command_end_label] must be matched "
+"and balanced.\n"
+"The [code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] Vulkan extension must be "
+"available and enabled for command buffer debug label region to work. See also "
+"[method draw_command_insert_label] and [method draw_command_end_label]."
+msgstr ""
+"创建命令缓冲调试标签区域,能够在 [url=https://renderdoc.org/]RenderDoc[/url] "
+"等第三方工具中显示。所有的区域都应该调用 [method draw_command_end_label] 结"
+"束。观察单个队列的线性提交序列时,[method draw_command_begin_label] 必须有与之"
+"对应的 [method draw_command_end_label]。\n"
+"Vulkan 扩展 [code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] 必须可用并启用,这"
+"样命令缓冲调试标签区域才能正常工作。另见 [method draw_command_insert_label] "
+"和 [method draw_command_end_label]。"
+
+msgid ""
+"Ends the command buffer debug label region started by a [method "
+"draw_command_begin_label] call."
+msgstr ""
+"结束命令缓冲调试标签区域,该区域由 [method draw_command_begin_label] 调用开"
+"启。"
+
+msgid ""
+"Inserts a command buffer debug label region in the current command buffer. "
+"Unlike [method draw_command_begin_label], this region should not be ended "
+"with a [method draw_command_end_label] call."
+msgstr ""
+"在当前的命令缓冲中插入命令缓冲调试标签区域。与 [method "
+"draw_command_begin_label] 不同,不应该调用 [method draw_command_end_label] 来"
+"结束这个区域。"
+
+msgid ""
+"Starts a list of raster drawing commands created with the [code]draw_*[/code] "
+"methods. The returned value should be passed to other [code]draw_list_*[/"
+"code] functions.\n"
+"Multiple draw lists cannot be created at the same time; you must finish the "
+"previous draw list first using [method draw_list_end].\n"
+"A simple drawing operation might look like this (code is not a complete "
+"example):\n"
+"[codeblock]\n"
+"var rd = RenderingDevice.new()\n"
+"var clear_colors = PackedColorArray([Color(0, 0, 0, 0), Color(0, 0, 0, 0), "
+"Color(0, 0, 0, 0)]\n"
+"var draw_list = rd.draw_list_begin(framebuffers[i], RenderingDevice."
+"INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_READ, RenderingDevice."
+"INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_DISCARD, clear_colors)\n"
+"\n"
+"# Draw opaque.\n"
+"rd.draw_list_bind_render_pipeline(draw_list, raster_pipeline)\n"
+"rd.draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0)\n"
+"rd.draw_list_set_push_constant(draw_list, raster_push_constant, "
+"raster_push_constant.size())\n"
+"rd.draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3)\n"
+"# Draw wire.\n"
+"rd.draw_list_bind_render_pipeline(draw_list, raster_pipeline_wire)\n"
+"rd.draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0)\n"
+"rd.draw_list_set_push_constant(draw_list, raster_push_constant, "
+"raster_push_constant.size())\n"
+"rd.draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3)\n"
+"\n"
+"rd.draw_list_end()\n"
+"[/codeblock]"
+msgstr ""
+"开始由 [code]draw_*[/code] 方法创建的栅格绘图命令列表。应该将返回值传递给其他 "
+"[code]draw_list_*[/code] 函数。\n"
+"无法同时创建多个绘图列表;你必须先使用 [method draw_list_end] 把之前的绘图列表"
+"完成。\n"
+"简易的绘图操作类似于下面这样(代码不是完整的示例):\n"
+"[codeblock]\n"
+"var rd = RenderingDevice.new()\n"
+"var clear_colors = PackedColorArray([Color(0, 0, 0, 0), Color(0, 0, 0, 0), "
+"Color(0, 0, 0, 0)]\n"
+"var draw_list = rd.draw_list_begin(framebuffers[i], RenderingDevice."
+"INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_READ, RenderingDevice."
+"INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_DISCARD, clear_colors)\n"
+"\n"
+"# 实心绘制。\n"
+"rd.draw_list_bind_render_pipeline(draw_list, raster_pipeline)\n"
+"rd.draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0)\n"
+"rd.draw_list_set_push_constant(draw_list, raster_push_constant, "
+"raster_push_constant.size())\n"
+"rd.draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3)\n"
+"# 线框绘制。\n"
+"rd.draw_list_bind_render_pipeline(draw_list, raster_pipeline_wire)\n"
+"rd.draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0)\n"
+"rd.draw_list_set_push_constant(draw_list, raster_push_constant, "
+"raster_push_constant.size())\n"
+"rd.draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3)\n"
+"\n"
+"rd.draw_list_end()\n"
+"[/codeblock]"
+
+msgid ""
+"High-level variant of [method draw_list_begin], with the parameters "
+"automtaically being adjusted for drawing onto the window specified by the "
+"[param screen] ID.\n"
+"[b]Note:[/b] Cannot be used with local RenderingDevices, as these don't have "
+"a screen. If called on a local RenderingDevice, [method "
+"draw_list_begin_for_screen] returns [constant INVALID_ID]."
+msgstr ""
+"[method draw_list_begin] 的高阶变体,会针对绘制到 [param screen] ID 指定的窗口"
+"上自动调整参数。\n"
+"[b]注意:[/b]局部 RenderingDevice 没有屏幕,所以无法使用。如果对局部 "
+"RenderingDevice 调用,[method draw_list_begin_for_screen] 会返回 [constant "
+"INVALID_ID]。"
+
+msgid ""
+"Variant of [method draw_list_begin] with support for multiple splits. The "
+"[param splits] parameter determines how many splits are created."
+msgstr ""
+"[method draw_list_begin] 的变体,支持多个拆分。[param splits] 参数决定创建多少"
+"拆分。"
+
msgid "Binds [param index_array] to the specified [param draw_list]."
msgstr "将 [param index_array] 绑定到指定的 [param draw_list]。"
@@ -92384,6 +97323,131 @@ msgid "Binds [param vertex_array] to the specified [param draw_list]."
msgstr "将 [param vertex_array] 绑定到指定的 [param draw_list]。"
msgid ""
+"Removes and disables the scissor rectangle for the specified [param "
+"draw_list]. See also [method draw_list_enable_scissor]."
+msgstr ""
+"为指定的 [param draw_list] 移除并禁用裁剪矩形。另见 [method "
+"draw_list_enable_scissor]。"
+
+msgid ""
+"Submits [param draw_list] for rendering on the GPU. This is the raster "
+"equivalent to [method compute_list_dispatch]."
+msgstr ""
+"将 [param draw_list] 提交给 GPU 渲染。相当于是栅格版本的 [method "
+"compute_list_dispatch]。"
+
+msgid ""
+"Creates a scissor rectangle and enables it for the specified [param "
+"draw_list]. Scissor rectangles are used for clipping by discarding fragments "
+"that fall outside a specified rectangular portion of the screen. See also "
+"[method draw_list_disable_scissor].\n"
+"[b]Note:[/b] The specified [param rect] is automatically intersected with the "
+"screen's dimensions, which means it cannot exceed the screen's dimensions."
+msgstr ""
+"创建裁剪矩形并为指定的 [param draw_list] 启用。裁剪矩形可以用来实现裁剪,会丢"
+"弃落在屏幕上指定矩形范围之外的片段。另见 [method "
+"draw_list_disable_scissor]。\n"
+"[b]注意:[/b]指定的 [param rect] 会自动与屏幕尺寸求交集,也就是说裁剪矩形无法"
+"超出屏幕的范围。"
+
+msgid ""
+"Finishes a list of raster drawing commands created with the [code]draw_*[/"
+"code] methods."
+msgstr "结束由 [code]draw_*[/code] 方法创建的栅格绘图命令列表。"
+
+msgid ""
+"Sets blend constants for the specified [param draw_list] to [param color]. "
+"Blend constants are used only if the graphics pipeline is created with "
+"[constant DYNAMIC_STATE_BLEND_CONSTANTS] flag set."
+msgstr ""
+"将指定 [param draw_list] 的混合常量设置为 [param color]。创建图形管线时设置了 "
+"[constant DYNAMIC_STATE_BLEND_CONSTANTS] 标志时才会使用混合常量。"
+
+msgid ""
+"Sets the push constant data to [param buffer] for the specified [param "
+"draw_list]. The shader determines how this binary data is used. The buffer's "
+"size in bytes must also be specified in [param size_bytes] (this can be "
+"obtained by calling the [method PackedByteArray.size] method on the passed "
+"[param buffer])."
+msgstr ""
+"为指定的 [param draw_list] 设置 [param buffer] 的推送常量数据。如何使用这个二"
+"进制数据由着色器决定。另外还必须在 [param size_bytes] 中指定缓冲的字节大小(可"
+"以通过对 [param buffer] 调用 [method PackedByteArray.size] 获取)。"
+
+msgid ""
+"Switches to the next draw pass and returns the split's ID. Equivalent to "
+"[method draw_list_switch_to_next_pass_split] with [code]splits[/code] set to "
+"[code]1[/code]."
+msgstr ""
+"切换到下一个绘制阶段并返回拆分 ID。等价于调用 [method "
+"draw_list_switch_to_next_pass_split] 时将 [code]splits[/code] 设为 [code]1[/"
+"code]。"
+
+msgid ""
+"Switches to the next draw pass, with the number of splits allocated specified "
+"in [param splits]. The return value is an array containing the ID of each "
+"split. For single-split usage, see [method draw_list_switch_to_next_pass]."
+msgstr ""
+"切换到下一个绘制阶段,分配的拆分数在 [param splits] 中指定。返回值是一个数组,"
+"包含各个拆分的 ID。如果使用的是单个拆分,请参阅 [method "
+"draw_list_switch_to_next_pass]。"
+
+msgid ""
+"Creates a new framebuffer. It can be accessed with the RID that is returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"新建帧缓冲。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Creates a new empty framebuffer. It can be accessed with the RID that is "
+"returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"新建空的帧缓冲。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Creates a new multipass framebuffer. It can be accessed with the RID that is "
+"returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"新建多阶段帧缓冲。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Creates a new framebuffer format with the specified [param attachments] and "
+"[param view_count]. Returns the new framebuffer's unique framebuffer format "
+"ID.\n"
+"If [param view_count] is greater than or equal to [code]2[/code], enables "
+"multiview which is used for VR rendering. This requires support for the "
+"Vulkan multiview extension."
+msgstr ""
+"新建帧缓冲格式,附件为 [param attachments]、视图数为 [param view_count]。返回"
+"的是新帧缓冲的唯一帧缓冲格式 ID。\n"
+"如果 [param view_count] 大于等于 [code]2[/code],则会针对 VR 渲染启用多视图。"
+"要求支持 Vulkan 的多视图扩展。"
+
+msgid ""
+"Creates a new empty framebuffer format with the specified number of [param "
+"samples] and returns its ID."
+msgstr "新建空的帧缓冲格式并返回其 ID,采样数为 [param samples]。"
+
+msgid ""
+"Creates a multipass framebuffer format with the specified [param "
+"attachments], [param passes] and [param view_count] and returns its ID. If "
+"[param view_count] is greater than or equal to [code]2[/code], enables "
+"multiview which is used for VR rendering. This requires support for the "
+"Vulkan multiview extension."
+msgstr ""
+"创建多阶段帧缓冲格式并返回其 ID,附件为 [param attachments]、阶段数为 [param "
+"passes]、视图数为 [param view_count]。如果 [param view_count] 大于等于 "
+"[code]2[/code],则会针对 VR 渲染启用多视图。要求支持 Vulkan 的多视图扩展。"
+
+msgid ""
"Returns the number of texture samples used for the given framebuffer [param "
"format] ID (returned by [method framebuffer_get_format])."
msgstr ""
@@ -92422,6 +97486,41 @@ msgstr ""
"[method full_barrier] 应该仅用于调试,因为对性能的影响极大。"
msgid ""
+"Returns the timestamp in CPU time for the rendering step specified by [param "
+"index] (in microseconds since the engine started). See also [method "
+"get_captured_timestamp_gpu_time] and [method capture_timestamp]."
+msgstr ""
+"返回渲染步骤的 CPU 时间戳(引擎启动后经过的毫秒数),渲染步骤由 [param index] "
+"指定。另见 [method get_captured_timestamp_gpu_time] 和 [method "
+"capture_timestamp]。"
+
+msgid ""
+"Returns the timestamp in GPU time for the rendering step specified by [param "
+"index] (in microseconds since the engine started). See also [method "
+"get_captured_timestamp_cpu_time] and [method capture_timestamp]."
+msgstr ""
+"返回渲染步骤的 GPU 时间戳(引擎启动后经过的毫秒数),渲染步骤由 [param index] "
+"指定。另见 [method get_captured_timestamp_cpu_time] 和 [method "
+"capture_timestamp]。"
+
+msgid ""
+"Returns the timestamp's name for the rendering step specified by [param "
+"index]. See also [method capture_timestamp]."
+msgstr ""
+"返回渲染步骤的时间戳的名称,渲染步骤由 [param index] 指定。另见 [method "
+"capture_timestamp]。"
+
+msgid ""
+"Returns the total number of timestamps (rendering steps) available for "
+"profiling."
+msgstr "返回能够进行性能分析的时间戳(渲染步骤)总数。"
+
+msgid ""
+"Returns the index of the last frame rendered that has rendering timestamps "
+"available for querying."
+msgstr "返回能够进行渲染时间戳查询的最后一个渲染帧的索引。"
+
+msgid ""
"Returns the name of the video adapter (e.g. \"GeForce GTX 1080/PCIe/SSE2\"). "
"Equivalent to [method RenderingServer.get_video_adapter_name]. See also "
"[method get_device_vendor_name]."
@@ -92431,6 +97530,17 @@ msgstr ""
"get_device_vendor_name]。"
msgid ""
+"Returns the universally unique identifier for the pipeline cache. This is "
+"used to cache shader files on disk, which avoids shader recompilations on "
+"subsequent engine runs. This UUID varies depending on the graphics card "
+"model, but also the driver version. Therefore, updating graphics drivers will "
+"invalidate the shader cache."
+msgstr ""
+"返回管线缓存的通用唯一标识符。用于将着色器文件缓存到磁盘,避免后续运行引擎时进"
+"行着色器的重新编译。这个 UUID 会根据显卡型号以及驱动版本的不同而不同。因此,更"
+"新图形驱动会使着色器缓存失效。"
+
+msgid ""
"Returns the vendor of the video adapter (e.g. \"NVIDIA Corporation\"). "
"Equivalent to [method RenderingServer.get_video_adapter_vendor]. See also "
"[method get_device_name]."
@@ -92439,6 +97549,16 @@ msgstr ""
"RenderingServer.get_video_adapter_vendor]。另见 [method get_device_name]。"
msgid ""
+"Returns the unique identifier of the driver [param resource] for the "
+"specified [param rid]. Some driver resource types ignore the specified [param "
+"rid] (see [enum DriverResource] descriptions). [param index] is always "
+"ignored but must be specified anyway."
+msgstr ""
+"返回指定 [param rid] 的驱动资源 [param resource] 的唯一标识符。部分驱动资源类"
+"型会忽略指定的 [param rid](说明见 [enum DriverResource])。[param index] 始终"
+"会被忽略,但仍然必须指定。"
+
+msgid ""
"Returns the frame count kept by the graphics API. Higher values result in "
"higher input lag, but with more consistent throughput. For the main "
"[RenderingDevice], frames are cycled (usually 3 with triple-buffered V-Sync "
@@ -92449,13 +97569,21 @@ msgstr ""
"部 [RenderingDevice] 只有 1 帧。"
msgid ""
+"Returns the memory usage in bytes corresponding to the given [param type]. "
+"When using Vulkan, these statistics are calculated by [url=https://github.com/"
+"GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator]Vulkan Memory Allocator[/url]."
+msgstr ""
+"返回与类型 [param type] 对应的内存用量,单位为字节。使用 Vulkan 时,会通过 "
+"[url=https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator]Vulkan "
+"Memory Allocator[/url] 计算这些统计信息。"
+
+msgid ""
"Creates a new index array. It can be accessed with the RID that is returned.\n"
"Once finished with your RID, you will want to free the RID using the "
"RenderingDevice's [method free_rid] method."
msgstr ""
"新建索引数组。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
msgid ""
"Creates a new index buffer. It can be accessed with the RID that is "
@@ -92464,8 +97592,19 @@ msgid ""
"RenderingDevice's [method free_rid] method."
msgstr ""
"新建索引缓冲。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Returns the value of the specified [param limit]. This limit varies depending "
+"on the current graphics hardware (and sometimes the driver version). If the "
+"given limit is exceeded, rendering errors will occur.\n"
+"Limits for various graphics hardware can be found in the [url=https://vulkan."
+"gpuinfo.org/]Vulkan Hardware Database[/url]."
+msgstr ""
+"返回指定 [param limit] 的值。这个极限值取决于当前的图形硬件(有时也和驱动版本"
+"有关)。如果超出了给定的极限,则会发生渲染错误。\n"
+"各种图形硬件的极限可以在 [url=https://vulkan.gpuinfo.org/]Vulkan 硬件数据库[/"
+"url]中找到。"
msgid ""
"Creates a new render pipeline. It can be accessed with the RID that is "
@@ -92474,8 +97613,14 @@ msgid ""
"RenderingDevice's [method free_rid] method."
msgstr ""
"新建渲染管线。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Returns [code]true[/code] if the render pipeline specified by the [param "
+"render_pipeline] RID is valid, [code]false[/code] otherwise."
+msgstr ""
+"如果由 [param render_pipeline] RID 指定的渲染管线有效则返回 [code]true[/"
+"code],否则返回 [code]false[/code]。"
msgid ""
"Creates a new sampler. It can be accessed with the RID that is returned.\n"
@@ -92483,8 +97628,7 @@ msgid ""
"RenderingDevice's [method free_rid] method."
msgstr ""
"新建采样器。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
msgid ""
"Returns [code]true[/code] if implementation supports using a texture of "
@@ -92506,6 +97650,99 @@ msgstr ""
"并返回 [constant INVALID_ID]。"
msgid ""
+"Returns the window height matching the graphics API context for the given "
+"window ID (in pixels). Despite the parameter being named [param screen], this "
+"returns the [i]window[/i] size. See also [method screen_get_width].\n"
+"[b]Note:[/b] Only the main [RenderingDevice] returned by [method "
+"RenderingServer.get_rendering_device] has a height. If called on a local "
+"[RenderingDevice], this method prints an error and returns [constant "
+"INVALID_ID]."
+msgstr ""
+"返回与给定窗口 ID 图形 API 上下文相匹配的窗口高度(单位为像素)。虽然参数的名"
+"字叫 [param screen],但返回的是[i]窗口[/i]的大小。另见 [method "
+"screen_get_width]。\n"
+"[b]注意:[/b]只有 [method RenderingServer.get_rendering_device] 返回的主 "
+"[RenderingDevice] 有高度。如果对局部 [RenderingDevice] 调用,则会输出错误并返"
+"回 [constant INVALID_ID]。"
+
+msgid ""
+"Returns the window width matching the graphics API context for the given "
+"window ID (in pixels). Despite the parameter being named [param screen], this "
+"returns the [i]window[/i] size. See also [method screen_get_height].\n"
+"[b]Note:[/b] Only the main [RenderingDevice] returned by [method "
+"RenderingServer.get_rendering_device] has a width. If called on a local "
+"[RenderingDevice], this method prints an error and returns [constant "
+"INVALID_ID]."
+msgstr ""
+"返回与给定窗口 ID 图形 API 上下文相匹配的窗口宽度(单位为像素)。虽然参数的名"
+"字叫 [param screen],但返回的是[i]窗口[/i]的大小。另见 [method "
+"screen_get_height]。\n"
+"[b]注意:[/b]只有 [method RenderingServer.get_rendering_device] 返回的主 "
+"[RenderingDevice] 有宽度。如果对局部 [RenderingDevice] 调用,则会输出错误并返"
+"回 [constant INVALID_ID]。"
+
+msgid ""
+"Sets the resource name for [param id] to [param name]. This is used for "
+"debugging with third-party tools such as [url=https://renderdoc."
+"org/]RenderDoc[/url].\n"
+"The following types of resources can be named: texture, sampler, vertex "
+"buffer, index buffer, uniform buffer, texture buffer, storage buffer, uniform "
+"set buffer, shader, render pipeline and compute pipeline. Framebuffers cannot "
+"be named. Attempting to name an incompatible resource type will print an "
+"error.\n"
+"[b]Note:[/b] Resource names are only set when the engine runs in verbose mode "
+"([method OS.is_stdout_verbose] = [code]true[/code]), or when using an engine "
+"build compiled with the [code]dev_mode=yes[/code] SCons option. The graphics "
+"driver must also support the [code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] "
+"Vulkan extension for named resources to work."
+msgstr ""
+"将 ID 为 [param id] 的资源名称设置为 [param name]。用于使用 [url=https://"
+"renderdoc.org/]RenderDoc[/url] 等第三方工具进行调试。\n"
+"可以为以下类型的资源命名:纹理、采样器、顶点缓冲、索引缓冲、uniform 缓冲、纹理"
+"缓冲、存储缓冲、uniform 集缓冲、着色器、渲染管线、计算管线。无法为帧缓冲命名。"
+"尝试为不兼容的资源类型命名会输出错误。\n"
+"[b]注意:[/b]引擎以详细模式运行时([method OS.is_stdout_verbose] = "
+"[code]true[/code]),或者使用 [code]dev_mode=yes[/code] SCons 选项编译引擎构建"
+"时,才会设置资源的名称。图形驱动也必须支持 Vulkan 扩展 "
+"[code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] 具名资源才能正常工作。"
+
+msgid ""
+"Compiles a binary shader from [param spirv_data] and returns the compiled "
+"binary data as a [PackedByteArray]. This compiled shader is specific to the "
+"GPU model and driver version used; it will not work on different GPU models "
+"or even different driver versions. See also [method "
+"shader_compile_spirv_from_source].\n"
+"[param name] is an optional human-readable name that can be given to the "
+"compiled shader for organizational purposes."
+msgstr ""
+"从 [param spirv_data] 编译二进制着色器,并将编译得到的二进制数据以 "
+"[PackedByteArray] 的形式返回。编译后的着色器与所使用的 GPU 型号和驱动版本对"
+"应;无法在不同的 GPU 型号甚至不同的驱动版本上正常工作。另见 [method "
+"shader_compile_spirv_from_source]。\n"
+"[param name] 是可选的人类可读名称,会给予编译后的着色器,方便组织。"
+
+msgid ""
+"Compiles a SPIR-V from the shader source code in [param shader_source] and "
+"returns the SPIR-V as a [RDShaderSPIRV]. This intermediate language shader is "
+"portable across different GPU models and driver versions, but cannot be run "
+"directly by GPUs until compiled into a binary shader using [method "
+"shader_compile_binary_from_spirv].\n"
+"If [param allow_cache] is [code]true[/code], make use of the shader cache "
+"generated by Godot. This avoids a potentially lengthy shader compilation step "
+"if the shader is already in cache. If [param allow_cache] is [code]false[/"
+"code], Godot's shader cache is ignored and the shader will always be "
+"recompiled."
+msgstr ""
+"将 [param shader_source] 中的着色器源代码编译为 [RDShaderSPIRV] 形式的 SPIR-"
+"V。这种中间语言的着色器可以在不同 GPU 型号和驱动版本之间移植,但无法直接在 "
+"GPU 上运行,需要先使用 [method shader_compile_binary_from_spirv] 编译为二进制"
+"着色器。\n"
+"如果 [param allow_cache] 为 [code]true[/code],则会使用 Godot 生成的着色器缓"
+"存。如果着色器已经在缓存中,这样就可能避免冗长的着色器编译步骤。[param "
+"allow_cache] 为 [code]false[/code],则会忽略 Godot 的着色器缓存,始终重新编译"
+"着色器。"
+
+msgid ""
"Creates a new shader instance from a binary compiled shader. It can be "
"accessed with the RID that is returned.\n"
"Once finished with your RID, you will want to free the RID using the "
@@ -92513,8 +97750,8 @@ msgid ""
"shader_compile_binary_from_spirv] and [method shader_create_from_spirv]."
msgstr ""
"根据二进制的已编译着色器创建新的着色器实例。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingDevice 的 [method free_rid] 静态方法进行释"
-"放。另见 [method shader_compile_binary_from_spirv] 和 [method "
+"RID 使用结束后,应该使用 RenderingDevice 的 [method free_rid] 方法进行释放。另"
+"见 [method shader_compile_binary_from_spirv] 和 [method "
"shader_create_from_spirv]。"
msgid ""
@@ -92525,11 +97762,118 @@ msgid ""
"shader_compile_spirv_from_source] and [method shader_create_from_bytecode]."
msgstr ""
"根据 SPIR-V 中间代码创建新的着色器实例。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingDevice 的 [method free_rid] 静态方法进行释"
-"放。另见 [method shader_compile_spirv_from_source] 和 [method "
+"RID 使用结束后,应该使用 RenderingDevice 的 [method free_rid] 方法进行释放。另"
+"见 [method shader_compile_spirv_from_source] 和 [method "
"shader_create_from_bytecode]。"
msgid ""
+"Creates a [url=https://vkguide.dev/docs/chapter-4/storage_buffers/]storage "
+"buffer[/url] with the specified [param data] and [param usage]. It can be "
+"accessed with the RID that is returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"创建带有指定数据 [param data] 用法为 [param usage] 的[url=https://vkguide.dev/"
+"docs/chapter-4/storage_buffers/]存储缓冲[/url]。可以通过返回的 RID 进行访"
+"问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Pushes the frame setup and draw command buffers then marks the local device "
+"as currently processing (which allows calling [method sync]).\n"
+"[b]Note:[/b] Only available in local RenderingDevices."
+msgstr ""
+"推送帧设置与绘图命令缓冲,然后将局部设备标记为当前正在处理(这样就能够调用 "
+"[method sync])。\n"
+"[b]注意:[/b]仅在局部 RenderingDevice 上可用。"
+
+msgid ""
+"Forces a synchronization between the CPU and GPU, which may be required in "
+"certain cases. Only call this when needed, as CPU-GPU synchronization has a "
+"performance cost.\n"
+"[b]Note:[/b] Only available in local RenderingDevices.\n"
+"[b]Note:[/b] [method sync] can only be called after a [method submit]."
+msgstr ""
+"让 CPU 与 GPU 进行强制同步,部分场合可能需要进行这样的操作。请只在需要时调用,"
+"因为 CPU 与 GPU 的同步存在性能开销。\n"
+"[b]注意:[/b]仅在局部 RenderingDevice 上可用。\n"
+"[b]注意:[/b]只能在 [method submit] 后调用 [method sync]。"
+
+msgid ""
+"Creates a new texture buffer. It can be accessed with the RID that is "
+"returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"新建纹理缓冲。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
+"Clears the specified [param texture] by replacing all of its pixels with the "
+"specified [param color]. [param base_mipmap] and [param mipmap_count] "
+"determine which mipmaps of the texture are affected by this clear operation, "
+"while [param base_layer] and [param layer_count] determine which layers of a "
+"3D texture (or texture array) are affected by this clear operation. For 2D "
+"textures (which only have one layer by design), [param base_layer] and [param "
+"layer_count] must both be [code]0[/code].\n"
+"[b]Note:[/b] [param texture] can't be cleared while a draw list that uses it "
+"as part of a framebuffer is being created. Ensure the draw list is finalized "
+"(and that the color/depth texture using it is not set to [constant "
+"FINAL_ACTION_CONTINUE]) to clear this texture."
+msgstr ""
+"将指定的 [param texture] 清屏,将所有像素替换为指定的颜色 [param color]。"
+"[param base_mipmap] 和 [param mipmap_count] 决定该清屏操作影响纹理的哪个 "
+"mipmap,而 [param base_layer] 和 [param layer_count] 决定该清屏操作影响 3D 纹"
+"理(或纹理数组)的哪一层。如果是 2D 纹理(本来就只有一层),则 [param "
+"base_layer] 和 [param layer_count] 必须都为 [code]0[/code]。\n"
+"[b]注意:[/b]如果使用 [param texture] 的绘图列表是创建的帧缓冲的一部分,则该纹"
+"理不能被清屏。绘图列表释放后(并且使用它的颜色和深度纹理没有被设为 [constant "
+"FINAL_ACTION_CONTINUE])才能对该纹理做清屏操作。"
+
+msgid ""
+"Copies the [param from_texture] to [param to_texture] with the specified "
+"[param from_pos], [param to_pos] and [param size] coordinates. The Z axis of "
+"the [param from_pos], [param to_pos] and [param size] must be [code]0[/code] "
+"for 2-dimensional textures. Source and destination mipmaps/layers must also "
+"be specified, with these parameters being [code]0[/code] for textures without "
+"mipmaps or single-layer textures. Returns [constant @GlobalScope.OK] if the "
+"texture copy was successful or [constant @GlobalScope.ERR_INVALID_PARAMETER] "
+"otherwise.\n"
+"[b]Note:[/b] [param from_texture] texture can't be copied while a draw list "
+"that uses it as part of a framebuffer is being created. Ensure the draw list "
+"is finalized (and that the color/depth texture using it is not set to "
+"[constant FINAL_ACTION_CONTINUE]) to copy this texture.\n"
+"[b]Note:[/b] [param from_texture] texture requires the [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT] to be retrieved.\n"
+"[b]Note:[/b] [param to_texture] can't be copied while a draw list that uses "
+"it as part of a framebuffer is being created. Ensure the draw list is "
+"finalized (and that the color/depth texture using it is not set to [constant "
+"FINAL_ACTION_CONTINUE]) to copy this texture.\n"
+"[b]Note:[/b] [param to_texture] requires the [constant "
+"TEXTURE_USAGE_CAN_COPY_TO_BIT] to be retrieved.\n"
+"[b]Note:[/b] [param from_texture] and [param to_texture] must be of the same "
+"type (color or depth)."
+msgstr ""
+"将 [param from_texture] 复制到 [param to_texture],使用指定的 [param "
+"from_pos]、[param to_pos] 和 [param size] 坐标。对于二维纹理,[param "
+"from_pos]、[param to_pos] 和 [param size] 的 Z 轴必须为 [code]0[/code]。来源和"
+"目标的 mipmap/图层也必须指定,对于没有 mipmap 或单层纹理的情况,这些参数应为 "
+"[code]0[/code]。如果纹理复制成功,则返回 [constant @GlobalScope.OK],否则返回 "
+"[constant @GlobalScope.ERR_INVALID_PARAMETER]。\n"
+"[b]注意:[/b]如果使用 [param from_texture] 纹理的绘图列表是创建的帧缓冲的一部"
+"分,则无法复制。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后再复制纹理。\n"
+"[b]注意:[/b][param from_texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT]。\n"
+"[b]注意:[/b]如果使用 [param to_texture] 纹理的绘图列表是创建的帧缓冲的一部"
+"分,则无法复制。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后再复制纹理。\n"
+"[b]注意:[/b][param to_texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_COPY_TO_BIT]。\n"
+"[b]注意:[/b][param from_texture] 和 [param to_texture] 的类型必须相同(颜色或"
+"深度)。"
+
+msgid ""
"Creates a new texture. It can be accessed with the RID that is returned.\n"
"Once finished with your RID, you will want to free the RID using the "
"RenderingDevice's [method free_rid] method.\n"
@@ -92537,13 +97881,59 @@ msgid ""
"texture_2d_create], which creates the Godot-specific [Texture2D] resource as "
"opposed to the graphics API's own texture type."
msgstr ""
-"创建新的纹理。可以通过返回的 RID 进行访问。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"新建纹理。可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]请勿与 [method RenderingServer.texture_2d_create] 混淆,后者创建"
"的是 Godot 专属的 [Texture2D] 资源,不是图形 API 自己的纹理类型。"
msgid ""
+"Creates a shared texture using the specified [param view] and the texture "
+"information from [param with_texture]."
+msgstr ""
+"使用指定的 [param view] 和 [param with_texture] 中的纹理信息创建共享纹理。"
+
+msgid ""
+"Creates a shared texture using the specified [param view] and the texture "
+"information from [param with_texture]'s [param layer] and [param mipmap]. The "
+"number of included mipmaps from the original texture can be controlled using "
+"the [param mipmaps] parameter. Only relevant for textures with multiple "
+"layers, such as 3D textures, texture arrays and cubemaps. For single-layer "
+"textures, use [method texture_create_shared]\n"
+"For 2D textures (which only have one layer), [param layer] must be [code]0[/"
+"code].\n"
+"[b]Note:[/b] Layer slicing is only supported for 2D texture arrays, not 3D "
+"textures or cubemaps."
+msgstr ""
+"使用指定的 [param view] 和 [param with_texture] 的 [param layer] 和 [param "
+"mipmap] 中的纹理信息创建共享纹理。可以使用 [param mipmaps] 参数控制从原始纹理"
+"中包含的 mipmap 数量。仅适用于 3D 纹理、纹理数组、立方体贴图等多层纹理。单层纹"
+"理请使用 [method texture_create_shared]。\n"
+"对于 2D 纹理(仅有一个图层),[param layer] 必须为 [code]0[/code]。\n"
+"[b]注意:[/b]图层切片仅支持 2D 纹理数组,不支持 3D 纹理或立方体贴图。"
+
+msgid ""
+"Returns the [param texture] data for the specified [param layer] as raw "
+"binary data. For 2D textures (which only have one layer), [param layer] must "
+"be [code]0[/code].\n"
+"[b]Note:[/b] [param texture] can't be retrieved while a draw list that uses "
+"it as part of a framebuffer is being created. Ensure the draw list is "
+"finalized (and that the color/depth texture using it is not set to [constant "
+"FINAL_ACTION_CONTINUE]) to retrieve this texture. Otherwise, an error is "
+"printed and a empty [PackedByteArray] is returned.\n"
+"[b]Note:[/b] [param texture] requires the [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT] to be retrieved. Otherwise, an error is "
+"printed and a empty [PackedByteArray] is returned."
+msgstr ""
+"将纹理 [param texture] 中指定层 [param layer] 的纹理数据以原始二进制数据的形式"
+"返回。2D 纹理(只有一层)的 [param layer] 必须为 [code]0[/code]。\n"
+"[b]注意:[/b]如果使用 [param texture] 纹理的绘图列表是创建的帧缓冲的一部分,则"
+"无法获取。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后获取纹理。否则会输出错误并返回空的 "
+"[PackedByteArray]。\n"
+"[b]注意:[/b][param texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT]。否则会输出错误并返回空的 [PackedByteArray]。"
+
+msgid ""
"Returns the internal graphics handle for this texture object. For use when "
"communicating with third-party APIs mostly with GDExtension.\n"
"[b]Note:[/b] This function returns a [code]uint64_t[/code] which internally "
@@ -92575,6 +97965,84 @@ msgstr ""
"code]。"
msgid ""
+"Resolves the [param from_texture] texture onto [param to_texture] with "
+"multisample antialiasing enabled. This must be used when rendering a "
+"framebuffer for MSAA to work. Returns [constant @GlobalScope.OK] if "
+"successful, [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.\n"
+"[b]Note:[/b] [param from_texture] and [param to_texture] textures must have "
+"the same dimension, format and type (color or depth).\n"
+"[b]Note:[/b] [param from_texture] can't be copied while a draw list that uses "
+"it as part of a framebuffer is being created. Ensure the draw list is "
+"finalized (and that the color/depth texture using it is not set to [constant "
+"FINAL_ACTION_CONTINUE]) to resolve this texture.\n"
+"[b]Note:[/b] [param from_texture] requires the [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT] to be retrieved.\n"
+"[b]Note:[/b] [param from_texture] must be multisampled and must also be 2D "
+"(or a slice of a 3D/cubemap texture).\n"
+"[b]Note:[/b] [param to_texture] can't be copied while a draw list that uses "
+"it as part of a framebuffer is being created. Ensure the draw list is "
+"finalized (and that the color/depth texture using it is not set to [constant "
+"FINAL_ACTION_CONTINUE]) to resolve this texture.\n"
+"[b]Note:[/b] [param to_texture] texture requires the [constant "
+"TEXTURE_USAGE_CAN_COPY_TO_BIT] to be retrieved.\n"
+"[b]Note:[/b] [param to_texture] texture must [b]not[/b] be multisampled and "
+"must also be 2D (or a slice of a 3D/cubemap texture)."
+msgstr ""
+"启用多重采样抗锯齿,将 [param from_texture] 纹理溶解至 [param to_texture]。启"
+"用后才能够正常渲染 MSAA 帧缓冲。成功时返回 [constant @GlobalScope.OK],否则返"
+"回 [constant @GlobalScope.ERR_INVALID_PARAMETER]。\n"
+"[b]注意:[/b][param from_texture] 和 [param to_texture] 的尺寸、格式、类型(颜"
+"色或深度)都必须相同。\n"
+"[b]注意:[/b]如果使用 [param from_texture] 纹理的绘图列表是创建的帧缓冲的一部"
+"分,则无法复制。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后再复制纹理。\n"
+"[b]注意:[/b][param from_texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_COPY_FROM_BIT]。\n"
+"[b]注意:[/b][param from_texture] 纹理必须为多重采样,并且必须为 2D 纹理(或者"
+"是 3D/立方体贴图纹理的切片)。\n"
+"[b]注意:[/b]如果使用 [param to_texture] 纹理的绘图列表是创建的帧缓冲的一部"
+"分,则无法复制。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后再溶解纹理。\n"
+"[b]注意:[/b][param to_texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_COPY_TO_BIT]。\n"
+"[b]注意:[/b][param from_texture] 纹理必须[b]不能[/b]是多重采样,并且必须为 "
+"2D 纹理(或者是 3D/立方体贴图纹理的切片)。"
+
+msgid ""
+"Updates texture data with new data, replacing the previous data in place. The "
+"updated texture data must have the same dimensions and format. For 2D "
+"textures (which only have one layer), [param layer] must be [code]0[/code]. "
+"Returns [constant @GlobalScope.OK] if the update was successful, [constant "
+"@GlobalScope.ERR_INVALID_PARAMETER] otherwise.\n"
+"[b]Note:[/b] Updating textures is forbidden during creation of a draw or "
+"compute list.\n"
+"[b]Note:[/b] The existing [param texture] can't be updated while a draw list "
+"that uses it as part of a framebuffer is being created. Ensure the draw list "
+"is finalized (and that the color/depth texture using it is not set to "
+"[constant FINAL_ACTION_CONTINUE]) to update this texture.\n"
+"[b]Note:[/b] The existing [param texture] requires the [constant "
+"TEXTURE_USAGE_CAN_UPDATE_BIT] to be updatable."
+msgstr ""
+"使用新的数据更新纹理数据,会原地替换之前的数据。更新后的纹理数据必须和原有尺"
+"寸、格式一致。2D 纹理(只有一层)的 [param layer] 必须为 [code]0[/code]。如果"
+"更新成功则返回 [constant @GlobalScope.OK],否则返回 [constant @GlobalScope."
+"ERR_INVALID_PARAMETER]。\n"
+"[b]注意:[/b]精致在创建绘图列表或计算列表时更新纹理。\n"
+"[b]注意:[/b]如果使用 [param texture] 纹理的绘图列表是创建的帧缓冲的一部分,则"
+"无法更新。请确保绘图列表已经完成(并且使用它的颜色/深度纹理没有设置为 "
+"[constant FINAL_ACTION_CONTINUE]),然后再更新纹理。\n"
+"[b]注意:[/b][param texture] 纹理需要获取 [constant "
+"TEXTURE_USAGE_CAN_UPDATE_BIT]。"
+
+msgid ""
+"It can be accessed with the RID that is returned.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingDevice's [method free_rid] method."
+msgstr ""
+"可以通过返回的 RID 进行访问。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
+
+msgid ""
"Creates a vertex array based on the specified buffers. Optionally, [param "
"offsets] (in bytes) may be defined for each buffer."
msgstr ""
@@ -92582,6 +98050,14 @@ msgstr ""
"位为字节)。"
msgid ""
+"Creates a new vertex format with the specified [param vertex_descriptions]. "
+"Returns a unique vertex format ID corresponding to the newly created vertex "
+"format."
+msgstr ""
+"新建顶点描述为 [param vertex_descriptions] 的顶点格式。返回与新建顶点格式对应"
+"的唯一格式 ID。"
+
+msgid ""
"Rendering device type does not match any of the other enum values or is "
"unknown."
msgstr "渲染设备的类型与其他枚举值均不匹配,或者未知。"
@@ -94697,13 +100173,108 @@ msgid ""
"will result in a blurry look."
msgstr "双线性采样器过滤。按照比源更高分辨率采样时,会产生模糊的效果。"
+msgid "Sample with repeating enabled."
+msgstr "启用重复采样。"
+
+msgid ""
+"Sample with mirrored repeating enabled. When sampling outside the [code][0.0, "
+"1.0][/code] range, return a mirrored version of the sampler. This mirrored "
+"version is mirrored again if sampling further away, with the pattern "
+"repeating indefinitely."
+msgstr ""
+"启用镜像重复采样。对 [code][0.0, 1.0][/code] 范围外进行采样时,返回采样器的镜"
+"像版本。如果采样的是更远的位置,则会对镜像版本再次镜像,并按照这样的规律无限重"
+"复下去。"
+
+msgid ""
+"Sample with repeating disabled. When sampling outside the [code][0.0, 1.0][/"
+"code] range, return the color of the last pixel on the edge."
+msgstr ""
+"禁用重复采样。对 [code][0.0, 1.0][/code] 范围外进行采样时,返回边缘上最后一个"
+"像素的颜色。"
+
+msgid ""
+"Sample with repeating disabled. When sampling outside the [code][0.0, 1.0][/"
+"code] range, return the specified [member RDSamplerState.border_color]."
+msgstr ""
+"禁用重复采样。对 [code][0.0, 1.0][/code] 范围外进行采样时,返回指定的边框颜色 "
+"[member RDSamplerState.border_color]。"
+
+msgid ""
+"Sample with mirrored repeating enabled, but only once. When sampling in the "
+"[code][-1.0, 0.0][/code] range, return a mirrored version of the sampler. "
+"When sampling outside the [code][-1.0, 1.0][/code] range, return the color of "
+"the last pixel on the edge."
+msgstr ""
+"启用单次镜像重复采样。对 [code][-1.0, 0.0][/code] 范围进行采样时,返回采样器的"
+"镜像版本。对 [code][-1.0, 1.0][/code] 范围外进行采样时,返回边缘上最后一个像素"
+"的颜色。"
+
msgid "Represents the size of the [enum SamplerRepeatMode] enum."
msgstr "代表 [enum SamplerRepeatMode] 枚举的大小。"
+msgid ""
+"Return a floating-point transparent black color when sampling outside the "
+"[code][0.0, 1.0][/code] range. Only effective if the sampler repeat mode is "
+"[constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回浮点型的透明黑色。仅在采样器"
+"的重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
+msgid ""
+"Return a integer transparent black color when sampling outside the [code]"
+"[0.0, 1.0][/code] range. Only effective if the sampler repeat mode is "
+"[constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回整型的透明黑色。仅在采样器的"
+"重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
+msgid ""
+"Return a floating-point opaque black color when sampling outside the [code]"
+"[0.0, 1.0][/code] range. Only effective if the sampler repeat mode is "
+"[constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回浮点型的不透明黑色。仅在采样"
+"器的重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
+msgid ""
+"Return a integer opaque black color when sampling outside the [code][0.0, 1.0]"
+"[/code] range. Only effective if the sampler repeat mode is [constant "
+"SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回整型的不透明黑色。仅在采样器"
+"的重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
+msgid ""
+"Return a floating-point opaque white color when sampling outside the [code]"
+"[0.0, 1.0][/code] range. Only effective if the sampler repeat mode is "
+"[constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回浮点型的不透明白色。仅在采样"
+"器的重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
+msgid ""
+"Return a integer opaque white color when sampling outside the [code][0.0, 1.0]"
+"[/code] range. Only effective if the sampler repeat mode is [constant "
+"SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER]."
+msgstr ""
+"对 [code][0.0, 1.0][/code] 范围外进行采样时,返回整型的不透明白色。仅在采样器"
+"的重复模式为 [constant SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER] 时有效。"
+
msgid "Represents the size of the [enum SamplerBorderColor] enum."
msgstr "代表 [enum SamplerBorderColor] 枚举的大小。"
msgid ""
+"Vertex attribute addressing is a function of the vertex. This is used to "
+"specify the rate at which vertex attributes are pulled from buffers."
+msgstr "顶点属性寻址是顶点的功能。用于指定从缓冲中拉取顶点属性的频率。"
+
+msgid ""
+"Vertex attribute addressing is a function of the instance index. This is used "
+"to specify the rate at which vertex attributes are pulled from buffers."
+msgstr "顶点属性寻址是实例索引的功能。用于指定从缓冲中拉取顶点属性的频率。"
+
+msgid ""
"Index buffer in 16-bit unsigned integer format. This limits the maximum index "
"that can be specified to [code]65535[/code]."
msgstr ""
@@ -94830,6 +100401,23 @@ msgstr ""
"据。[/url]\n"
"[b]注意:[/b]邻接数据仅在几何着色器中有用,但 Godot 并没有暴露。"
+msgid ""
+"Triangle strip rendering primitive with [i]primitive restart[/i] enabled. "
+"Triangles drawn are connected to the previous triangle, but a primitive "
+"restart index can be specified before drawing to create a second triangle "
+"strip after the specified index.\n"
+"[b]Note:[/b] Only compatible with indexed draws."
+msgstr ""
+"渲染三角形条带的图元,启用[i]图元重启[/i]。绘制的三角形与它的前一个三角形是相"
+"连的,但是在绘制前可以指定图元重启索引,这样在指定索引之后就会再创建一条三角形"
+"条带。\n"
+"[b]注意:[/b]仅兼容索引绘图。"
+
+msgid ""
+"Tessellation patch rendering primitive. Only useful with tessellation "
+"shaders, which can be used to deform these patches."
+msgstr "曲面细分面片渲染图元。仅对曲面细分着色器有用,可以将面片变形。"
+
msgid "Represents the size of the [enum RenderPrimitive] enum."
msgstr "代表 [enum RenderPrimitive] 枚举的大小。"
@@ -95179,12 +100767,98 @@ msgstr ""
msgid "Represents the size of the [enum InitialAction] enum."
msgstr "代表 [enum InitialAction] 枚举的大小。"
+msgid ""
+"Store the texture for reading and make it read-only if it has the [constant "
+"TEXTURE_USAGE_SAMPLING_BIT] bit (only applies to color, depth and stencil "
+"attachments)."
+msgstr ""
+"以读取为目的存储纹理,如果设置了 [constant TEXTURE_USAGE_SAMPLING_BIT] 位则将"
+"其设为只读(仅适用于颜色、深度、模板附件)。"
+
+msgid ""
+"Discard the texture data and make it read-only if it has the [constant "
+"TEXTURE_USAGE_SAMPLING_BIT] bit (only applies to color, depth and stencil "
+"attachments)."
+msgstr ""
+"丢弃纹理数据,如果设置了 [constant TEXTURE_USAGE_SAMPLING_BIT] 位则将其设为只"
+"读(仅适用于颜色、深度、模板附件)。"
+
+msgid ""
+"Store the texture and continue for further processing. Similar to [constant "
+"FINAL_ACTION_READ], but does not make the texture read-only if it has the "
+"[constant TEXTURE_USAGE_SAMPLING_BIT] bit."
+msgstr ""
+"存储纹理并继续后续处理。与 [constant FINAL_ACTION_READ] 类似,但不会在设置了 "
+"[constant TEXTURE_USAGE_SAMPLING_BIT] 位时将其设为只读。"
+
msgid "Represents the size of the [enum FinalAction] enum."
msgstr "代表 [enum FinalAction] 枚举的大小。"
+msgid ""
+"Vertex shader stage. This can be used to manipulate vertices from a shader "
+"(but not create new vertices)."
+msgstr "顶点着色器阶段。可用于在着色器中操作顶点(但无法新建顶点)。"
+
+msgid ""
+"Fragment shader stage (called \"pixel shader\" in Direct3D). This can be used "
+"to manipulate pixels from a shader."
+msgstr ""
+"片段着色器阶段(Direct3D 中成为“像素着色器”)。可用于在着色器中操作像素。"
+
+msgid ""
+"Tessellation control shader stage. This can be used to create additional "
+"geometry from a shader."
+msgstr "曲面细分控制着色器阶段。可用于在着色器中创建额外的几何体。"
+
+msgid ""
+"Tessellation evaluation shader stage. This can be used to create additional "
+"geometry from a shader."
+msgstr "曲面细分求值着色器阶段。可用于在着色器中创建额外的几何体。"
+
+msgid ""
+"Compute shader stage. This can be used to run arbitrary computing tasks in a "
+"shader, performing them on the GPU instead of the CPU."
+msgstr ""
+"计算着色器阶段。可用于在着色器中执行任意计算任务,在 GPU 而不是 CPU 上进行计"
+"算。"
+
msgid "Represents the size of the [enum ShaderStage] enum."
msgstr "代表 [enum ShaderStage] 枚举的大小。"
+msgid "Vertex shader stage bit (see also [constant SHADER_STAGE_VERTEX])."
+msgstr "顶点着色器阶段位(另见 [constant SHADER_STAGE_VERTEX])。"
+
+msgid "Fragment shader stage bit (see also [constant SHADER_STAGE_FRAGMENT])."
+msgstr "片段着色器阶段位(另见 [constant SHADER_STAGE_FRAGMENT])。"
+
+msgid ""
+"Tessellation control shader stage bit (see also [constant "
+"SHADER_STAGE_TESSELATION_CONTROL])."
+msgstr ""
+"曲面细分控制着色器阶段位(另见 [constant SHADER_STAGE_TESSELATION_CONTROL])。"
+
+msgid ""
+"Tessellation evaluation shader stage bit (see also [constant "
+"SHADER_STAGE_TESSELATION_EVALUATION])."
+msgstr ""
+"曲面细分求值着色器阶段位(另见 [constant "
+"SHADER_STAGE_TESSELATION_EVALUATION])。"
+
+msgid "Compute shader stage bit (see also [constant SHADER_STAGE_COMPUTE])."
+msgstr "计算着色器阶段位(另见 [constant SHADER_STAGE_COMPUTE])。"
+
+msgid ""
+"Khronos' GLSL shading language (used natively by OpenGL and Vulkan). This is "
+"the language used for core Godot shaders."
+msgstr ""
+"Khronos 的 GLSL 着色语言(OpenGL 和 Vulkan 原生使用)。这是核心 Godot 着色器所"
+"使用的语言。"
+
+msgid ""
+"Microsoft's High-Level Shading Language (used natively by Direct3D, but can "
+"also be used in Vulkan)."
+msgstr "Microsoft 的高级着色器语言(Direct3D 原生使用,Vulkan 中也能使用)。"
+
msgid "Boolean specialization constant."
msgstr "布尔型特化常量。"
@@ -95194,12 +100868,45 @@ msgstr "整型特化常量。"
msgid "Floating-point specialization constant."
msgstr "浮点型特化常量。"
+msgid "Maximum number of uniform sets that can be bound at a given time."
+msgstr "能够同时绑定的最大 uniform 集的数量。"
+
+msgid ""
+"Maximum number of color framebuffer attachments that can be used at a given "
+"time."
+msgstr "能够同时使用的最大颜色帧缓冲附件的数量。"
+
+msgid "Maximum number of textures that can be used per uniform set."
+msgstr "单个 uniform 集能够使用的最大纹理数量。"
+
+msgid "Maximum number of samplers that can be used per uniform set."
+msgstr "单个 uniform 集能够使用的最大采样器数量。"
+
+msgid ""
+"Maximum number of [url=https://vkguide.dev/docs/chapter-4/"
+"storage_buffers/]storage buffers[/url] per uniform set."
+msgstr ""
+"单个 uniform 集的最大[url=https://vkguide.dev/docs/chapter-4/storage_buffers/]"
+"存储缓冲[/url]数量。"
+
+msgid "Maximum number of storage images per uniform set."
+msgstr "单个 uniform 集的最大存储图像数量。"
+
+msgid "Maximum number of uniform buffers per uniform set."
+msgstr "单个 uniform 集的最大 uniform 缓冲数量。"
+
+msgid "Maximum index for an indexed draw command."
+msgstr "索引绘图指令的最大索引。"
+
msgid "Maximum height of a framebuffer (in pixels)."
msgstr "帧缓冲的最大高度(单位为像素)。"
msgid "Maximum width of a framebuffer (in pixels)."
msgstr "帧缓冲的最大宽度(单位为像素)。"
+msgid "Maximum number of texture array layers."
+msgstr "纹理数组的最大层数。"
+
msgid ""
"Maximum supported 1-dimensional texture size (in pixels on a single axis)."
msgstr "支持的一维纹理的最大尺寸(单轴像素数)。"
@@ -95233,6 +100940,14 @@ msgstr ""
msgid "Maximum number of storage images per shader stage."
msgstr "每个着色器阶段的最大存储图像数。"
+msgid ""
+"Maximum size of a push constant. A lot of devices are limited to 128 bytes, "
+"so try to avoid exceeding 128 bytes in push constants to ensure compatibility "
+"even if your GPU is reporting a higher value."
+msgstr ""
+"推送常量的最大大小。许多设备都有 128 字节的限制,所以即便你的 GPU 汇报的值更"
+"大,也请尝试避免让推送常量超过 127 字节,从而确保兼容性。"
+
msgid "Maximum size of a uniform buffer."
msgstr "Uniform 缓冲的最大大小。"
@@ -95395,8 +101110,7 @@ msgid ""
msgstr ""
"创建相机属性对象并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这"
"个 RID 会在所有 [code]camera_attributes_[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [CameraAttributes]。"
msgid ""
@@ -95473,8 +101187,7 @@ msgid ""
msgstr ""
"创建 3D 相机并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]camera_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [Camera3D]。"
msgid ""
@@ -95540,8 +101253,7 @@ msgid ""
msgstr ""
"创建画布并返回分配的 [RID]。可以通过返回的 RID 进行访问。这个 RID 会在所有 "
"[code]canvas_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"没有与画布等价的 [Resource] 或 [Node]。"
msgid ""
@@ -95670,7 +101382,7 @@ msgstr ""
"[b]注意:[/b][param count] 未使用,可以不指定。"
msgid "Clears the [CanvasItem] and removes all commands in it."
-msgstr "清除[CanvasItem]并删除其中的所有命令。"
+msgstr "清空 [CanvasItem] 并删除其中的所有命令。"
msgid ""
"Creates a new CanvasItem instance and returns its [RID]. It can be accessed "
@@ -95682,10 +101394,37 @@ msgid ""
msgstr ""
"新建 CanvasItem 实例并返回其 [RID]。可以通过返回的 RID 进行访问。这个 RID 会在"
"所有 [code]canvas_item_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [CanvasItem]。"
+msgid ""
+"Sets the canvas group mode used during 2D rendering for the canvas item "
+"specified by the [param item] RID. For faster but more limited clipping, use "
+"[method canvas_item_set_clip] instead.\n"
+"[b]Note:[/b] The equivalent node functionality is found in [CanvasGroup] and "
+"[member CanvasItem.clip_children]."
+msgstr ""
+"设置对画布项进行 2D 渲染时使用的画布分组模式,画布项由 [param item] RID 指定。"
+"要使用更快速但局限性更大的裁剪,请改用 [method canvas_item_set_clip]。\n"
+"[b]注意:[/b]等价的节点功能可以在 [CanvasGroup] 和 [member CanvasItem."
+"clip_children] 中找到。"
+
+msgid ""
+"If [param clip] is [code]true[/code], makes the canvas item specified by the "
+"[param item] RID not draw anything outside of its rect's coordinates. This "
+"clipping is fast, but works only with axis-aligned rectangles. This means "
+"that rotation is ignored by the clipping rectangle. For more advanced "
+"clipping shapes, use [method canvas_item_set_canvas_group_mode] instead.\n"
+"[b]Note:[/b] The equivalent node functionality is found in [member Label."
+"clip_text], [RichTextLabel] (always enabled) and more."
+msgstr ""
+"如果 [param clip] 为 [code]true[/code],则画布项不会在其矩形坐标之外绘制内容,"
+"画布项由 [param item] RID 指定。这种裁剪很快,但只能用于轴对齐的矩形。也就是说"
+"裁剪矩形会忽略旋转。更高阶的裁剪形状请改用 [method "
+"canvas_item_set_canvas_group_mode]。\n"
+"[b]注意:[/b]等价的节点功能可以在 [member Label.clip_text]、[RichTextLabel]"
+"(始终启用)等处找到。"
+
msgid "Sets the [CanvasItem] to copy a rect to the backbuffer."
msgstr "设置 [CanvasItem] 以将矩形复制到后台缓冲区。"
@@ -95835,7 +101574,7 @@ msgstr "设置 [CanvasItem] 的 Z 索引,即它的绘制顺序(首先绘制
msgid ""
"Attaches the canvas light to the canvas. Removes it from its previous canvas."
-msgstr "将画布灯连接到画布上,并将其从以前的画布中取出。"
+msgstr "将画布灯连接到画布上,并将其从以前的画布中取出。"
msgid ""
"Creates a canvas light and adds it to the RenderingServer. It can be accessed "
@@ -95847,8 +101586,7 @@ msgid ""
msgstr ""
"创建画布灯光并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]canvas_light_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [Light2D]。"
msgid ""
@@ -95866,8 +101604,7 @@ msgstr ""
"创建光线遮挡器并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]canvas_light_occluder_*[/code] RenderingServer 函数中使"
"用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [LightOccluder2D]。"
msgid "Enables or disables light occluder."
@@ -95965,11 +101702,10 @@ msgid ""
"RenderingServer's [method free_rid] method.\n"
"[b]Note:[/b] The equivalent resource is [OccluderPolygon2D]."
msgstr ""
-"创建一个新的光线遮挡多边形并将其添加到 RenderingServer。可以通过返回的 RID 进"
-"行访问。这个 RID 会在所有 [code]canvas_occluder_polygon_*[/code] "
-"RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"新建光线遮挡多边形并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。"
+"这个 RID 会在所有 [code]canvas_occluder_polygon_*[/code] RenderingServer 函数"
+"中使用。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [OccluderPolygon2D]。"
msgid ""
@@ -96008,8 +101744,8 @@ msgid ""
msgstr ""
"创建画布纹理并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]canvas_texture_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。另"
+"见 [method texture_2d_create]。\n"
"[b]注意:[/b]等价资源为 [CanvasTexture],应该仅用于 2D 渲染,不用于 3D。"
msgid ""
@@ -96070,8 +101806,7 @@ msgid ""
msgstr ""
"创建贴花并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID 会"
"在所有 [code]decal_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个贴花放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]等价节点为 [Decal]。"
@@ -96141,7 +101876,7 @@ msgid ""
"specified decal. Equivalent to [method Decal.set_texture]."
msgstr ""
"设置指定贴花中给定纹理类型插槽 [param type] 的纹理 [param texture]。等价于 "
-"[member Decal.set_texture]。"
+"[method Decal.set_texture]。"
msgid ""
"Sets the texture [param filter] mode to use when rendering decals. This "
@@ -96162,8 +101897,7 @@ msgid ""
msgstr ""
"创建平行光并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID "
"会在大多数 [code]light_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个平行光放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]等价节点为 [DirectionalLight3D]。"
@@ -96188,6 +101922,32 @@ msgstr ""
"这个参数是全局的,无法针对某个视口单独设置。"
msgid ""
+"Generates and returns an [Image] containing the radiance map for the "
+"specified [param environment] RID's sky. This supports built-in sky material "
+"and custom sky shaders. If [param bake_irradiance] is [code]true[/code], the "
+"irradiance map is saved instead of the radiance map. The radiance map is used "
+"to render reflected light, while the irradiance map is used to render ambient "
+"light. See also [method sky_bake_panorama].\n"
+"[b]Note:[/b] The image is saved in linear color space without any tonemapping "
+"performed, which means it will look too dark if viewed directly in an image "
+"editor.\n"
+"[b]Note:[/b] [param size] should be a 2:1 aspect ratio for the generated "
+"panorama to have square pixels. For radiance maps, there is no point in using "
+"a height greater than [member Sky.radiance_size], as it won't increase "
+"detail. Irradiance maps only contain low-frequency data, so there is usually "
+"no point in going past a size of 128×64 pixels when saving an irradiance map."
+msgstr ""
+"生成并返回包含 [param environment] RID 中的天空的辐射度贴图的 [Image]。支持内"
+"置天空材质和自定义天空着色器。如果 [param bake_irradiance] 为 [code]true[/"
+"code],则保存的是辐照度贴图,而不是辐射度贴图。辐射度贴图用于渲染反射光,而辐"
+"照度贴图用于渲染环境光。另见 [method sky_bake_panorama]。\n"
+"[b]注意:[/b]图像使用线性色彩空间保存,未执行任何色调映射,也就是说如果在图像"
+"编辑器中查看会显得太暗。\n"
+"[b]注意:[/b]要让生成的全景图拥有正方形的像素,[param size] 的长宽比应该为 "
+"2:1。辐射度贴图的高度超过 [member Sky.radiance_size] 没有意义,不会增加细节。"
+"辐照度仅包含低频数据,保存时超过 128×64 像素通常没有意义。"
+
+msgid ""
"Creates an environment and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all "
"[code]environment_*[/code] RenderingServer functions.\n"
@@ -96197,11 +101957,19 @@ msgid ""
msgstr ""
"创建环境并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID 会"
"在所有 [code]environment_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [Environment]。"
msgid ""
+"If [param enable] is [code]true[/code], enables bicubic upscaling for glow "
+"which improves quality at the cost of performance. Equivalent to [member "
+"ProjectSettings.rendering/environment/glow/upscale_mode]."
+msgstr ""
+"如果 [param enable] 为 [code]true[/code],则会为辉光启用双三次插值,能够牺牲性"
+"能、提升质量。等价于 [member ProjectSettings.rendering/environment/glow/"
+"upscale_mode]。"
+
+msgid ""
"Sets the values to be used with the \"adjustments\" post-process effect. See "
"[Environment] for more details."
msgstr "设置用于“调整”后期处理效果的数值。详见 [Environment]。"
@@ -96350,8 +102118,7 @@ msgid ""
msgstr ""
"新建雾体积并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID "
"会在所有 [code]fog_volume_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [FogVolume]。"
msgid ""
@@ -96411,6 +102178,16 @@ msgstr ""
"set_default_clear_color]。"
msgid ""
+"Returns the time taken to setup rendering on the CPU in milliseconds. This "
+"value is shared across all viewports and does [i]not[/i] require [method "
+"viewport_set_measure_render_time] to be enabled on a viewport to be queried. "
+"See also [method viewport_get_measured_render_time_cpu]."
+msgstr ""
+"返回在 CPU 上设置渲染所消耗的时间,单位为毫秒。这个值是所有视口共享的,[i]不需"
+"要[/i]在查询的视口上启用 [method viewport_set_measure_render_time]。另见 "
+"[method viewport_get_measured_render_time_cpu]。"
+
+msgid ""
"Returns the global RenderingDevice.\n"
"[b]Note:[/b] When using the OpenGL backend or when running in headless mode, "
"this function always returns [code]null[/code]."
@@ -96419,6 +102196,42 @@ msgstr ""
"[b]注意:[/b]当使用 OpenGL 后端或在无头模式下运行时,这个函数始终返回 "
"[code]null[/code]。"
+msgid ""
+"Returns a statistic about the rendering engine which can be used for "
+"performance profiling. See [enum RenderingServer.RenderingInfo] for a list of "
+"values that can be queried. See also [method viewport_get_render_info], which "
+"returns information specific to a viewport.\n"
+"[b]Note:[/b] Only 3D rendering is currently taken into account by some of "
+"these values, such as the number of draw calls.\n"
+"[b]Note:[/b] Rendering information is not available until at least 2 frames "
+"have been rendered by the engine. If rendering information is not available, "
+"[method get_rendering_info] returns [code]0[/code]. To print rendering "
+"information in [code]_ready()[/code] successfully, use the following:\n"
+"[codeblock]\n"
+"func _ready():\n"
+" for _i in 2:\n"
+" await get_tree().process_frame\n"
+"\n"
+" print(RenderingServer."
+"get_rendering_info(RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME))\n"
+"[/codeblock]"
+msgstr ""
+"返回关于渲染引擎的统计信息,能够用于性能分析。能够查询的值的列表见 [enum "
+"RenderingServer.RenderingInfo]。另见 [method viewport_get_render_info],返回的"
+"是某个视口的相关信息。\n"
+"[b]注意:[/b]部分值目前仅考虑 3D 渲染,例如绘制调用的数量。\n"
+"[b]注意:[/b]引擎渲染至少 2 帧后渲染信息才可用。渲染信息不可用时 [method "
+"get_rendering_info] 返回 [code]0[/code]。要在 [code]_ready()[/code] 中成功输出"
+"渲染信息,请使用如下代码:\n"
+"[codeblock]\n"
+"func _ready():\n"
+" for _i in 2:\n"
+" await get_tree().process_frame\n"
+"\n"
+" print(RenderingServer."
+"get_rendering_info(RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME))\n"
+"[/codeblock]"
+
msgid "Returns the parameters of a shader."
msgstr "返回着色器的参数。"
@@ -96455,6 +102268,21 @@ msgstr ""
"[/codeblock]"
msgid ""
+"Returns the version of the graphics video adapter [i]currently in use[/i] (e."
+"g. \"1.2.189\" for Vulkan, \"3.3.0 NVIDIA 510.60.02\" for OpenGL). This "
+"version may be different from the actual latest version supported by the "
+"hardware, as Godot may not always request the latest version. See also "
+"[method OS.get_video_adapter_driver_info].\n"
+"[b]Note:[/b] When running a headless or server binary, this function returns "
+"an empty string."
+msgstr ""
+"返回[i]当前使用的[/i]图形视频适配器的版本(例如,Vulkan 为“1.2.189”,OpenGL "
+"为“3.3.0 NVIDIA 510.60.02”)。该版本可能与硬件支持的实际最新版本不同,因为 "
+"Godot 可能并不总是要求最新版本。另见 [method OS."
+"get_video_adapter_driver_info]。\n"
+"[b]注意:[/b]当运行无头或服务器可执行文件时,该函数返回一个空字符串。"
+
+msgid ""
"Returns the name of the video adapter (e.g. \"GeForce GTX 1080/PCIe/SSE2\").\n"
"[b]Note:[/b] When running a headless or server binary, this function returns "
"an empty string."
@@ -96511,6 +102339,23 @@ msgstr ""
"[/codeblock]"
msgid ""
+"If [param half_resolution] is [code]true[/code], renders [VoxelGI] and SDFGI "
+"([member Environment.sdfgi_enabled]) buffers at halved resolution on each "
+"axis (e.g. 960×540 when the viewport size is 1920×1080). This improves "
+"performance significantly when VoxelGI or SDFGI is enabled, at the cost of "
+"artifacts that may be visible on polygon edges. The loss in quality becomes "
+"less noticeable as the viewport resolution increases. [LightmapGI] rendering "
+"is not affected by this setting. Equivalent to [member ProjectSettings."
+"rendering/global_illumination/gi/use_half_resolution]."
+msgstr ""
+"如果 [param half_resolution] 为 [code]true[/code],则每个轴上都会使用一半的分"
+"辨率渲染 [VoxelGI] 和 SDFGI([member Environment.sdfgi_enabled])缓冲区(例如"
+"视口大小为 1920×1080 时使用 960×540)。启用 VoxelGI 或 SDFGI 时,这样做能够显"
+"著提升性能,但代价是多边形边缘可能产生显示问题。视口分辨率越高,越不容易注意到"
+"质量的损失。[LightmapGI] 的渲染不受这个设置的影响。等价于 [member "
+"ProjectSettings.rendering/global_illumination/gi/use_half_resolution]。"
+
+msgid ""
"Creates a new global shader uniform.\n"
"[b]Note:[/b] Global shader parameter names are case-sensitive."
msgstr ""
@@ -96620,13 +102465,57 @@ msgid ""
msgstr ""
"创建可视实例并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]instance_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"实例可以将 3D 对象放置到场景中。粒子、网格、反射探针、贴花等对象都需要使用 "
"[method instance_set_base] 与实例关联,才能显示在场景中。\n"
"[b]注意:[/b]等价节点为 [VisualInstance3D]。"
msgid ""
+"Creates a visual instance, adds it to the RenderingServer, and sets both base "
+"and scenario. It can be accessed with the RID that is returned. This RID will "
+"be used in all [code]instance_*[/code] RenderingServer functions.\n"
+"Once finished with your RID, you will want to free the RID using the "
+"RenderingServer's [method free_rid] method. This is a shorthand for using "
+"[method instance_create] and setting the base and scenario manually."
+msgstr ""
+"创建可视实例并将其添加到 RenderingServer、设置基础和场景。可以通过返回的 RID "
+"进行访问。这个 RID 会在大多数 [code]instance_*[/code] RenderingServer 函数中使"
+"用。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。这"
+"是使用 [method instance_create] 并手动设置基础和场景的快捷方式。"
+
+msgid ""
+"Returns the value of the per-instance shader uniform from the specified 3D "
+"geometry instance. Equivalent to [method GeometryInstance3D."
+"get_instance_shader_parameter].\n"
+"[b]Note:[/b] Per-instance shader parameter names are case-sensitive."
+msgstr ""
+"返回指定 3D 几何体实例的单实例着色器 uniform 的值。等价于 [method "
+"GeometryInstance3D.get_instance_shader_parameter]。\n"
+"[b]注意:[/b]单实例着色器参数的名称是大小写敏感的。"
+
+msgid ""
+"Returns the default value of the per-instance shader uniform from the "
+"specified 3D geometry instance. Equivalent to [method GeometryInstance3D."
+"get_instance_shader_parameter]."
+msgstr ""
+"返回指定 3D 几何体实例的单实例着色器 uniform 的默认值。等价于 [method "
+"GeometryInstance3D.get_instance_shader_parameter]。"
+
+msgid ""
+"Returns a dictionary of per-instance shader uniform names of the per-instance "
+"shader uniform from the specified 3D geometry instance. The returned "
+"dictionary is in PropertyInfo format, with the keys [code]name[/code], "
+"[code]class_name[/code], [code]type[/code], [code]hint[/code], "
+"[code]hint_string[/code] and [code]usage[/code]. Equivalent to [method "
+"GeometryInstance3D.get_instance_shader_parameter]."
+msgstr ""
+"返回指定 3D 几何体实例的单实例着色器名称字典。返回的字典使用 PropertyInfo 格"
+"式,包含 [code]name[/code]、[code]class_name[/code]、[code]type[/code]、"
+"[code]hint[/code]、[code]hint_string[/code] 以及 [code]usage[/code] 等键。等价"
+"于 [method GeometryInstance3D.get_instance_shader_parameter]。"
+
+msgid ""
"Sets the shadow casting setting to one of [enum ShadowCastingSetting]. "
"Equivalent to [member GeometryInstance3D.cast_shadow]."
msgstr ""
@@ -96640,6 +102529,24 @@ msgstr ""
"设置给定的 [enum InstanceFlags] 标志。更多细节请参阅 [enum InstanceFlags]。"
msgid ""
+"Sets the lightmap GI instance to use for the specified 3D geometry instance. "
+"The lightmap UV scale for the specified instance (equivalent to [member "
+"GeometryInstance3D.gi_lightmap_scale]) and lightmap atlas slice must also be "
+"specified."
+msgstr ""
+"为指定的 3D 几何体实例设置要使用的光照贴图 GI 实例。必须同时指定该实例的光照贴"
+"图 UV 缩放(等价于 [member GeometryInstance3D.gi_lightmap_scale])和光照贴图图"
+"集切片。"
+
+msgid ""
+"Sets the level of detail bias to use when rendering the specified 3D geometry "
+"instance. Higher values result in higher detail from further away. Equivalent "
+"to [member GeometryInstance3D.lod_bias]."
+msgstr ""
+"为指定的 3D 几何体实例设置要使用的细节级别偏置。值越高,距离较远时的细节也会越"
+"高。等价于 [member GeometryInstance3D.lod_bias]。"
+
+msgid ""
"Sets a material that will be rendered for all surfaces on top of active "
"materials for the mesh associated with this instance. Equivalent to [member "
"GeometryInstance3D.material_overlay]."
@@ -96656,6 +102563,13 @@ msgstr ""
"[member GeometryInstance3D.material_override]。"
msgid ""
+"Sets the per-instance shader uniform on the specified 3D geometry instance. "
+"Equivalent to [method GeometryInstance3D.set_instance_shader_parameter]."
+msgstr ""
+"设置指定的 3D 几何体实例的单实例着色器 uniform。等价于 [method "
+"GeometryInstance3D.set_instance_shader_parameter]。"
+
+msgid ""
"Sets the transparency for the given geometry instance. Equivalent to [member "
"GeometryInstance3D.transparency].\n"
"A transparency of [code]0.0[/code] is fully opaque, while [code]1.0[/code] is "
@@ -96689,6 +102603,17 @@ msgstr ""
"设置给定几何实例的可见性范围值。相当于 [member GeometryInstance3D."
"visibility_range_begin] 和相关属性。"
+msgid ""
+"Sets the base of the instance. A base can be any of the 3D objects that are "
+"created in the RenderingServer that can be displayed. For example, any of the "
+"light types, mesh, multimesh, particle system, reflection probe, decal, "
+"lightmap, voxel GI and visibility notifiers are all types that can be set as "
+"the base of an instance in order to be displayed in the scenario."
+msgstr ""
+"设置实例的基础。基础可以是在 RenderingServer 中创建的任何可以显示的 3D 对象。"
+"例如,任何光源类型、网格、多重网格、粒子系统、反射探针、贴花、光照贴图、体素 "
+"GI 和可见性通知器都可以设置为实例的基础,以便在场景中显示。"
+
msgid "Sets the weight for a given blend shape associated with this instance."
msgstr "设置与该实例相关的特定混合形状的权重。"
@@ -96708,6 +102633,16 @@ msgstr ""
"对象。相当于 [member GeometryInstance3D.extra_cull_margin]。"
msgid ""
+"If [code]true[/code], ignores both frustum and occlusion culling on the "
+"specified 3D geometry instance. This is not the same as [member "
+"GeometryInstance3D.ignore_occlusion_culling], which only ignores occlusion "
+"culling and leaves frustum culling intact."
+msgstr ""
+"如果为 [code]true[/code],则会忽略指定 3D 几何体实例的视锥剔除和遮挡剔除。和 "
+"[member GeometryInstance3D.ignore_occlusion_culling] 不同,后者只会忽略遮挡剔"
+"除,仍会保留视锥剔除。"
+
+msgid ""
"Sets the render layers that this instance will be drawn to. Equivalent to "
"[member VisualInstance3D.layers]."
msgstr "设置这个实例要绘制到的渲染层。相当于 [member VisualInstance3D.layers]。"
@@ -96745,6 +102680,54 @@ msgid ""
msgstr "设置是否绘制实例。相当于 [member Node3D.visible]。"
msgid ""
+"Returns an array of object IDs intersecting with the provided AABB. Only 3D "
+"nodes that inherit from [VisualInstance3D] are considered, such as "
+"[MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope."
+"instance_from_id] to obtain the actual nodes. A scenario RID must be "
+"provided, which is available in the [World3D] you want to query. This forces "
+"an update for all resources queued to update.\n"
+"[b]Warning:[/b] This function is primarily intended for editor usage. For in-"
+"game use cases, prefer physics collision."
+msgstr ""
+"返回与提供的 AABB 相交的对象 ID 的数组。仅考虑继承自 [VisualInstance3D] 的 3D "
+"节点,例如 [MeshInstance3D] 或 [DirectionalLight3D]。可使用 [method "
+"@GlobalScope.instance_from_id] 来获取实际节点。必须提供一个场景 RID,且它在要"
+"查询的 [World3D] 中可用。这会强制更新所有已被队列以等待更新的资源。\n"
+"[b]警告:[/b]该函数主要供编辑器使用。对于游戏中的用例,最好是物理碰撞。"
+
+msgid ""
+"Returns an array of object IDs intersecting with the provided convex shape. "
+"Only 3D nodes that inherit from [VisualInstance3D] are considered, such as "
+"[MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope."
+"instance_from_id] to obtain the actual nodes. A scenario RID must be "
+"provided, which is available in the [World3D] you want to query. This forces "
+"an update for all resources queued to update.\n"
+"[b]Warning:[/b] This function is primarily intended for editor usage. For in-"
+"game use cases, prefer physics collision."
+msgstr ""
+"返回与提供的凸形相交的对象 ID 的数组。仅考虑继承自 [VisualInstance3D] 的 3D 节"
+"点,例如 [MeshInstance3D] 或 [DirectionalLight3D]。可使用 [method "
+"@GlobalScope.instance_from_id] 以获取实际节点。必须提供场景 RID,且它在要查询"
+"的 [World3D] 中可用。这会强制更新所有已被队列以等待更新的资源。\n"
+"[b]警告:[/b]该函数主要供编辑器使用。对于游戏中的用例,最好是物理碰撞。"
+
+msgid ""
+"Returns an array of object IDs intersecting with the provided 3D ray. Only 3D "
+"nodes that inherit from [VisualInstance3D] are considered, such as "
+"[MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope."
+"instance_from_id] to obtain the actual nodes. A scenario RID must be "
+"provided, which is available in the [World3D] you want to query. This forces "
+"an update for all resources queued to update.\n"
+"[b]Warning:[/b] This function is primarily intended for editor usage. For in-"
+"game use cases, prefer physics collision."
+msgstr ""
+"返回与提供的 3D 射线相交的对象 ID 的数组。仅考虑继承自 [VisualInstance3D] 的 "
+"3D 节点,例如 [MeshInstance3D] 或 [DirectionalLight3D]。可使用 [method "
+"@GlobalScope.instance_from_id] 以获取实际节点。必须提供场景 RID,且它在你要查"
+"询的 [World3D] 中可用。这会强制更新所有已被队列以等待更新的资源。\n"
+"[b]警告:[/b]该函数主要供编辑器使用。对于游戏中的用例,最好是物理碰撞。"
+
+msgid ""
"If [code]true[/code], this directional light will blend between shadow map "
"splits resulting in a smoother transition between them. Equivalent to [member "
"DirectionalLight3D.directional_shadow_blend_splits]."
@@ -96780,6 +102763,13 @@ msgstr ""
"影。相当于 [member OmniLight3D.omni_shadow_mode]。"
msgid ""
+"Sets the texture filter mode to use when rendering light projectors. This "
+"parameter is global and cannot be set on a per-light basis."
+msgstr ""
+"设置渲染光线投射器时使用的纹理过滤模式。这个参数是全局的,不能单独针对某个灯光"
+"进行设置。"
+
+msgid ""
"Sets the bake mode to use for the specified 3D light. Equivalent to [member "
"Light3D.light_bake_mode]."
msgstr ""
@@ -96789,6 +102779,52 @@ msgid "Sets the color of the light. Equivalent to [member Light3D.light_color]."
msgstr "设置灯光的颜色。相当于 [member Light3D.light_color]。"
msgid ""
+"Sets the cull mask for this 3D light. Lights only affect objects in the "
+"selected layers. Equivalent to [member Light3D.light_cull_mask]."
+msgstr ""
+"设置该 3D 灯光的剔除掩码。灯光仅影响选定层中的对象。相当于 [member Light3D."
+"light_cull_mask]。"
+
+msgid ""
+"Sets the distance fade for this 3D light. This acts as a form of level of "
+"detail (LOD) and can be used to improve performance. Equivalent to [member "
+"Light3D.distance_fade_enabled], [member Light3D.distance_fade_begin], [member "
+"Light3D.distance_fade_shadow], and [member Light3D.distance_fade_length]."
+msgstr ""
+"设置该 3D 灯光的淡入淡出距离。这充当了一种多细节层次(LOD)的形式,可用于提高"
+"性能。相当于 [member Light3D.distance_fade_enabled]、[member Light3D."
+"distance_fade_begin]、[member Light3D.distance_fade_shadow] 和 [member "
+"Light3D.distance_fade_length]。"
+
+msgid ""
+"Sets the maximum SDFGI cascade in which the 3D light's indirect lighting is "
+"rendered. Higher values allow the light to be rendered in SDFGI further away "
+"from the camera."
+msgstr ""
+"设置渲染 3D 灯光间接光照时的 SDFGI 最大级联数。较高的值能够让远离相机的灯光在 "
+"SDFGI 中渲染。"
+
+msgid ""
+"If [code]true[/code], the 3D light will subtract light instead of adding "
+"light. Equivalent to [member Light3D.light_negative]."
+msgstr ""
+"如果为 [code]true[/code],则该 3D 灯光会扣除光照而不是增加。等价于 [member "
+"Light3D.light_negative]。"
+
+msgid ""
+"Sets the specified 3D light parameter. See [enum LightParam] for options. "
+"Equivalent to [method Light3D.set_param]."
+msgstr ""
+"设置指定的 3D 灯光参数。选项见 [enum LightParam]。等价于 [method Light3D."
+"set_param]。"
+
+msgid ""
+"Sets the projector texture to use for the specified 3D light. Equivalent to "
+"[member Light3D.light_projector]."
+msgstr ""
+"设置指定 3D 灯光使用的投射器纹理。等价于 [member Light3D.light_projector]。"
+
+msgid ""
"If [code]true[/code], reverses the backface culling of the mesh. This can be "
"useful when you have a flat mesh that has a light behind it. If you need to "
"cast a shadow on both sides of the mesh, set the mesh to use double-sided "
@@ -96815,10 +102851,9 @@ msgid ""
"RenderingServer's [method free_rid] method.\n"
"[b]Note:[/b] The equivalent node is [LightmapGI]."
msgstr ""
-"创建全局光照的光照贴图并将其添加到 RenderingServer。可以通过返回的 RID 进行访"
+"新建全局光照的光照贴图并将其添加到 RenderingServer。可以通过返回的 RID 进行访"
"问。这个 RID 会在所有 [code]lightmap_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]与其等价的资源为 [LightmapGI]。"
msgid ""
@@ -96833,6 +102868,23 @@ msgstr ""
"光水平。有关详细信息,请参阅 [method camera_attributes_set_exposure]。"
msgid ""
+"Set the textures on the given [param lightmap] GI instance to the texture "
+"array pointed to by the [param light] RID. If the lightmap texture was baked "
+"with [member LightmapGI.directional] set to [code]true[/code], then [param "
+"uses_sh] must also be [code]true[/code]."
+msgstr ""
+"将给定光照贴图 [param lightmap] GI 实例的纹理设置为 [param light] RID 所指向的"
+"纹理数组。如果烘焙光照贴图纹理时的 [member LightmapGI.directional] 为 "
+"[code]true[/code],则 [param uses_sh] 也必须为 [code]true[/code]。"
+
+msgid ""
+"Returns a mesh of a sphere with the given number of horizontal subdivisions, "
+"vertical subdivisions and radius. See also [method get_test_cube]."
+msgstr ""
+"返回球体网格,具有给定数量的水平细分、垂直细分、半径。另见 [method "
+"get_test_cube]。"
+
+msgid ""
"Creates an empty material and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
"[code]material_*[/code] RenderingServer functions.\n"
@@ -96842,8 +102894,7 @@ msgid ""
msgstr ""
"创建空材质并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID "
"会在所有 [code]material_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]与其等价的资源为 [Material]。"
msgid "Returns the value of a certain material's parameter."
@@ -96876,8 +102927,7 @@ msgid ""
msgstr ""
"新建网格并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID 会"
"在所有 [code]mesh_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个网格放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]与其等价的资源为 [Mesh]。"
@@ -96924,8 +102974,7 @@ msgid ""
msgstr ""
"新建多网格并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID "
"会在所有 [code]multimesh_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个多网格放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]与其等价的资源为 [MultiMesh]。"
@@ -96933,7 +102982,20 @@ msgstr ""
msgid ""
"Calculates and returns the axis-aligned bounding box that encloses all "
"instances within the multimesh."
-msgstr "计算并返回轴对齐的包围盒,该包围盒将所有的实例都包含在 multimesh 中。"
+msgstr "计算并返回轴对齐的边界框,该边界框将所有的实例都包含在 multimesh 中。"
+
+msgid ""
+"Returns the MultiMesh data (such as instance transforms, colors, etc). See "
+"[method multimesh_set_buffer] for a description of the returned data.\n"
+"[b]Note:[/b] If the buffer is in the engine's internal cache, it will have to "
+"be fetched from GPU memory and possibly decompressed. This means [method "
+"multimesh_get_buffer] is potentially a slow operation and should be avoided "
+"whenever possible."
+msgstr ""
+"返回 MultiMesh 数据(实例的变换、颜色等)。返回数据的描述见 [method "
+"multimesh_set_buffer]。\n"
+"[b]注意:[/b]如果缓冲位于引擎的内部缓存中,则需要从 GPU 显存获取,并且有可能需"
+"要解压。也就是说 [method multimesh_get_buffer] 可能会比较慢,应该尽可能避免。"
msgid "Returns the number of instances allocated for this multimesh."
msgstr "返回分配给这个 multimesh 的实例的数量。"
@@ -97059,8 +103121,7 @@ msgid ""
msgstr ""
"创建遮挡器实例并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]occluder_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]与其等价的资源为 [Occluder3D](请勿与 [OccluderInstance3D] 节点混"
"淆)。"
@@ -97081,8 +103142,8 @@ msgid ""
msgstr ""
"创建一个新的全向灯并将其添加到 RenderingServer。可以使用返回的 RID 访问它。该 "
"RID 可用于大多数 [code]light_*[/code] RenderingServer 函数。\n"
-"一旦使用 RID 完成操作后,需要使用 RenderingServer 的静态方法 [method "
-"free_rid] 来释放该 RID。\n"
+"一旦使用 RID 完成操作后,需要使用 RenderingServer 的方法 [method free_rid] 来"
+"释放该 RID。\n"
"要放置在场景中,请使用 [method instance_set_base] 使用该返回的 RID 将该全向灯"
"附加到一个实例。\n"
"[b]注意:[/b]等价节点为 [OmniLight3D]。"
@@ -97219,8 +103280,7 @@ msgid ""
msgstr ""
"创建基于 GPU 的粒子系统并将其添加到 RenderingServer。可以通过返回的 RID 进行访"
"问。这个 RID 会在所有 [code]particles_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个粒子系统放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]等价节点为 [GPUParticles2D] 和 [GPUParticles3D]。\n"
@@ -97417,8 +103477,7 @@ msgid ""
msgstr ""
"创建反射探针并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]reflection_probe_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个反射探针放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]等价节点为 [ReflectionProbe]。"
@@ -97612,8 +103671,7 @@ msgid ""
msgstr ""
"创建空的着色器并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]shader_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [Shader]。"
msgid "Returns a shader's source code as a string."
@@ -97673,8 +103731,7 @@ msgid ""
msgstr ""
"创建骨架并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID 会"
"在所有 [code]skeleton_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
msgid "Returns the number of bones allocated for this skeleton."
msgstr "返回分配给这个骨架的骨骼数量。"
@@ -97717,8 +103774,7 @@ msgid ""
msgstr ""
"创建空的天空并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]sky_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。"
msgid ""
"Sets the material that the sky uses to render the background, ambient and "
@@ -97750,8 +103806,7 @@ msgid ""
msgstr ""
"创建聚光灯并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 RID "
"会在大多数 [code]light_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个聚光灯放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。"
@@ -97787,8 +103842,7 @@ msgid ""
msgstr ""
"创建二维纹理并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]texture_2d_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [Texture2D]。\n"
"[b]注意:[/b]请勿与 [method RenderingDevice.texture_create] 混淆,后者创建的是"
"图形 API 自己的纹理类型,并非 Godot 专属的 [Texture2D] 资源。"
@@ -97830,8 +103884,7 @@ msgstr ""
"创建二维多层纹理并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这"
"个 RID 会在所有 [code]texture_2d_layered_*[/code] RenderingServer 函数中使"
"用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [TextureLayered]。"
msgid ""
@@ -97862,8 +103915,7 @@ msgstr ""
"访问。这个 RID 会在所有 [code]texture_2d_layered_*[/code] RenderingServer 函数"
"中使用,但使用时什么都不会发生。另见 [method "
"texture_2d_layered_placeholder_create]。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [PlaceholderTexture2D]。"
msgid ""
@@ -97885,6 +103937,11 @@ msgid "[b]Note:[/b] The equivalent resource is [Texture3D]."
msgstr "[b]注意:[/b]等价的资源是 [Texture3D]。"
msgid ""
+"Returns 3D texture data as an array of [Image]s for the specified texture "
+"[RID]."
+msgstr "以 [Image] 数组的形式返回指定纹理 [RID] 的 3D 纹理数据。"
+
+msgid ""
"Creates a placeholder for a 3-dimensional texture and adds it to the "
"RenderingServer. It can be accessed with the RID that is returned. This RID "
"will be used in all [code]texture_3d_*[/code] RenderingServer functions, "
@@ -97895,8 +103952,7 @@ msgid ""
msgstr ""
"创建三维纹理的占位符并将其添加到 RenderingServer。可以通过返回的 RID 进行访"
"问。这个 RID 会在所有 [code]texture_3d_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价资源为 [PlaceholderTexture3D]。"
msgid ""
@@ -97991,8 +104047,7 @@ msgid ""
msgstr ""
"创建空的视口并将其添加到 RenderingServer。可以通过返回的 RID 进行访问。这个 "
"RID 会在所有 [code]viewport_*[/code] RenderingServer 函数中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [Viewport]。"
msgid ""
@@ -98049,6 +104104,54 @@ msgstr ""
"viewport_get_measured_render_time_gpu] 进行性能测试时牢记这一点。可以在显卡驱"
"动的设置中改变这种行为,但代价是耗电量增大。"
+msgid ""
+"Returns a statistic about the rendering engine which can be used for "
+"performance profiling. This is separated into render pass [param type]s, each "
+"of them having the same [param info]s you can query (different passes will "
+"return different values). See [enum RenderingServer.ViewportRenderInfoType] "
+"for a list of render pass types and [enum RenderingServer.ViewportRenderInfo] "
+"for a list of information that can be queried.\n"
+"See also [method get_rendering_info], which returns global information across "
+"all viewports.\n"
+"[b]Note:[/b] Viewport rendering information is not available until at least 2 "
+"frames have been rendered by the engine. If rendering information is not "
+"available, [method viewport_get_render_info] returns [code]0[/code]. To print "
+"rendering information in [code]_ready()[/code] successfully, use the "
+"following:\n"
+"[codeblock]\n"
+"func _ready():\n"
+" for _i in 2:\n"
+" await get_tree().process_frame\n"
+"\n"
+" print(\n"
+" RenderingServer.viewport_get_render_info(get_viewport()."
+"get_viewport_rid(),\n"
+" RenderingServer.VIEWPORT_RENDER_INFO_TYPE_VISIBLE,\n"
+" RenderingServer.VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME)\n"
+" )\n"
+"[/codeblock]"
+msgstr ""
+"返回关于渲染引擎的统计信息,能够用于性能分析。会区分不同的渲染阶段类型 [param "
+"type],每种类型都有相同的可查询信息 [param info](不同的阶段会返回不同的值)。"
+"渲染阶段类型列表见 [enum RenderingServer.ViewportRenderInfoType],能够查询的信"
+"息列表见 [enum RenderingServer.ViewportRenderInfo]。\n"
+"另见 [method get_rendering_info],返回的是所有视口的全局信息。\n"
+"[b]注意:[/b]引擎渲染至少 2 帧后渲染信息才可用。渲染信息不可用时 [method "
+"viewport_get_render_info] 返回 [code]0[/code]。要在 [code]_ready()[/code] 中成"
+"功输出渲染信息,请使用如下代码:\n"
+"[codeblock]\n"
+"func _ready():\n"
+" for _i in 2:\n"
+" await get_tree().process_frame\n"
+"\n"
+" print(\n"
+" RenderingServer.viewport_get_render_info(get_viewport()."
+"get_viewport_rid(),\n"
+" RenderingServer.VIEWPORT_RENDER_INFO_TYPE_VISIBLE,\n"
+" RenderingServer.VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME)\n"
+" )\n"
+"[/codeblock]"
+
msgid "Returns the render target for the viewport."
msgstr "返回该视口的渲染目标。"
@@ -98092,6 +104195,28 @@ msgid ""
msgstr "设置视口的调试绘图模式。可选项见 [enum ViewportDebugDraw]。"
msgid ""
+"Sets the default texture filtering mode for the specified [param viewport] "
+"RID. See [enum CanvasItemTextureFilter] for options."
+msgstr ""
+"设置视口的默认纹理过滤模式,视口由 [param viewport] RID 指定。选项见 [enum "
+"CanvasItemTextureFilter]。"
+
+msgid ""
+"Sets the default texture repeat mode for the specified [param viewport] RID. "
+"See [enum CanvasItemTextureRepeat] for options."
+msgstr ""
+"设置视口的默认纹理重复模式,视口由 [param viewport] RID 指定。选项见 [enum "
+"CanvasItemTextureRepeat]。"
+
+msgid ""
+"If [code]true[/code], the viewport's canvas (i.e. 2D and GUI elements) is not "
+"rendered."
+msgstr "如果为 [code]true[/code],则不渲染视口的画布(即 2D 和 GUI 元素)。"
+
+msgid "If [code]true[/code], the viewport's 3D elements are not rendered."
+msgstr "如果为 [code]true[/code],则不渲染视口的 3D 元素。"
+
+msgid ""
"Sets the viewport's environment mode which allows enabling or disabling "
"rendering of 3D environment over 2D canvas. When disabled, 2D will not be "
"affected by the environment. When enabled, 2D will be affected by the "
@@ -98111,6 +104236,19 @@ msgid "Sets the viewport's global transformation matrix."
msgstr "设置视口的全局变换矩阵。"
msgid ""
+"Sets the measurement for the given [param viewport] RID (obtained using "
+"[method Viewport.get_viewport_rid]). Once enabled, [method "
+"viewport_get_measured_render_time_cpu] and [method "
+"viewport_get_measured_render_time_gpu] will return values greater than "
+"[code]0.0[/code] when queried with the given [param viewport]."
+msgstr ""
+"为给定的 [param viewport] RID(使用 [method Viewport.get_viewport_rid] 获取)"
+"设置是否测量。启用后,使用给定的 [param viewport] 对 [method "
+"viewport_get_measured_render_time_cpu] 和 [method "
+"viewport_get_measured_render_time_gpu] 进行查询返回的就是大于 [code]0.0[/"
+"code] 的值。"
+
+msgid ""
"Sets the multisample anti-aliasing mode for 2D/Canvas on the specified [param "
"viewport] RID. See [enum ViewportMSAA] for options."
msgstr ""
@@ -98141,6 +104279,40 @@ msgstr ""
"occlusion_rays_per_thread]。这个参数是全局的,无法针对特定视口设置。"
msgid ""
+"Sets the viewport's parent to the viewport specified by the [param "
+"parent_viewport] RID."
+msgstr "将该视口的父项设置为 [param parent_viewport] RID 指定的视口。"
+
+msgid ""
+"Sets the number of subdivisions to use in the specified shadow atlas [param "
+"quadrant] for omni and spot shadows. See also [method Viewport."
+"set_positional_shadow_atlas_quadrant_subdiv]."
+msgstr ""
+"设置全向灯和聚光灯阴影的指定阴影图集象限 [param quadrant] 的细分次数。另见 "
+"[method Viewport.set_positional_shadow_atlas_quadrant_subdiv]。"
+
+msgid ""
+"Sets the [param size] of the shadow atlas's images (used for omni and spot "
+"lights) on the viewport specified by the [param viewport] RID. The value is "
+"rounded up to the nearest power of 2. If [param use_16_bits] is [code]true[/"
+"code], use 16 bits for the omni/spot shadow depth map. Enabling this results "
+"in shadows having less precision and may result in shadow acne, but can lead "
+"to performance improvements on some devices.\n"
+"[b]Note:[/b] If this is set to [code]0[/code], no positional shadows will be "
+"visible at all. This can improve performance significantly on low-end systems "
+"by reducing both the CPU and GPU load (as fewer draw calls are needed to draw "
+"the scene without shadows)."
+msgstr ""
+"设置阴影图集图像的大小(用于全向灯和聚光灯),大小由 [param size] 指定,生效的"
+"视口由 [param viewport] RID 指定。该值将向上舍入到最接近的 2 次幂。如果 "
+"[param use_16_bits] 为 [code]true[/code],则会使用 16 位的全向灯/聚光灯阴影深"
+"度贴图。启用后,阴影的精度会降低,可能造成阴影失真,但能够在部分设备上提升性"
+"能。\n"
+"[b]注意:[/b]如果设置为 [code]0[/code],将根本看不到任何阴影。可以通过降低 "
+"CPU 和 GPU 负载来显著提升在低端系统上的性能(因为绘制不带阴影的场景需要的绘制"
+"调用更少)。"
+
+msgid ""
"If [code]true[/code], render the contents of the viewport directly to screen. "
"This allows a low-level optimization where you can skip drawing a viewport to "
"the root viewport. While this optimization can result in a significant "
@@ -98162,6 +104334,20 @@ msgstr ""
"性,那么只会绘制适合窗口的部分, 无法自动缩放,即使游戏场景明显大于窗口大小。"
msgid ""
+"Sets the 3D resolution scaling mode. Bilinear scaling renders at different "
+"resolution to either undersample or supersample the viewport. FidelityFX "
+"Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that "
+"produces high quality images at fast framerates by using a spatially aware "
+"upscaling algorithm. FSR is slightly more expensive than bilinear, but it "
+"produces significantly higher image quality. FSR should be used where "
+"possible."
+msgstr ""
+"设置 3D 分辨率缩放模式。双线性缩放使用不同的分辨率渲染,能够对视口进行欠采样或"
+"超采样。FidelityFX 超分辨率 1.0,缩写为 FSR,是一种放大技术,通过使用空间感知"
+"放大算法以快速帧速率生成高质量图像。FSR 比双线性的开销略大,但产生的图像质量明"
+"显更高。应尽可能使用 FSR。"
+
+msgid ""
"Scales the 3D render buffer based on the viewport size uses an image filter "
"specified in [enum ViewportScaling3DMode] to scale the output image to the "
"full viewport size. Values lower than [code]1.0[/code] can be used to speed "
@@ -98321,8 +104507,7 @@ msgstr ""
"新建 3D 可见性通知对象并将其添加到 RenderingServer。可以通过返回的 RID 进行访"
"问。这个 RID 会在所有 [code]visibility_notifier_*[/code] RenderingServer 函数"
"中使用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"如果要将这个网格放置到场景中,请使用返回的 RID 调用 [method "
"instance_set_base],将其附加至某个实例上。\n"
"[b]注意:[/b]等价节点为 [VisibleOnScreenNotifier3D]。"
@@ -98338,8 +104523,7 @@ msgstr ""
"新建基于体素的全局光照对象并将其添加到 RenderingServer。可以通过返回的 RID 进"
"行访问。这个 RID 会在所有 [code]voxel_gi_*[/code] RenderingServer 函数中使"
"用。\n"
-"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 静态方法进行释"
-"放。\n"
+"RID 使用结束后,应该使用 RenderingServer 的 [method free_rid] 方法进行释放。\n"
"[b]注意:[/b]等价节点为 [VoxelGI]。"
msgid ""
@@ -98410,7 +104594,7 @@ msgid ""
"with rendering disabled."
msgstr ""
"如果为 [code]false[/code],则完全禁用渲染,但引擎逻辑仍在处理中。即使禁用渲"
-"染,您也可以调用 [method force_draw] 来绘制帧。"
+"染,你也可以调用 [method force_draw] 来绘制帧。"
msgid ""
"Emitted at the end of the frame, after the RenderingServer has finished "
@@ -98824,6 +105008,16 @@ msgstr ""
"模糊阴影的边缘。可用于隐藏低分辨率阴影贴图中的像素伪影。较高的值会使阴影显得粗"
"糙,并可能导致其他不需要的伪影。尽量保持接近默认值。"
+msgid ""
+"Constant representing the intensity of the light, measured in Lumens when "
+"dealing with a [SpotLight3D] or [OmniLight3D], or measured in Lux with a "
+"[DirectionalLight3D]. Only used when [member ProjectSettings.rendering/"
+"lights_and_shadows/use_physical_light_units] is [code]true[/code]."
+msgstr ""
+"代表灯光强度的常量,[SpotLight3D] 和 [OmniLight3D] 的单位为流明,"
+"[DirectionalLight3D] 的单位为勒克斯。仅在 [member ProjectSettings.rendering/"
+"lights_and_shadows/use_physical_light_units] 为 [code]true[/code] 时使用。"
+
msgid "Represents the size of the [enum LightParam] enum."
msgstr "代表 [enum LightParam] 枚举的大小。"
@@ -98836,6 +105030,23 @@ msgstr ""
"烘焙时灯光将被忽略。这是最快的模式,但是在烘焙全局照明时仍会考虑该灯光。该模式"
"通常应用于快速变化的动态灯光,因为全局照明的效果在这些灯光上不太明显。"
+msgid ""
+"Light is taken into account in dynamic baking ([VoxelGI] and SDFGI ([member "
+"Environment.sdfgi_enabled]) only). The light can be moved around or modified "
+"with global illumination updating in real-time. The light's global "
+"illumination appearance will be slightly different compared to [constant "
+"LIGHT_BAKE_STATIC]. This has a greater performance cost compared to [constant "
+"LIGHT_BAKE_STATIC]. When using SDFGI, the update speed of dynamic lights is "
+"affected by [member ProjectSettings.rendering/global_illumination/sdfgi/"
+"frames_to_update_lights]."
+msgstr ""
+"动态烘焙时考虑灯光(仅 [VoxelGI] 和 SDFGI([member Environment."
+"sdfgi_enabled]))。灯光可以四处移动或修改,全局照明会实时更新。灯光的全局照明"
+"效果与 [constant LIGHT_BAKE_STATIC] 略有不同。性能开销比 [constant "
+"LIGHT_BAKE_STATIC] 更大。使用 SDFGI 时,动态灯光的更新速度受 [member "
+"ProjectSettings.rendering/global_illumination/sdfgi/frames_to_update_lights] "
+"的影响。"
+
msgid "Use a dual paraboloid shadow map for omni lights."
msgstr "对全向光使用双抛物面阴影贴图。"
@@ -98936,6 +105147,25 @@ msgid ""
"moving objects."
msgstr "反射探针将每帧更新。这种模式对于捕捉移动物体是必要的。"
+msgid ""
+"Do not apply any ambient lighting inside the reflection probe's box defined "
+"by its size."
+msgstr "不要在反射探针的区域内应用任何环境光,区域由探针的大小决定。"
+
+msgid ""
+"Apply automatically-sourced environment lighting inside the reflection "
+"probe's box defined by its size."
+msgstr "在反射探针的区域内应用自动来源的环境光照,区域由探针的大小决定。"
+
+msgid ""
+"Apply custom ambient lighting inside the reflection probe's box defined by "
+"its size. See [method reflection_probe_set_ambient_color] and [method "
+"reflection_probe_set_ambient_energy]."
+msgstr ""
+"在反射探针的区域内应用自定义环境光,区域由探针的大小决定。见 [method "
+"reflection_probe_set_ambient_color] 和 [method "
+"reflection_probe_set_ambient_energy]。"
+
msgid "Albedo texture slot in a decal ([member Decal.texture_albedo])."
msgstr "贴花中的反照率纹理([member Decal.texture_albedo])。"
@@ -99105,7 +105335,8 @@ msgstr "不要更新视口的渲染目标。"
msgid ""
"Update the viewport's render target once, then switch to [constant "
"VIEWPORT_UPDATE_DISABLED]."
-msgstr "更新一次视口的渲染目标,然后切换到 [constant UPDATE_DISABLED]。"
+msgstr ""
+"更新一次视口的渲染目标,然后切换到 [constant VIEWPORT_UPDATE_DISABLED]。"
msgid ""
"Update the viewport's render target only when it is visible. This is the "
@@ -99127,7 +105358,8 @@ msgstr "永不清除视口的渲染目标。"
msgid ""
"Clear the viewport's render target on the next frame, then switch to "
"[constant VIEWPORT_CLEAR_NEVER]."
-msgstr "在下一帧清除视口的渲染目标,然后切换到 [constant CLEAR_MODE_NEVER]。"
+msgstr ""
+"在下一帧清除视口的渲染目标,然后切换到 [constant VIEWPORT_CLEAR_NEVER]。"
msgid "Disable rendering of 3D environment over 2D canvas."
msgstr "禁用在 2D 画布上渲染 3D 环境。"
@@ -99135,9 +105367,46 @@ msgstr "禁用在 2D 画布上渲染 3D 环境。"
msgid "Enable rendering of 3D environment over 2D canvas."
msgstr "启用在 2D 画布上渲染 3D 环境。"
+msgid ""
+"Inherit enable/disable value from parent. If the topmost parent is also set "
+"to [constant VIEWPORT_ENVIRONMENT_INHERIT], then this has the same behavior "
+"as [constant VIEWPORT_ENVIRONMENT_ENABLED]."
+msgstr ""
+"从父级继承启用/禁用值。如果最顶层的父级也被设置为 [constant "
+"VIEWPORT_ENVIRONMENT_INHERIT],那么与 [constant VIEWPORT_ENVIRONMENT_ENABLED] "
+"的行为相同。"
+
msgid "Represents the size of the [enum ViewportEnvironmentMode] enum."
msgstr "代表 [enum ViewportEnvironmentMode] 枚举的大小。"
+msgid ""
+"Do not oversize the 2D signed distance field. Occluders may disappear when "
+"touching the viewport's edges, and [GPUParticles3D] collision may stop "
+"working earlier than intended. This has the lowest GPU requirements."
+msgstr ""
+"不使用过大的 2D 带符号距离场。遮挡器可能在接触视口边缘时消失,"
+"[GPUParticles3D] 碰撞也可能比预期更早地停止工作。对 GPU 的要求最低。"
+
+msgid ""
+"2D signed distance field covers 20% of the viewport's size outside the "
+"viewport on each side (top, right, bottom, left)."
+msgstr ""
+"2D 带符号距离场在每个方向(上、右、下、左)都覆盖超出视口大小 20% 的范围。"
+
+msgid ""
+"2D signed distance field covers 50% of the viewport's size outside the "
+"viewport on each side (top, right, bottom, left)."
+msgstr ""
+"2D 带符号距离场在每个方向(上、右、下、左)都覆盖超出视口大小 50% 的范围。"
+
+msgid ""
+"2D signed distance field covers 100% of the viewport's size outside the "
+"viewport on each side (top, right, bottom, left). This has the highest GPU "
+"requirements."
+msgstr ""
+"2D 带符号距离场在每个方向(上、右、下、左)都覆盖超出视口大小 100% 的范围。对 "
+"GPU 的要求最高。"
+
msgid "Represents the size of the [enum ViewportSDFOversize] enum."
msgstr "代表 [enum ViewportSDFOversize] 枚举的大小。"
@@ -99202,9 +105471,27 @@ msgstr ""
msgid "Represents the size of the [enum ViewportScreenSpaceAA] enum."
msgstr "代表 [enum ViewportScreenSpaceAA] 枚举的大小。"
+msgid ""
+"Low occlusion culling BVH build quality (as defined by Embree). Results in "
+"the lowest CPU usage, but least effective culling."
+msgstr ""
+"较低的遮挡剔除 BVH 构建质量(由 Embree 定义)。CPU 占用最低,但剔除效率最低。"
+
+msgid "Medium occlusion culling BVH build quality (as defined by Embree)."
+msgstr "中等的遮挡剔除 BVH 构建质量(由 Embree 定义)。"
+
+msgid ""
+"High occlusion culling BVH build quality (as defined by Embree). Results in "
+"the highest CPU usage, but most effective culling."
+msgstr ""
+"较高的遮挡剔除 BVH 构建质量(由 Embree 定义)。CPU 占用最高,但剔除效率最高。"
+
msgid "Number of objects drawn in a single frame."
msgstr "在单帧中绘制的对象的数量。"
+msgid "Number of points, lines, or triangles drawn in a single frame."
+msgstr "在单帧中绘制的点、线、三角形的数量。"
+
msgid "Number of draw calls during this frame."
msgstr "此帧期间的绘制调用数。"
@@ -99279,6 +105566,13 @@ msgstr ""
"在 [Viewport] 的左上象限中绘制存储来自 [DirectionalLight3D] 的阴影的阴影图集。"
msgid ""
+"Draws the estimated scene luminance. This is a 1×1 texture that is generated "
+"when autoexposure is enabled to control the scene's exposure."
+msgstr ""
+"绘制估计的场景亮度。这是一个 1×1 的纹理,启用自动曝光时生成,用于控制场景的曝"
+"光。"
+
+msgid ""
"Draws the screen space ambient occlusion texture instead of the scene so that "
"you can clearly see how it is affecting objects. In order for this display "
"mode to work, you must have [member Environment.ssao_enabled] set in your "
@@ -99360,10 +105654,76 @@ msgstr ""
"绘制 [ReflectionProbe] 集群。集群决定屏幕空间中反射探针的放置位置,能够让引擎"
"在处理反射探针时仅对屏幕的部分区域进行处理。"
+msgid ""
+"Draws the occlusion culling buffer. This low-resolution occlusion culling "
+"buffer is rasterized on the CPU and is used to check whether instances are "
+"occluded by other objects."
+msgstr ""
+"绘制遮挡剔除缓冲。这个低分辨率遮挡剔除缓冲在 CPU 栅格化,可用于检查实例是否被"
+"其他对象遮挡。"
+
+msgid ""
+"Draws the motion vectors buffer. This is used by temporal antialiasing to "
+"correct for motion that occurs during gameplay."
+msgstr "绘制运动向量缓冲。由时间抗锯齿使用,能够修正在游戏过程中发生的运动。"
+
+msgid "Variable rate shading is disabled."
+msgstr "可变速率着色已禁用。"
+
+msgid ""
+"Variable rate shading uses a texture. Note, for stereoscopic use a texture "
+"atlas with a texture for each view."
+msgstr ""
+"可变速率着色使用纹理。请注意,对于立体视觉,请使用为每个视图提供纹理的纹理图"
+"集。"
+
+msgid "Variable rate shading texture is supplied by the primary [XRInterface]."
+msgstr "可变速率着色纹理由主 [XRInterface] 提供。"
+
msgid "Represents the size of the [enum ViewportVRSMode] enum."
msgstr "代表 [enum ViewportVRSMode] 枚举的大小。"
msgid ""
+"Automatically selects the appropriate process mode based on your sky shader. "
+"If your shader uses [code]TIME[/code] or [code]POSITION[/code], this will use "
+"[constant SKY_MODE_REALTIME]. If your shader uses any of the [code]LIGHT_*[/"
+"code] variables or any custom uniforms, this uses [constant "
+"SKY_MODE_INCREMENTAL]. Otherwise, this defaults to [constant "
+"SKY_MODE_QUALITY]."
+msgstr ""
+"根据天空着色器自动选择合适的处理模式。如果着色器使用 [code]TIME[/code] 或 "
+"[code]POSITION[/code],则会使用 [constant SKY_MODE_REALTIME]。如果着色器使用任"
+"何 [code]LIGHT_*[/code] 变量或任何自定义 uniform,则会使用 [constant "
+"SKY_MODE_INCREMENTAL]。否则默认为 [constant SKY_MODE_QUALITY]。"
+
+msgid ""
+"Uses high quality importance sampling to process the radiance map. In "
+"general, this results in much higher quality than [constant "
+"SKY_MODE_REALTIME] but takes much longer to generate. This should not be used "
+"if you plan on changing the sky at runtime. If you are finding that the "
+"reflection is not blurry enough and is showing sparkles or fireflies, try "
+"increasing [member ProjectSettings.rendering/reflections/sky_reflections/"
+"ggx_samples]."
+msgstr ""
+"使用高质量重要性采样处理辐射度贴图。得到的结果通常比 [constant "
+"SKY_MODE_REALTIME] 的质量更高,但需要花费更多的时间来生成。如果你计划在运行时"
+"修改天空,则不应使用。如果你发现反射不够模糊,出现了火花或者萤火虫,请尝试增"
+"大 [member ProjectSettings.rendering/reflections/sky_reflections/"
+"ggx_samples]。"
+
+msgid ""
+"Uses the same high quality importance sampling to process the radiance map as "
+"[constant SKY_MODE_QUALITY], but updates over several frames. The number of "
+"frames is determined by [member ProjectSettings.rendering/reflections/"
+"sky_reflections/roughness_layers]. Use this when you need highest quality "
+"radiance maps, but have a sky that updates slowly."
+msgstr ""
+"使用与 [constant SKY_MODE_QUALITY] 相同的高质量重要性采样来处理辐射度贴图,但"
+"更新会占用若干帧。帧数由 [member ProjectSettings.rendering/reflections/"
+"sky_reflections/roughness_layers] 决定。当需要最高质量的辐射度贴图,但天空更新"
+"缓慢时,请使用该选项。"
+
+msgid ""
"Uses the fast filtering algorithm to process the radiance map. In general "
"this results in lower quality, but substantially faster run times. If you "
"need better quality, but still need to update the sky every frame, consider "
@@ -99377,9 +105737,9 @@ msgstr ""
"快。如果需要更好的质量,但仍需要每帧更新天空,请考虑开启 [member "
"ProjectSettings.rendering/reflections/sky_reflections/"
"fast_filter_high_quality]。\n"
-"[b]注意:[/b]快速过滤算法被限制为 256x256 立方体贴图,因此 [member "
-"radiance_size] 必须被设置为 [code]256[/code]。否则会打印警告并忽略对辐照度大小"
-"的覆盖。"
+"[b]注意:[/b]快速过滤算法被限制为 256x256 立方体贴图,因此 [method "
+"sky_set_radiance_size] 必须被设置为 [code]256[/code]。否则会打印警告并忽略对辐"
+"照度大小的覆盖。"
msgid "Use the clear color as background."
msgstr "用透明的颜色作为背景。"
@@ -100073,6 +106433,28 @@ msgstr ""
msgid "Texture memory used (in bytes)."
msgstr "纹理内存的使用量(单位为字节)。"
+msgid ""
+"Buffer memory used (in bytes). This includes vertex data, uniform buffers, "
+"and many miscellaneous buffer types used internally."
+msgstr ""
+"缓冲内存的使用量(单位为字节)。包括顶点数据、uniform 缓冲以及内部使用的各种不"
+"同缓冲类型。"
+
+msgid ""
+"Video memory used (in bytes). When using the Forward+ or mobile rendering "
+"backends, this is always greater than the sum of [constant "
+"RENDERING_INFO_TEXTURE_MEM_USED] and [constant "
+"RENDERING_INFO_BUFFER_MEM_USED], since there is miscellaneous data not "
+"accounted for by those two metrics. When using the GL Compatibility backend, "
+"this is equal to the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and "
+"[constant RENDERING_INFO_BUFFER_MEM_USED]."
+msgstr ""
+"显存的使用量(单位为字节)。使用 Forward+ 或移动渲染后端时,始终比 [constant "
+"RENDERING_INFO_TEXTURE_MEM_USED] 与 [constant RENDERING_INFO_BUFFER_MEM_USED] "
+"的总和要大,因为这两项之外还有一些杂项数据。使用 GL Compatibility 后端时,等"
+"于 [constant RENDERING_INFO_TEXTURE_MEM_USED] 与 [constant "
+"RENDERING_INFO_BUFFER_MEM_USED] 之和。"
+
msgid "Hardware supports shaders. This enum is currently unused in Godot 3.x."
msgstr "硬件支持着色器。这个枚举目前在 Godot 3.x 中没有使用。"
@@ -100261,15 +106643,29 @@ msgstr ""
"本,该名称会在脚本编辑器中作为选项卡名称的一部分显示。"
msgid ""
+"The unique path to this resource. If it has been saved to disk, the value "
+"will be its filepath. If the resource is exclusively contained within a "
+"scene, the value will be the [PackedScene]'s filepath, followed by a unique "
+"identifier.\n"
+"[b]Note:[/b] Setting this property manually may fail if a resource with the "
+"same path has already been previously loaded. If necessary, use [method "
+"take_over_path]."
+msgstr ""
+"该资源的唯一路径。如果已被保存到磁盘,该值将是其文件路径。如果该资源仅包含在某"
+"一个场景中,该值将是 [PackedScene] 的文件路径后加上一个唯一标识符。\n"
+"[b]注意:[/b]如果之前已经加载了具有相同路径的资源,手动设置该属性可能会失败。"
+"如果有必要,请使用 [method take_over_path]。"
+
+msgid ""
"Emitted when the resource changes, usually when one of its properties is "
"modified. See also [method emit_changed].\n"
"[b]Note:[/b] This signal is not emitted automatically for properties of "
"custom resources. If necessary, a setter needs to be created to emit the "
"signal."
msgstr ""
-"当资源发生更改时发出信号,通常是当其属性之一被修改时。另请参见 [method "
+"当资源发生更改时发出信号,通常是当其属性之一被修改时。另见 [method "
"emit_changed] 。\n"
-"[b]注意:[/b] 自定义资源的属性不会自动发出此信号。如有必要,需要创建一个 "
+"[b]注意:[/b]自定义资源的属性不会自动发出此信号。如有必要,需要创建一个 "
"setter 来触发。"
msgid ""
@@ -100306,14 +106702,14 @@ msgstr ""
"[ResourceLoader] 单例自动查询,或在加载具有内部依赖项的资源时自动查询。每种文"
"件类型可以作为不同的资源类型加载,因此在引擎中注册多个 "
"ResourceFormatLoaders。\n"
-"扩展此类可让您定义自己的加载器。请确保遵守文档中记录的返回类型和值。您应该使"
+"扩展此类可让你定义自己的加载器。请确保遵守文档中记录的返回类型和值。你应该使"
"用 [code]class_name[/code] 给它一个全局类名以进行注册。像内置的 "
-"ResourceFormatLoaders 一样,当加载其处理的类型的资源时,它将自动被调用。您还可"
+"ResourceFormatLoaders 一样,当加载其处理的类型的资源时,它将自动被调用。你还可"
"以实现 [ResourceFormatSaver]。\n"
-"[b]注意:[/b] 如果您需要的资源类型存在,但 Godot 无法加载其格式,则也可以扩展 "
+"[b]注意:[/b]如果你需要的资源类型存在,但 Godot 无法加载其格式,则也可以扩展 "
"[EditorImportPlugin]。选择哪种方法取决于该格式是否适用于最终导出的游戏。例如,"
-"最好首先将 [code].png[/code] 纹理作为 [code].ctex[/code] "
-"([CompressedTexture2D]) 导入,以便在图形卡上能更高效的加载它们。"
+"最好首先将 [code].png[/code] 纹理作为 [code].ctex[/code]"
+"([CompressedTexture2D])导入,以便在图形卡上能更高效的加载它们。"
msgid ""
"If implemented, gets the dependencies of a given resource. If [param "
@@ -100347,7 +106743,7 @@ msgid ""
msgstr ""
"获取与给定路径相关的资源的类名。如果加载器不能处理它,它应该返回 [code]\"\"[/"
"code]。\n"
-"[b]注意:[/b][ClassDB] 不知道脚本定义的自定义资源类型,因此您可能只为它们返回 "
+"[b]注意:[/b][ClassDB] 不知道脚本定义的自定义资源类型,因此你可能只为它们返回 "
"[code]\"Resource\"[/code]。"
msgid ""
@@ -100356,7 +106752,7 @@ msgid ""
"[ClassDB], so you might just handle [code]\"Resource\"[/code] for them."
msgstr ""
"说明这个加载器可以加载哪个资源类。\n"
-"[b]注意:[/b][ClassDB] 不知道脚本定义的自定义资源类型,因此您可以只为它们处理 "
+"[b]注意:[/b][ClassDB] 不知道脚本定义的自定义资源类型,因此你可以只为它们处理 "
"[code]\"Resource\"[/code]。"
msgid ""
@@ -100412,10 +106808,10 @@ msgid ""
"ResourceFormatSavers, it will be called automatically when saving resources "
"of its recognized type(s). You may also implement a [ResourceFormatLoader]."
msgstr ""
-"当您从编辑器执行此操作或使用 [ResourceSaver] 单例时,引擎可以节省资源。这要归"
+"当你从编辑器执行此操作或使用 [ResourceSaver] 单例时,引擎可以节省资源。这要归"
"功于多个 [ResourceFormatSaver],每个都处理自己的格式并由引擎自动调用。\n"
"默认情况下,Godot 将资源保存为 [code].tres[/code](基于文本)、[code].res[/"
-"code](二进制)或其他内置格式,但您可以选择通过扩展这个类来创建自己的格式。请"
+"code](二进制)或其他内置格式,但你可以选择通过扩展这个类来创建自己的格式。请"
"务必遵守记录的返回类型和值。你应该给它一个全局类名 [code]class_name[/code] 以"
"便它被注册。与内置的 ResourceFormatSaver 一样,它会在保存其识别类型的资源时自"
"动调用。你也可以实现一个 [ResourceFormatLoader]。"
@@ -100486,6 +106882,23 @@ msgid "A singleton for loading resource files."
msgstr "用于加载资源文件的单例。"
msgid ""
+"A singleton used to load resource files from the filesystem.\n"
+"It uses the many [ResourceFormatLoader] classes registered in the engine "
+"(either built-in or from a plugin) to load files into memory and convert them "
+"to a format that can be used by the engine.\n"
+"[b]Note:[/b] You have to import the files into the engine first to load them "
+"using [method load]. If you want to load [Image]s at run-time, you may use "
+"[method Image.load]. If you want to import audio files, you can use the "
+"snippet described in [member AudioStreamMP3.data]."
+msgstr ""
+"用于从文件系统加载资源文件的单例。\n"
+"会使用引擎中(内置或插件)注册的许多 [ResourceFormatLoader] 类将文件加载到内存"
+"中并将其转换为引擎可以使用的格式。\n"
+"[b]注意:[/b]你需要先将文件导入引擎,才能使用 [method load] 进行加载。如果你想"
+"在运行时加载 [Image],可以使用 [method Image.load]。如果你想导入音频文件,可以"
+"使用 [member AudioStreamMP3.data] 中描述的代码段。"
+
+msgid ""
"Registers a new [ResourceFormatLoader]. The ResourceLoader will use the "
"ResourceFormatLoader as described in [method load].\n"
"This method is performed implicitly for ResourceFormatLoaders written in "
@@ -100507,6 +106920,25 @@ msgstr ""
"[Resource] 类型。任何继承自 [Resource] 的内容都可以用作类型提示,例如 "
"[Image]。"
+msgid ""
+"Returns the dependencies for the resource at the given [param path].\n"
+"[b]Note:[/b] The dependencies are returned with slices separated by [code]::[/"
+"code]. You can use [method String.get_slice] to get their components.\n"
+"[codeblock]\n"
+"for dep in ResourceLoader.get_dependencies(path):\n"
+" print(dep.get_slice(\"::\", 0)) # Prints UID.\n"
+" print(dep.get_slice(\"::\", 2)) # Prints path.\n"
+"[/codeblock]"
+msgstr ""
+"返回位于给定路径 [param path] 的资源的依赖项。\n"
+"[b]注意:[/b]返回的单个依赖项是由 [code]::[/code] 分隔的切片。你可以使用 "
+"[method String.get_slice] 来获取每段的内容。\n"
+"[codeblock]\n"
+"for dep in ResourceLoader.get_dependencies(path):\n"
+" print(dep.get_slice(\"::\", 0)) # 输出 UID。\n"
+" print(dep.get_slice(\"::\", 2)) # 输出路径。\n"
+"[/codeblock]"
+
msgid "Returns the list of recognized extensions for a resource type."
msgstr "返回资源类型的已识别扩展名列表。"
@@ -100629,6 +107061,9 @@ msgid ""
"load_threaded_get]."
msgstr "资源成功加载,可以通过 [method load_threaded_get] 访问。"
+msgid "A node used to preload sub-resources inside a scene."
+msgstr "用于预加载场景子资源的节点。"
+
msgid ""
"This node is used to preload sub-resources inside a scene, so when the scene "
"is loaded, all the resources are ready to use and can be retrieved from the "
@@ -100831,12 +107266,71 @@ msgstr ""
"用于无效 UID 的值,例如无法加载的资源。\n"
"对应的文本表示为 [code]uid://<invalid>[/code]。"
+msgid "Represents a straight ribbon-shaped [PrimitiveMesh] with variable width."
+msgstr "代表竖直丝带形状的 [PrimitiveMesh],丝带的宽度可变。"
+
+msgid ""
+"[RibbonTrailMesh] represents a straight ribbon-shaped mesh with variable "
+"width. The ribbon is composed of a number of flat or cross-shaped sections, "
+"each with the same [member section_length] and number of [member "
+"section_segments]. A [member curve] is sampled along the total length of the "
+"ribbon, meaning that the curve determines the size of the ribbon along its "
+"length.\n"
+"This primitive mesh is usually used for particle trails."
+msgstr ""
+"[RibbonTrailMesh] 代表竖直条带形状的网格,条带的宽度可变。条带由若干扁平或十字"
+"形的分节构成,每一节的长度 [member section_length] 和分段数 [member "
+"section_segments] 都相同。条带会沿着总长度对 [member curve] 进行采样,这样这条"
+"曲线就决定了条带沿长度的大小。\n"
+"该基本网格常用于粒子拖尾。"
+
msgid "3D Particle trails"
msgstr "3D 粒子拖尾"
msgid "Particle systems (3D)"
msgstr "粒子系统(3D)"
+msgid ""
+"Determines the size of the ribbon along its length. The size of a particular "
+"section segment is obtained by multiplying the baseline [member size] by the "
+"value of this curve at the given distance. For values smaller than [code]0[/"
+"code], the faces will be inverted."
+msgstr ""
+"决定条带沿长度的大小。通过将基础大小 [member size] 乘以这条曲线上给定位置对应"
+"的值,就可以得到分节上某一段的大小。如果得到的值小于 [code]0[/code],则对应的"
+"面会被翻转。"
+
+msgid "The length of a section of the ribbon."
+msgstr "条带中一节的长度。"
+
+msgid ""
+"The number of segments in a section. The [member curve] is sampled on each "
+"segment to determine its size. Higher values result in a more detailed ribbon "
+"at the cost of performance."
+msgstr ""
+"条带中一节的段数。每一段的大小是根据对 [member curve] 的采样确定的。更高的值会"
+"生成更细致的条带,但以性能为代价。"
+
+msgid "The total number of sections on the ribbon."
+msgstr "条带中分节的数量。"
+
+msgid "Determines the shape of the ribbon."
+msgstr "决定条带的形状。"
+
+msgid ""
+"The baseline size of the ribbon. The size of a particular section segment is "
+"obtained by multiplying this size by the value of the [member curve] at the "
+"given distance."
+msgstr ""
+"条带的基础大小。通过将这个大小乘以 [member curve] 上给定位置对应的值,就可以得"
+"到分节上某一段的大小。"
+
+msgid "Gives the mesh a single flat face."
+msgstr "将网格指定为单个扁平的面。"
+
+msgid "Gives the mesh two perpendicular flat faces, making a cross shape."
+msgstr "将网格指定为两个互相垂直的面,形成十字形。"
+
msgid "A custom effect for a [RichTextLabel]."
msgstr "[RichTextLabel] 的自定义效果。"
@@ -100886,6 +107380,44 @@ msgstr ""
"须返回 [code]true[/code]。如果该方法返回 [code]false[/code],则它将跳过转换以"
"避免显示损坏的文本。"
+msgid ""
+"A control for displaying text that can contain different font styles, images, "
+"and basic formatting."
+msgstr "用于显示文本的控件,文本中能够包含不同的字体样式、图片以及基础格式。"
+
+msgid ""
+"A control for displaying text that can contain custom fonts, images, and "
+"basic formatting. [RichTextLabel] manages these as an internal tag stack. It "
+"also adapts itself to given width/heights.\n"
+"[b]Note:[/b] Assignments to [member text] clear the tag stack and reconstruct "
+"it from the property's contents. Any edits made to [member text] will erase "
+"previous edits made from other manual sources such as [method append_text] "
+"and the [code]push_*[/code] / [method pop] methods.\n"
+"[b]Note:[/b] RichTextLabel doesn't support entangled BBCode tags. For "
+"example, instead of using [code][b]bold[i]bold italic[/b]italic[/i][/code], "
+"use [code][b]bold[i]bold italic[/i][/b][i]italic[/i][/code].\n"
+"[b]Note:[/b] [code]push_*/pop_*[/code] functions won't affect BBCode.\n"
+"[b]Note:[/b] Unlike [Label], [RichTextLabel] doesn't have a [i]property[/i] "
+"to horizontally align text to the center. Instead, enable [member "
+"bbcode_enabled] and surround the text in a [code][center][/code] tag as "
+"follows: [code][center]Example[/center][/code]. There is currently no built-"
+"in way to vertically align text either, but this can be emulated by relying "
+"on anchors/containers and the [member fit_content] property."
+msgstr ""
+"用于显示文本的控件,文本中能够包含自定义字体、图片以及基础格式。"
+"[RichTextLabel] 使用内部标签栈管理这些内容。它还可以适应给定的宽度和高度。\n"
+"[b]注意:[/b]对 [member text] 赋值会将标签栈清空并根据该属性的内容重建。对 "
+"[member text] 所做的任何编辑都将擦除之前从 [method append_text] 和 "
+"[code]push_*[/code] / [method pop] 方法等其他手动来源所做的编辑。\n"
+"[b]注意:[/b]RichTextLabel 不支持纠缠的 BBCode 标签。例如,请不要使用 [code]"
+"[b]加粗[i]加粗斜体[/b]斜体[/i][/code],请改为 [code][b]加粗[i]加粗斜体[/i][/b]"
+"[i]斜体[/i][/code]。\n"
+"[b]注意:[/b][code]push_*/pop[/code] 函数不会影响 BBCode。\n"
+"[b]注意:[/b]与 [Label] 不同,[RichTextLabel] 没有使文本水平居中的[i]属性[/"
+"i]。请启用 [member bbcode_enabled] 并将文本包围在 [code][center][/code] 标签"
+"中,类似:[code][center]示例[/center][/code]。目前也没有垂直对齐文本的内置方"
+"法,但这可以通过使用锚点/容器和 [member fit_content] 属性来模拟。"
+
msgid "GUI Rich Text/BBcode Demo"
msgstr "GUI 富文本/BBcode 演示"
@@ -100922,10 +107454,19 @@ msgstr ""
"解析 [param bbcode] 并根据需要将标签添加到标签栈中。\n"
"[b]注意:[/b]使用该方法,无法关闭在之前的 [method append_text] 调用中打开的标"
"签。这样做是为了提高性能,尤其是在更新大型 RichTextLabel 时,因为每次都重建整"
-"个 BBCode 会比较慢。如果您绝对需要在接下来的方法调用中关闭标签,请追加 "
+"个 BBCode 会比较慢。如果你绝对需要在接下来的方法调用中关闭标签,请追加 "
"[member text] 而不是使用 [method append_text]。"
msgid ""
+"Clears the tag stack.\n"
+"[b]Note:[/b] This method will not modify [member text], but setting [member "
+"text] to an empty string also clears the stack."
+msgstr ""
+"清空标签栈。\n"
+"[b]注意:[/b]这个方法不会修改 [member text],但将 [member text] 设置为空字符串"
+"也能清空标签栈。"
+
+msgid ""
"Returns the line number of the character position provided.\n"
"[b]Note:[/b] If [member threaded] is enabled, this method returns a value for "
"the loaded part of the document. Use [method is_ready] or [signal finished] "
@@ -101138,7 +107679,7 @@ msgid ""
"to determine whether document is fully loaded."
msgstr ""
"返回可见段落的数量。如果段落中至少有一行是可见的,则该段落被认为是可见的。\n"
-"[b]注意:[/b] 如果启用了 [member threaded],则此方法返回文档已加载部分的值。使"
+"[b]注意:[/b]如果启用了 [member threaded],则此方法返回文档已加载部分的值。使"
"用 [method is_ready] 或 [signal finished] 来确定文档是否已完全加载。"
msgid ""
@@ -101240,6 +107781,14 @@ msgstr ""
"[member tab_size] 以确定新的边距长度。"
msgid ""
+"Adds a [code][font][/code] tag with an italics font to the tag stack. This is "
+"the same as adding an [code][i][/code] tag if not currently in a [code][b][/"
+"code] tag."
+msgstr ""
+"在标签栈中添加 [code][font][/code] 标签,字体为斜体。如果当前不在 [code][b][/"
+"code] 标签中,则与添加 [code][i][/code] 标签相同。"
+
+msgid ""
"Adds [code][ol][/code] or [code][ul][/code] tag to the tag stack. Multiplies "
"[param level] by current [member tab_size] to determine new margin length."
msgstr ""
@@ -101390,7 +107939,7 @@ msgid ""
msgstr ""
"加载进度条显示的延迟时间,单位为毫秒。将其设置为 [code]-1[/code] 将完全禁用进"
"度条。\n"
-"[b]注意:[/b]仅当 [member threaded] 已启用时才会显示进度条。"
+"[b]注意:[/b]仅当 [member threaded] 已启用时才会显示进度条。"
msgid ""
"If [code]true[/code], the scrollbar is visible. Setting this to [code]false[/"
@@ -101435,10 +107984,10 @@ msgid ""
msgstr ""
"以 BBCode 格式表示的标签的文本。当编辑时,不代表对内部标签栈所做的手动修改。在"
"编辑时将擦除使用其他方法添加的更改。\n"
-"[b]注意:[/b] 如果 [member bbcode_enabled] 是 [code]true[/code],则不建议使用 "
+"[b]注意:[/b]如果 [member bbcode_enabled] 是 [code]true[/code],则不建议使用 "
"[code]text += \"some string\"[/code] 这样的 [code]+=[/code] 操作符,因为它会替"
"换整个文本,并可能导致减速。它还将擦除使用 [code]push_*[/code] 方法添加到堆栈"
-"中的所有 BBCode。可使用 [method append_text] 来添加文本,除非您绝对需要关闭在"
+"中的所有 BBCode。可使用 [method append_text] 来添加文本,除非你绝对需要关闭在"
"之前的方法调用中打开的标记。"
msgid "If [code]true[/code], text processing is done in a background thread."
@@ -101578,6 +108127,9 @@ msgstr ""
msgid "The normal background for the [RichTextLabel]."
msgstr "[RichTextLabel] 的正常背景。"
+msgid "A handle for a [Resource]'s unique identifier."
+msgstr "[Resource] 的唯一标识符的句柄。"
+
msgid ""
"The RID [Variant] type is used to access a low-level resource by its unique "
"ID. RIDs are opaque, which means they do not grant access to the resource by "
@@ -101732,8 +108284,8 @@ msgstr ""
"返回与此物体发生碰撞的物体的列表。需要将 [member contact_monitor] 设置为 "
"[code]true[/code],并将 [member max_contacts_reported] 设置足够高以侦测所有碰"
"撞。\n"
-"[b]注意:[/b]此测试的结果不会立即在移动物体后得出。为了提高性能,碰撞列表每帧更"
-"新一次,且在物理步骤之前进行。可考虑改用信号来代替。"
+"[b]注意:[/b]此测试的结果不会立即在移动物体后得出。为了提高性能,碰撞列表每帧"
+"更新一次,且在物理步骤之前进行。可考虑改用信号来代替。"
msgid ""
"Returns the number of contacts this body has with other bodies. By default, "
@@ -101743,8 +108295,8 @@ msgid ""
"get_colliding_bodies]."
msgstr ""
"返回此物体与其他物体的接触数。默认情况下,除非配置监视接触的物体(请参见 "
-"[member contact_monitor]),否则返回0。\n"
-"[b]注意:[/b] 要获取正在碰撞的物体,请使用 [method get_colliding_bodies]。"
+"[member contact_monitor]),否则返回 0。\n"
+"[b]注意:[/b]要获取正在碰撞的物体,请使用 [method get_colliding_bodies]。"
msgid ""
"Sets the body's velocity on the given axis. The velocity in the given vector "
@@ -101765,7 +108317,7 @@ msgid ""
msgstr ""
"减缓物体的旋转。默认情况下,物体将使用 [b]项目> 项目设置> 物理> 2D[/b] 中的[b]"
"默认角阻尼[/b],或由 [Area2D] 设置的任何值覆盖。根据 [member "
-"angular_damp_mode],您可以设置 [member angular_damp_mode] 以添加到或替换物体的"
+"angular_damp_mode],你可以设置 [member angular_damp_mode] 以添加到或替换物体的"
"阻尼值。\n"
"有关阻尼的更多详细信息,请参见 [member ProjectSettings.physics/2d/"
"default_angular_damp] 。"
@@ -101815,6 +108367,16 @@ msgstr ""
"请参见 [method add_constant_torque] 。"
msgid ""
+"If [code]true[/code], the RigidBody2D will emit signals when it collides with "
+"another body.\n"
+"[b]Note:[/b] By default the maximum contacts reported is set to 0, meaning "
+"nothing will be recorded, see [member max_contacts_reported]."
+msgstr ""
+"如果为 [code]true[/code],则该 RigidBody2D 将在与其他物体碰撞时发出信号。\n"
+"[b]注意:[/b]默认情况下,报告的最大接触数被设置为 0,表示不会记录任何内容,见 "
+"[member max_contacts_reported]。"
+
+msgid ""
"Continuous collision detection mode.\n"
"Continuous collision detection tries to predict where a moving body will "
"collide instead of moving it and correcting its movement after collision. "
@@ -101937,7 +108499,7 @@ msgid ""
msgstr ""
"阻碍物体的运动。默认情况下,物体将使用 [b]项目 > 项目设置 > Physics > 2d[/b] "
"中的 [b]默认线性阻尼(Default Linear Damp)[/b]、或物体所在的 [Area2D] 设置的"
-"任何值覆盖。取决于 [member linear_damp_mode],您可以将 [member linear_damp] 设"
+"任何值覆盖。取决于 [member linear_damp_mode],你可以将 [member linear_damp] 设"
"置为添加或替换物体的阻尼值。\n"
"有关阻尼的更多详细信息,请参见 [member ProjectSettings.physics/2d/"
"default_linear_damp]。"
@@ -101971,7 +108533,7 @@ msgstr ""
"将记录的最大接触点数。需要一个大于 0 的值,并将 [member contact_monitor] 设置"
"为 [code]true[/code] 以开始注册接触。使用 [method get_contact_count] 检索计数"
"或使用 [method get_colliding_bodies] 检索已发生碰撞的物体。\n"
-"[b]注意:[/b] 接触点的数量不同于碰撞的数量。平行边之间的碰撞将导致两个接触点"
+"[b]注意:[/b]接触点的数量不同于碰撞的数量。平行边之间的碰撞将导致两个接触点"
"(每个端点一个),平行面之间的碰撞将导致四个接触点(每个角落一个)。"
msgid ""
@@ -102221,6 +108783,16 @@ msgid "The RigidBody3D's rotational velocity in [i]radians[/i] per second."
msgstr "该 RigidBody3D 的旋转速度,单位为[i]弧度[/i]每秒。"
msgid ""
+"If [code]true[/code], the RigidBody3D will emit signals when it collides with "
+"another body.\n"
+"[b]Note:[/b] By default the maximum contacts reported is set to 0, meaning "
+"nothing will be recorded, see [member max_contacts_reported]."
+msgstr ""
+"如果为 [code]true[/code],则该 RigidBody3D 将在与其他物体碰撞时发出信号。\n"
+"[b]注意:[/b]默认情况下,报告的最大接触数被设置为 0,表示不会记录任何内容,见 "
+"[member max_contacts_reported]。"
+
+msgid ""
"If [code]true[/code], continuous collision detection is used.\n"
"Continuous collision detection tries to predict where a moving body will "
"collide, instead of moving it and correcting its movement if it collided. "
@@ -102589,6 +109161,23 @@ msgstr ""
"peer_authentication_failed] 信号。"
msgid ""
+"Maximum size of each delta packet. Higher values increase the chance of "
+"receiving full updates in a single frame, but also the chance of causing "
+"networking congestion (higher latency, disconnections). See "
+"[MultiplayerSynchronizer]."
+msgstr ""
+"增量数据包的最大大小。值越大,单帧能够收到完整更新的几率就越大,但造成网络拥堵"
+"的几率也越大(网络延迟、断线等)。见 [MultiplayerSynchronizer]。"
+
+msgid ""
+"Maximum size of each synchronization packet. Higher values increase the "
+"chance of receiving full updates in a single frame, but also the chance of "
+"packet loss. See [MultiplayerSynchronizer]."
+msgstr ""
+"同步数据包的最大大小。值越大,单帧能够收到完整更新的几率就越大,但丢包的几率也"
+"越大。见 [MultiplayerSynchronizer]。"
+
+msgid ""
"If [code]true[/code], the MultiplayerAPI's [member MultiplayerAPI."
"multiplayer_peer] refuses new incoming connections."
msgstr ""
@@ -102727,6 +109316,20 @@ msgstr "从配置中移除属性,该属性由 [param path] 指定。"
msgid "Provides access to a scene file's information."
msgstr "提供对场景文件信息的访问。"
+msgid ""
+"Maintains a list of resources, nodes, exported and overridden properties, and "
+"built-in scripts associated with a scene. They cannot be modified from a "
+"[SceneState], only accessed. Useful for peeking into what a [PackedScene] "
+"contains without instantiating it.\n"
+"This class cannot be instantiated directly, it is retrieved for a given scene "
+"as the result of [method PackedScene.get_state]."
+msgstr ""
+"维护一个与场景相关的资源、节点、导出的和重写的属性以及内置脚本的列表。无法从 "
+"[SceneState] 修改,只能读取。可用于在不实例化 [PackedScene] 的前提下观察其中的"
+"内容。\n"
+"这个类不能直接实例化,它是作为 [method PackedScene.get_state] 的结果为一个给定"
+"的场景检索的。"
+
msgid "Returns the list of bound parameters for the signal at [param idx]."
msgstr "返回 [param idx] 处信号的绑定参数列表。"
@@ -102930,6 +109533,60 @@ msgstr ""
"调用昂贵的方法,这可能会导致卡顿。"
msgid ""
+"Calls [param method] on each member of the given group, respecting the given "
+"[enum GroupCallFlags]. You can pass arguments to [param method] by specifying "
+"them at the end of the method call. If a node doesn't have the given method "
+"or the argument list does not match (either in count or in types), it will be "
+"skipped.\n"
+"[codeblock]\n"
+"# Call the method in a deferred manner and in reverse order.\n"
+"get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree."
+"GROUP_CALL_REVERSE)\n"
+"[/codeblock]\n"
+"[b]Note:[/b] Group call flags are used to control the method calling "
+"behavior. By default, methods will be called immediately in a way similar to "
+"[method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is "
+"present in the [param flags] argument, methods will be called at the end of "
+"the frame in a way similar to [method Object.set_deferred]."
+msgstr ""
+"调用给定分组中每个成员的 [param method] 方法,遵循给定的 [enum "
+"GroupCallFlags]。你可以在方法调用末尾指定要传递给 [param method] 的参数。如果"
+"某个节点没有给定的方法,或者方法的参数列表不匹配(无论是数量还是类型不匹配),"
+"则会跳过这个节点。\n"
+"[codeblock]\n"
+"# 使用延迟方式逆序调用该方法。\n"
+"get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree."
+"GROUP_CALL_REVERSE)\n"
+"[/codeblock]\n"
+"[b]注意:[/b]分组调用标志可用于控制方法调用的行为。默认情况下方法是立即调用"
+"的,与 [method call_group] 类似。但是如果在 [param flags] 中存在 [constant "
+"GROUP_CALL_DEFERRED] 标志,则方法会在该帧末尾调用,与 [method Object."
+"set_deferred] 类似。"
+
+msgid ""
+"Changes the running scene to the one at the given [param path], after loading "
+"it into a [PackedScene] and creating a new instance.\n"
+"Returns [constant OK] on success, [constant ERR_CANT_OPEN] if the [param "
+"path] cannot be loaded into a [PackedScene], or [constant ERR_CANT_CREATE] if "
+"that scene cannot be instantiated.\n"
+"[b]Note:[/b] The scene change is deferred, which means that the new scene "
+"node is added to the tree at the end of the frame. This ensures that both "
+"scenes aren't running at the same time, while still freeing the previous "
+"scene in a safe way similar to [method Node.queue_free]. As such, you won't "
+"be able to access the loaded scene immediately after the [method "
+"change_scene_to_file] call."
+msgstr ""
+"将位于给定路径 [param path] 的场景加载进一个 [PackedScene] 并新建其实例,然后"
+"将正在运行的场景修改为这个场景。\n"
+"成功时返回 [constant OK],如果 [param path] 不能被加载到一个 [PackedScene] "
+"中,则返回 [constant ERR_CANT_OPEN];如果该场景无法被实例化,则返回 [constant "
+"ERR_CANT_CREATE]。\n"
+"[b]注意:[/b]场景改变是延迟的,即新的场景节点是在该帧的末尾添加的。这确保了两"
+"个场景永远不会同时加载,如果场景太大或在内存受限的环境中运行,这会耗尽系统资"
+"源。因此,无法在 [method change_scene_to_file] 调用后,立即访问到被加载的场"
+"景。"
+
+msgid ""
"Changes the running scene to a new instance of the given [PackedScene] (which "
"must be valid).\n"
"Returns [constant OK] on success, [constant ERR_CANT_CREATE] if the scene "
@@ -103126,6 +109783,33 @@ msgstr ""
"[constant ERR_CANT_CREATE]。"
msgid ""
+"Sets the given [param property] to [param value] on all members of the given "
+"group.\n"
+"[b]Note:[/b] [method set_group] will set the property immediately on all "
+"members at once, which can cause stuttering if a property with an expensive "
+"setter is set on lots of members."
+msgstr ""
+"将给定分组中所有成员的 [param property] 设置为 [param value]。\n"
+"[b]注意:[/b][method set_group] 会立即在所有成员上设置属性,如果对许多成员设置"
+"具有大量耗费的 setter 的属性,则可能会导致卡顿。"
+
+msgid ""
+"Sets the given [param property] to [param value] on all members of the given "
+"group, respecting the given [enum GroupCallFlags].\n"
+"[b]Note:[/b] Group call flags are used to control the property setting "
+"behavior. By default, properties will be set immediately in a way similar to "
+"[method set_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is "
+"present in the [param call_flags] argument, properties will be set at the end "
+"of the frame in a way similar to [method Object.call_deferred]."
+msgstr ""
+"将给定分组中所有成员的 [param property] 设置为 [param value],设置时会考虑给定"
+"的 [enum GroupCallFlags]。\n"
+"[b]注意:[/b]分组调用标志可用于控制属性设置的行为。默认情况下会立即设置属性,"
+"类似于 [method set_group]。但是,如果在 [param call_flags] 参数中存在 "
+"[constant GROUP_CALL_DEFERRED] 标志,则属性将在该帧的末尾再设置,类似于 "
+"[method Object.call_deferred]。"
+
+msgid ""
"Sets a custom [MultiplayerAPI] with the given [param root_path] (controlling "
"also the relative subpaths), or override the default one if [param root_path] "
"is empty.\n"
@@ -103276,6 +109960,9 @@ msgstr "对分组进行调用时,不使用标志(默认)。"
msgid "Call a group in reverse scene order."
msgstr "对分组进行调用时,使用逆场景序。"
+msgid "Call a group at the end of the current frame (process or physics)."
+msgstr "在当前帧的末尾对分组进行调用(处理帧或物理帧)。"
+
msgid ""
"Call a group only once even if the call is executed many times.\n"
"[b]Note:[/b] Arguments are not taken into account when deciding whether the "
@@ -103425,6 +110112,9 @@ msgstr ""
"脚本的源代码,如果源代码不可用,则为空字符串。当设置时,不会自动重新加载类的实"
"现。"
+msgid "Godot editor's popup dialog for creating new [Script] files."
+msgstr "Godot 编辑器用于创建新 [Script] 文件的弹出对话框。"
+
msgid ""
"The [ScriptCreateDialog] creates script files according to a given template "
"for a given scripting language. The standard use is to configure its fields "
@@ -103483,6 +110173,15 @@ msgid "Godot editor's script editor."
msgstr "Godot 编辑器的脚本编辑器。"
msgid ""
+"Godot editor's script editor.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_script_editor]."
+msgstr ""
+"Godot 编辑器的脚本编辑器。\n"
+"[b]注意:[/b]这个类不应该被直接实例化。请使用 [method EditorInterface."
+"get_script_editor] 来访问这个单例。"
+
+msgid ""
"Returns the [ScriptEditorBase] object that the user is currently editing."
msgstr "返回用户当前正在编辑的 [ScriptEditorBase] 对象。"
@@ -103540,6 +110239,11 @@ msgstr "当编辑器即将关闭活动脚本时发出。参数是将要关闭的
msgid "Base editor for editing scripts in the [ScriptEditor]."
msgstr "用于在 [ScriptEditor] 中编辑脚本的基础编辑器。"
+msgid ""
+"Base editor for editing scripts in the [ScriptEditor]. This does not include "
+"documentation items."
+msgstr "用于在 [ScriptEditor] 中编辑脚本的基础编辑器。不包含文档项目。"
+
msgid "Adds a [EditorSyntaxHighlighter] to the open script."
msgstr "将 [EditorSyntaxHighlighter] 添加到打开的脚本中。"
@@ -103817,6 +110521,16 @@ msgid ""
"any collider."
msgstr "用于物理碰撞的 2D 射线形状,会尝试将自己与其他碰撞体分开。"
+msgid ""
+"A 2D ray shape, intended for use in physics. Usually used to provide a shape "
+"for a [CollisionShape2D]. When a [SeparationRayShape2D] collides with an "
+"object, it tries to separate itself from it by moving its endpoint to the "
+"collision point. It can for example be used for spears falling from the sky."
+msgstr ""
+"2D 射线形状,旨在用于物理。通常用来为 [CollisionShape2D] 提供形状。"
+"[SeparationRayShape2D] 与某个对象发生碰撞时,会尝试将其端点移动至碰撞点,将自"
+"己与该对象分离。示例用法是充当从天上落下的长矛。"
+
msgid "The ray's length."
msgstr "射线的长度。"
@@ -103836,6 +110550,16 @@ msgid ""
"any collider."
msgstr "用于物理碰撞的 3D 射线形状,会尝试将自己与其他碰撞体分开。"
+msgid ""
+"A 3D ray shape, intended for use in physics. Usually used to provide a shape "
+"for a [CollisionShape2D]. When a [SeparationRayShape3D] collides with an "
+"object, it tries to separate itself from it by moving its endpoint to the "
+"collision point. It can for example be used for spears falling from the sky."
+msgstr ""
+"3D 射线形状,旨在用于物理。通常用来为 [CollisionShape2D] 提供形状。"
+"[SeparationRayShape3D] 与某个对象发生碰撞时,会尝试将其端点移动至碰撞点,将自"
+"己与该对象分离。示例用法是充当从天上落下的长矛。"
+
msgid "Abstract base class for separators."
msgstr "分隔线的抽象基类。"
@@ -103930,6 +110654,64 @@ msgstr "用于绘制天空的模式。仅适用于附加到 [Sky] 对象的着
msgid "Mode used for setting the color and density of volumetric fog effect."
msgstr "用于设置体积雾效果的颜色和密度的模式。"
+msgid "Overrides global shader parameters' values in a specific scene."
+msgstr "针对指定场景覆盖全局着色器参数的取值。"
+
+msgid ""
+"Similar to how a [WorldEnvironment] node can be used to override the "
+"environment while a specific scene is loaded, [ShaderGlobalsOverride] can be "
+"used to override global shader parameters temporarily. Once the node is "
+"removed, the project-wide values for the global shader parameters are "
+"restored. See the [RenderingServer] [code]global_shader_parameter_*[/code] "
+"methods for more information.\n"
+"[b]Note:[/b] Only one [ShaderGlobalsOverride] can be used per scene. If there "
+"is more than one [ShaderGlobalsOverride] node in the scene tree, only the "
+"first node (in tree order) will be taken into account.\n"
+"[b]Note:[/b] All [ShaderGlobalsOverride] nodes are made part of a "
+"[code]\"shader_overrides_group\"[/code] group when they are added to the "
+"scene tree. The currently active [ShaderGlobalsOverride] node also has a "
+"[code]\"shader_overrides_group_active\"[/code] group added to it. You can use "
+"this to check which [ShaderGlobalsOverride] node is currently active."
+msgstr ""
+"就像 [WorldEnvironment] 能够在加载指定场景时覆盖环境一样,"
+"[ShaderGlobalsOverride] 能够临时覆盖全局着色器参数。移除该节点后,就会恢复项目"
+"范围的全局着色器参数。详情见 [RenderingServer] 的 "
+"[code]global_shader_parameter_*[/code] 方法。\n"
+"[b]注意:[/b]一个场景只能用一个 [ShaderGlobalsOverride]。如果场景树中存在多个 "
+"[ShaderGlobalsOverride],则只会考虑第一个节点(按照树顺序)。\n"
+"[b]注意:[/b]所有 [ShaderGlobalsOverride] 节点在添加至场景树时都会加入 "
+"[code]\"shader_overrides_group\"[/code] 分组。当前活动的 "
+"[ShaderGlobalsOverride] 还会加入 [code]\"shader_overrides_group_active\"[/"
+"code] 分组。你可以据此来检查当前活动的 [ShaderGlobalsOverride] 节点是哪一个。"
+
+msgid ""
+"A snippet of shader code to be included in a [Shader] with [code]#include[/"
+"code]."
+msgstr "着色器代码片段,能够在 [Shader] 中使用 [code]#include[/code] 引入。"
+
+msgid ""
+"A shader include file, saved with the [code].gdshaderinc[/code] extension. "
+"This class allows you to define a custom shader snippet that can be included "
+"in a [Shader] by using the preprocessor directive [code]#include[/code], "
+"followed by the file path (e.g. [code]#include \"res://shader_lib."
+"gdshaderinc\"[/code]). The snippet doesn't have to be a valid shader on its "
+"own."
+msgstr ""
+"着色器头文件,保存时使用 [code].gdshaderinc[/code] 扩展名。这个类能够用于定义"
+"自定义着色器代码片段,在 [Shader] 中可以使用预处理器指令 [code]#include[/"
+"code] 加上文件路径引入(例如 [code]#include \"res://shader_lib.gdshaderinc\"[/"
+"code])。代码片段本身不必是有效的着色器。"
+
+msgid "Shader preprocessor"
+msgstr "着色器预处理器"
+
+msgid ""
+"Returns the code of the shader include file. The returned text is what the "
+"user has written, not the full generated code used internally."
+msgstr ""
+"返回着色器头文件的代码。返回的文本是用户所编写的内容,不是内部使用的完整生成的"
+"代码。"
+
msgid "A material that uses a custom [Shader] program."
msgstr "使用自定义 [Shader] 程序的材质。"
@@ -104123,6 +110905,32 @@ msgstr ""
"过其边距时,碰撞算法的成本会更高,所以边距的数值越高对性能越好,但代价是边缘的"
"精度会降低,因为会让边缘的锐度降低。"
+msgid "A 2D shape that sweeps a region of space to detect [CollisionObject2D]s."
+msgstr "2D 形状,会扫描空间中某个区域,用于检测 [CollisionObject2D]。"
+
+msgid ""
+"Shape casting allows to detect collision objects by sweeping its [member "
+"shape] along the cast direction determined by [member target_position]. This "
+"is similar to [RayCast2D], but it allows for sweeping a region of space, "
+"rather than just a straight line. [ShapeCast2D] can detect multiple collision "
+"objects. It is useful for things like wide laser beams or snapping a simple "
+"shape to a floor.\n"
+"Immediate collision overlaps can be done with the [member target_position] "
+"set to [code]Vector2(0, 0)[/code] and by calling [method "
+"force_shapecast_update] within the same physics frame. This helps to overcome "
+"some limitations of [Area2D] when used as an instantaneous detection area, as "
+"collision information isn't immediately available to it.\n"
+"[b]Note:[/b] Shape casting is more computationally expensive than ray casting."
+msgstr ""
+"形状投射会将其 [member shape] 沿着 [member target_position] 确定的投射方向进行"
+"扫描,能够检测到碰撞对象。类似于 [RayCast2D],但是能够扫描空间中的一个区域,而"
+"不仅仅是一条直线。[ShapeCast2D] 能够检测到多个碰撞对象。可用于实现较宽的激光射"
+"线,或者将简单的形状吸附到地面。\n"
+"要立即检测碰撞重叠,可以将 [member target_position] 设置为 [code]Vector2(0, 0)"
+"[/code],并在同一个物理帧中调用 [method force_shapecast_update]。这样就能够克"
+"服 [Area2D] 在进行连续区域检测时的局限性,因为它无法立即获取碰撞信息。\n"
+"[b]注意:[/b]形状投射比射线投射的计算量更大。"
+
msgid ""
"Adds a collision exception so the shape does not report collisions with the "
"specified [CollisionObject2D] node."
@@ -104252,6 +111060,32 @@ msgid ""
"The shape's destination point, relative to this node's [code]position[/code]."
msgstr "该形状的目标点,相对于该节点的 [code]position[/code]。"
+msgid "A 3D shape that sweeps a region of space to detect [CollisionObject3D]s."
+msgstr "3D 形状,会扫描空间中某个区域,用于检测 [CollisionObject3D]。"
+
+msgid ""
+"Shape casting allows to detect collision objects by sweeping its [member "
+"shape] along the cast direction determined by [member target_position]. This "
+"is similar to [RayCast3D], but it allows for sweeping a region of space, "
+"rather than just a straight line. [ShapeCast3D] can detect multiple collision "
+"objects. It is useful for things like wide laser beams or snapping a simple "
+"shape to a floor.\n"
+"Immediate collision overlaps can be done with the [member target_position] "
+"set to [code]Vector3(0, 0, 0)[/code] and by calling [method "
+"force_shapecast_update] within the same physics frame. This helps to overcome "
+"some limitations of [Area3D] when used as an instantaneous detection area, as "
+"collision information isn't immediately available to it.\n"
+"[b]Note:[/b] Shape casting is more computationally expensive than ray casting."
+msgstr ""
+"形状投射会将其 [member shape] 沿着 [member target_position] 确定的投射方向进行"
+"扫描,能够检测到碰撞对象。类似于 [RayCast3D],但是能够扫描空间中的一个区域,而"
+"不仅仅是一条直线。[ShapeCast3D] 能够检测到多个碰撞对象。可用于实现较宽的激光射"
+"线,或者将简单的形状吸附到地面。\n"
+"要立即检测碰撞重叠,可以将 [member target_position] 设置为 [code]Vector3(0, "
+"0, 0)[/code],并在同一个物理帧中调用 [method force_shapecast_update]。这样就能"
+"够克服 [Area3D] 在进行连续区域检测时的局限性,因为它无法立即获取碰撞信息。\n"
+"[b]注意:[/b]形状投射比射线投射的计算量更大。"
+
msgid ""
"Adds a collision exception so the shape does not report collisions with the "
"specified [CollisionObject3D] node."
@@ -104354,6 +111188,9 @@ msgstr ""
"通常使用的 [InputEvent] 是 [InputEventKey],尽管也可以是任何 [InputEvent],包"
"括 [InputEventAction]。"
+msgid "A built-in type representing a signal of an [Object]."
+msgstr "代表 [Object] 中某个信号的内置类型。"
+
msgid ""
"[Signal] is a built-in [Variant] type that represents a signal of an [Object] "
"instance. Like all [Variant] types, it can be stored in variables and passed "
@@ -104514,6 +111351,25 @@ msgid ""
"Returns [code]true[/code] if both signals share the same object and name."
msgstr "如果信号的对象和名称相同,则返回 [code]true[/code]。"
+msgid ""
+"The parent of a hierarchy of [Bone2D]s, used to create a 2D skeletal "
+"animation."
+msgstr "[Bone2D] 层级结构的父节点,用于创建 2D 骨骼动画。"
+
+msgid ""
+"[Skeleton2D] parents a hierarchy of [Bone2D] nodes. It holds a reference to "
+"each [Bone2D]'s rest pose and acts as a single point of access to its bones.\n"
+"To set up different types of inverse kinematics for the given Skeleton2D, a "
+"[SkeletonModificationStack2D] should be created. The inverse kinematics be "
+"applied by increasing [member SkeletonModificationStack2D.modification_count] "
+"and creating the desired number of modifications."
+msgstr ""
+"[Skeleton2D] 是 [Bone2D] 节点层级结构的父节点,持有对每个 [Bone2D] 的放松姿势"
+"的引用,充当其骨骼的单一访问点。\n"
+"要为给定的 Skeleton2D 设置不同类型的反向运动学机制,应当创建一个 "
+"[SkeletonModificationStack2D]。增加 [member SkeletonModificationStack2D."
+"modification_count] 并创建所需数量的修改器即可应用反向运动学机制。"
+
msgid "2D skeletons"
msgstr "2D 骨架"
@@ -104577,6 +111433,28 @@ msgid ""
msgstr "包含骨骼层级结构的节点,用于创建 3D 骨骼动画。"
msgid ""
+"[Skeleton3D] provides an interface for managing a hierarchy of bones, "
+"including pose, rest and animation (see [Animation]). It can also use ragdoll "
+"physics.\n"
+"The overall transform of a bone with respect to the skeleton is determined by "
+"bone pose. Bone rest defines the initial transform of the bone pose.\n"
+"Note that \"global pose\" below refers to the overall transform of the bone "
+"with respect to skeleton, so it is not the actual global/world transform of "
+"the bone.\n"
+"To setup different types of inverse kinematics, consider using "
+"[SkeletonIK3D], or add a custom IK implementation in [method Node._process] "
+"as a child node."
+msgstr ""
+"[Skeleton3D] 提供了管理骨骼层级结构的接口,包括姿势、放松姿势和动画(见 "
+"[Animation])。它还可以使用布娃娃物理。\n"
+"骨骼相对于骨架的整体变换由骨骼的姿势决定。骨骼的放松姿势定义的是骨骼姿势的初始"
+"变换。\n"
+"请注意,下文的“全局姿势”是指骨骼相对于骨架的整体变换,因此并不是骨骼的实际全"
+"局/世界变换。\n"
+"要设置不同类型的反向运动学,请考虑使用 [SkeletonIK3D],或者添加一个子节点并在 "
+"[method Node._process] 中实现自定义 IK。"
+
+msgid ""
"Adds a bone, with name [param name]. [method get_bone_count] will become the "
"bone index."
msgstr ""
@@ -104646,6 +111524,9 @@ msgstr ""
"返回 [param bone_idx] 处的骨骼的父级骨骼索引。如果为 -1,则该骨骼没有父级。\n"
"[b]注意:[/b]返回的父骨骼索引总是小于 [param bone_idx]。"
+msgid "Returns the pose transform of the specified bone."
+msgstr "返回指定骨骼的姿势变换。"
+
msgid "Returns the rest transform for a bone [param bone_idx]."
msgstr "返回骨骼 [param bone_idx] 的放松变换。"
@@ -104754,6 +111635,15 @@ msgstr ""
"位置。"
msgid ""
+"Multiplies the 3D position track animation.\n"
+"[b]Note:[/b] Unless this value is [code]1.0[/code], the key value in "
+"animation will not match the actual position value."
+msgstr ""
+"与 3D 位置轨道动画相乘。\n"
+"[b]注意:[/b]除非这个值是 [code]1.0[/code],否则动画中的键值将与实际位置值不匹"
+"配。"
+
+msgid ""
"This signal is emitted when one of the bones in the Skeleton3D node have "
"changed their pose. This is used to inform nodes that rely on bone positions "
"that one of the bones in the Skeleton3D have changed their transform/pose."
@@ -104981,6 +111871,14 @@ msgid ""
msgstr "安装修改器时调用。修改器在此时执行初始化。"
msgid ""
+"Takes an angle and clamps it so it is within the passed-in [param min] and "
+"[param max] range. [param invert] will inversely clamp the angle, clamping it "
+"to the range outside of the given bounds."
+msgstr ""
+"接受角度并将其钳制在传入的 [param min] 和 [param max] 范围内。[param invert] "
+"会逆向钳制该角度,将其钳制在给定范围之外。"
+
+msgid ""
"Returns whether this modification will call [method _draw_editor_gizmo] in "
"the Godot editor to draw modification-specific gizmos."
msgstr ""
@@ -105587,6 +112485,31 @@ msgstr ""
"行时执行。"
msgid ""
+"A modification that rotates two bones using the law of cosines to reach the "
+"target."
+msgstr "这种修改器会让两个骨骼按照余弦定理进行旋转,最终抵达目标。"
+
+msgid ""
+"This [SkeletonModification2D] uses an algorithm typically called TwoBoneIK. "
+"This algorithm works by leveraging the law of cosines and the lengths of the "
+"bones to figure out what rotation the bones currently have, and what rotation "
+"they need to make a complete triangle, where the first bone, the second bone, "
+"and the target form the three vertices of the triangle. Because the algorithm "
+"works by making a triangle, it can only operate on two bones.\n"
+"TwoBoneIK is great for arms, legs, and really any joints that can be "
+"represented by just two bones that bend to reach a target. This solver is "
+"more lightweight than [SkeletonModification2DFABRIK], but gives similar, "
+"natural looking results."
+msgstr ""
+"这种 [SkeletonModification2D] 所使用的算法一般称之为 TwoBoneIK。这种算法的原理"
+"是利用余弦定理和骨骼的长度来推算骨骼当前的旋转量和构成三角形所需的旋转量,三角"
+"形由第一根骨骼、第二根骨骼以及目标构成。因为这种算法的原理是构成三角形,所以仅"
+"能对两根骨骼进行操作。\n"
+"TwoBoneIK 适用于手臂、腿部,其实任何能够用两根骨头弯向某个目标来代表的关节均能"
+"使用。求解器比 [SkeletonModification2DFABRIK] 更轻量,但也能得到类似的比较自然"
+"的结果。"
+
+msgid ""
"Returns the [Bone2D] node that is being used as the first bone in the "
"TwoBoneIK modification."
msgstr "返回 TwoBoneIK 修改器中作为第一个骨骼的 [Bone2D] 节点。"
@@ -105754,6 +112677,11 @@ msgstr ""
"[Bone2D] 姿势。"
msgid ""
+"Base class for a profile of a virtual skeleton used as a target for "
+"retargeting."
+msgstr "用作重定向目标的虚拟骨架的配置文件的基类。"
+
+msgid ""
"This resource is used in [EditorScenePostImport]. Some parameters are "
"referring to bones in [Skeleton3D], [Skin], [Animation], and some other nodes "
"are rewritten based on the parameters of [SkeletonProfile].\n"
@@ -106050,6 +112978,24 @@ msgstr ""
"sky_reflections/roughness_layers] 决定。当需要最高质量的辐照度贴图,但天空更新"
"缓慢时,请使用该选项。"
+msgid ""
+"Uses the fast filtering algorithm to process the radiance map. In general "
+"this results in lower quality, but substantially faster run times. If you "
+"need better quality, but still need to update the sky every frame, consider "
+"turning on [member ProjectSettings.rendering/reflections/sky_reflections/"
+"fast_filter_high_quality].\n"
+"[b]Note:[/b] The fast filtering algorithm is limited to 256×256 cubemaps, so "
+"[member radiance_size] must be set to [constant RADIANCE_SIZE_256]. "
+"Otherwise, a warning is printed and the overridden radiance size is ignored."
+msgstr ""
+"使用快速过滤算法处理辐射度贴图。一般来说,这会导致质量较低,但运行时间会大大加"
+"快。如果需要更好的质量,但仍需要每帧更新天空,请考虑开启 [member "
+"ProjectSettings.rendering/reflections/sky_reflections/"
+"fast_filter_high_quality]。\n"
+"[b]注意:[/b]快速过滤算法被限制为 256x256 立方体贴图,因此必须将 [member "
+"radiance_size] 设置为 [constant RADIANCE_SIZE_256]。否则会输出警告并忽略覆盖的"
+"辐射度大小。"
+
msgid "Abstract base class for sliders."
msgstr "滑块的抽象基类。"
@@ -106091,6 +113037,22 @@ msgid "Emitted when dragging is started."
msgstr "拖拽开始时触发。"
msgid ""
+"A physics joint that restricts the movement of a 3D physics body along an "
+"axis relative to another physics body."
+msgstr ""
+"一种物理关节,能够将 3D 物理体的移动限制在相对于另一个物理体的某个轴上。"
+
+msgid ""
+"A physics joint that restricts the movement of a 3D physics body along an "
+"axis relative to another physics body. For example, Body A could be a "
+"[StaticBody3D] representing a piston base, while Body B could be a "
+"[RigidBody3D] representing the piston head, moving up and down."
+msgstr ""
+"一种物理关节,能够将 3D 物理体的移动限制在相对于另一个物理体的某个轴上。例如物"
+"体 A 是代表活塞基底的 [StaticBody3D],而物体 B 是代表活塞头的 [RigidBody3D],"
+"能够上下移动。"
+
+msgid ""
"The amount of damping of the rotation when the limit is surpassed.\n"
"A lower damping value allows a rotation initiated by body A to travel to body "
"B slower."
@@ -106127,10 +113089,20 @@ msgstr ""
"一旦超过 [member linear_limit/lower_distance] 和 [member linear_limit/"
"upper_distance] 所定义的极限,就会产生的阻尼量。"
+msgid "A deformable 3D physics mesh."
+msgstr "可形变的 3D 物理网格。"
+
msgid ""
-"The amount of restitution once the limits are surpassed. The lower, the more "
-"velocity-energy gets lost."
-msgstr "超出限制后的补偿。数值越低,损失的速度能量越多。"
+"A deformable 3D physics mesh. Used to create elastic or deformable objects "
+"such as cloth, rubber, or other flexible materials.\n"
+"[b]Note:[/b] There are many known bugs in [SoftBody3D]. Therefore, it's not "
+"recommended to use them for things that can affect gameplay (such as "
+"trampolines)."
+msgstr ""
+"可形变的 3D 物理网格。用于创建弹性或可形变的对象,例如布料、橡胶或其他柔性材"
+"质。\n"
+"[b]注意:[/b][SoftBody3D] 中有许多已知的问题。因此,不建议用于可能影响游戏玩法"
+"的东西上(例如蹦床)。"
msgid "SoftBody"
msgstr "SoftBody"
@@ -106378,6 +113350,19 @@ msgid "Sets a custom [Texture2D] for up and down arrows of the [SpinBox]."
msgstr "为该 [SpinBox] 的上下箭头设置自定义的 [Texture2D]。"
msgid ""
+"A container that splits two child controls horizontally or vertically and "
+"provides a grabber for adjusting the split ratio."
+msgstr "将两个子控件垂直或水平分隔的容器,提供了用于调整分隔比例的抓取器。"
+
+msgid ""
+"A container that accepts only two child controls, then arranges them "
+"horizontally or vertically and creates a divisor between them. The divisor "
+"can be dragged around to change the size relation between the child controls."
+msgstr ""
+"仅接受两个子控件的容器,会将它们垂直或水平排列,在中间创建一个分隔条。分隔条可"
+"以拖拽,从而改变两个控件的大小关系。"
+
+msgid ""
"Clamps the [member split_offset] value to not go outside the currently "
"possible minimal and maximum values."
msgstr "限制 [member split_offset] 值不超出当前可能的最小值和最大值。"
@@ -106524,6 +113509,21 @@ msgstr ""
"光的缩放还是其父节点的缩放)。"
msgid ""
+"A 3D raycast that dynamically moves its children near the collision point."
+msgstr "能够动态地将子节点朝碰撞点移动的 3D 射线投射。"
+
+msgid ""
+"[SpringArm3D] casts a ray or a shape along its Z axis and moves all its "
+"direct children to the collision point, with an optional margin. This is "
+"useful for 3rd person cameras that move closer to the player when inside a "
+"tight space (you may need to exclude the player's collider from the "
+"[SpringArm3D]'s collision check."
+msgstr ""
+"[SpringArm3D] 会朝它的 Z 轴投射射线或形状,并将所有直接子节点朝碰撞点移动,可"
+"以保留一定的边距。可用于第三人称相机,让其在狭窄空间中朝玩家移动(你可能需要"
+"在 [SpringArm3D] 的碰撞检查中排除玩家的碰撞体)。"
+
+msgid ""
"Adds the [PhysicsBody3D] object with the given [RID] to the list of "
"[PhysicsBody3D] objects excluded from the collision check."
msgstr ""
@@ -107032,15 +114032,15 @@ msgid ""
"The body's constant angular velocity. This does not rotate the body, but "
"affects touching bodies, as if it were rotating."
msgstr ""
-"该物体的恒定角速度。不会旋转该物体,但会影响接触的物体,就好像这个静态物体正在"
-"旋转一样。"
+"该物体的恒定角速度。不会旋转该物体,但会影响接触的物体,就好像这个物体正在旋转"
+"一样。"
msgid ""
"The body's constant linear velocity. This does not move the body, but affects "
"touching bodies, as if it were moving."
msgstr ""
-"该物体的恒定线速度。不会移动该物体,但会影响接触的物体,就好像这个静态物体正在"
-"移动一样。"
+"该物体的恒定线速度。不会移动该物体,但会影响接触的物体,就好像这个物体正在移动"
+"一样。"
msgid ""
"A 3D physics body that can't be moved by external forces. When moved "
@@ -107073,6 +114073,21 @@ msgstr ""
msgid "Abstract base class for interacting with streams."
msgstr "与流交互的抽象基类。"
+msgid ""
+"StreamPeer is an abstract base class mostly used for stream-based protocols "
+"(such as TCP). It provides an API for sending and receiving data through "
+"streams as raw data or strings.\n"
+"[b]Note:[/b] When exporting to Android, make sure to enable the "
+"[code]INTERNET[/code] permission in the Android export preset before "
+"exporting the project or using one-click deploy. Otherwise, network "
+"communication of any kind will be blocked by Android."
+msgstr ""
+"StreamPeer 是一种抽象基类,常用于流式协议(例如 TCP)。它提供了通过流发送数据"
+"的 API,将数据作为原始数据或字符串处理。\n"
+"[b]注意:[/b]导出到安卓时,在导出项目或使用一键部署之前,请务必在安卓导出预设"
+"中,开启 [code]INTERNET[/code] 权限。否则,任何类型的网络通信都将被 Android 阻"
+"止。"
+
msgid "Gets a signed byte from the stream."
msgstr "从流中获取有符号字节。"
@@ -107135,6 +114150,16 @@ msgid "Gets an unsigned 64-bit value from the stream."
msgstr "从流中获取一个无符号 64 位值。"
msgid ""
+"Gets a UTF-8 string with byte-length [param bytes] from the stream (this "
+"decodes the string sent as UTF-8). If [param bytes] is negative (default) the "
+"length will be read from the stream using the reverse process of [method "
+"put_utf8_string]."
+msgstr ""
+"从流中获取一个字节长度为 [param bytes] 的 UTF-8 字符串(将发送的字符串解码为 "
+"UTF-8)。如果 [param bytes] 为负(默认),会按照 [method put_utf8_string] 的逆"
+"向操作从流中读取长度。"
+
+msgid ""
"Gets a Variant from the stream. If [param allow_objects] is [code]true[/"
"code], decoding objects is allowed.\n"
"Internally, this uses the same decoding mechanism as the [method @GlobalScope."
@@ -107181,6 +114206,33 @@ msgstr ""
"通过连接发送数据。如果数据无法一次性发完,则仅会发送部分数据。该函数返回两个"
"值,一个 [enum Error] 错误码以及一个整数,表示实际发送的数据量。"
+msgid ""
+"Puts a zero-terminated ASCII string into the stream prepended by a 32-bit "
+"unsigned integer representing its size.\n"
+"[b]Note:[/b] To put an ASCII string without prepending its size, you can use "
+"[method put_data]:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"put_data(\"Hello world\".to_ascii_buffer())\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"PutData(\"Hello World\".ToAsciiBuffer());\n"
+"[/csharp]\n"
+"[/codeblocks]"
+msgstr ""
+"向流中放入一个以零结尾的 ASCII 字符串,会前置一个表示其大小的 32 位无符号整"
+"数。\n"
+"[b]注意:[/b]如果要放置 ASCII 字符串,而不前置大小,可以使用 [method "
+"put_data]:\n"
+"[codeblocks]\n"
+"[gdscript]\n"
+"put_data(\"Hello world\".to_ascii_buffer())\n"
+"[/gdscript]\n"
+"[csharp]\n"
+"PutData(\"Hello World\".ToAsciiBuffer());\n"
+"[/csharp]\n"
+"[/codeblocks]"
+
msgid "Puts an unsigned byte into the stream."
msgstr "向流中放入一个无符号字节。"
@@ -108924,6 +115976,30 @@ msgid "Returns the string converted to [code]camelCase[/code]."
msgstr "返回将该字符串转换为小驼峰命名 [code]camelCase[/code] 的结果。"
msgid ""
+"Converts the string representing a decimal number into a [float]. This method "
+"stops on the first non-number character, except the first decimal point "
+"([code].[/code]) and the exponent letter ([code]e[/code]). See also [method "
+"is_valid_float].\n"
+"[codeblock]\n"
+"var a = \"12.35\".to_float() # a is 12.35\n"
+"var b = \"1.2.3\".to_float() # b is 1.2\n"
+"var c = \"12xy3\".to_float() # c is 12.0\n"
+"var d = \"1e3\".to_float() # d is 1000.0\n"
+"var e = \"Hello!\".to_float() # e is 0.0\n"
+"[/codeblock]"
+msgstr ""
+"将代表十进制数的字符串转换为 [float]。该方法会在首个非数字字符处停止,除非是首"
+"次遇到 [code].[/code](小数点)以及表示指数的 [code]e[/code]。另见 [method "
+"is_valid_float]。\n"
+"[codeblock]\n"
+"var a = \"12.35\".to_float() # a 为 12.35\n"
+"var b = \"1.2.3\".to_float() # b 为 1.2\n"
+"var c = \"12xy3\".to_float() # c 为 12.0\n"
+"var d = \"1e3\".to_float() # d 为 1000.0\n"
+"var e = \"Hello!\".to_float() # e 为 0.0\n"
+"[/codeblock]"
+
+msgid ""
"Converts the string representing an integer number into an [int]. This method "
"removes any non-number character and stops at the first decimal point ([code]."
"[/code]). See also [method is_valid_int].\n"
@@ -109074,6 +116150,15 @@ msgstr ""
"下划线。"
msgid ""
+"Returns a copy of the string with all characters that are not allowed in "
+"[member Node.name] ([code].[/code] [code]:[/code] [code]@[/code] [code]/[/"
+"code] [code]\"[/code] [code]%[/code]) replaced with underscores."
+msgstr ""
+"返回该字符串的副本,所有 [member Node.name] 中不允许的字符都会被替换为下划线"
+"([code].[/code] [code]:[/code] [code]@[/code] [code]/[/code] [code]\"[/code] "
+"[code]%[/code]))。"
+
+msgid ""
"Returns a copy of the string with special characters escaped using the XML "
"standard. If [param escape_quotes] is [code]true[/code], the single quote "
"([code]'[/code]) and double quote ([code]\"[/code]) characters are also "
@@ -110426,7 +117511,7 @@ msgstr ""
"commit_to_arrays] 之前设置。"
msgid "Sets [Material] to be used by the [Mesh] you are constructing."
-msgstr "设置要由您正在构建的 [Mesh] 使用的 [Material]。"
+msgstr "设置要由你正在构建的 [Mesh] 使用的 [Material]。"
msgid ""
"Specifies a normal to use for the [i]next[/i] vertex. If every vertex needs "
@@ -110475,7 +117560,7 @@ msgid ""
"vertex needs to have this information set and you fail to submit it for the "
"first vertex, this information may not be used at all."
msgstr ""
-"指定[i]下一个[/i]顶点所使用的 UV 坐标。如果每个顶点都需要设置此信息,而您未能"
+"指定[i]下一个[/i]顶点所使用的 UV 坐标。如果每个顶点都需要设置此信息,而你未能"
"为第一个顶点提交此信息,此信息可能根本就不会被使用。"
msgid ""
@@ -110645,7 +117730,7 @@ msgid ""
"[b]Note:[/b] This is called automatically when the associated [TextEdit] "
"node, updates its own cache."
msgstr ""
-"清除然后更新 [SyntaxHighlighter] 缓存。为一个回调重写 [method "
+"清除然后更新 [SyntaxHighlighter] 缓存。为一个回调覆盖 [method "
"_update_cache]。\n"
"[b]注意:[/b]当关联的 [TextEdit] 节点更新它自己的缓存时,该函数会被自动调用。"
@@ -112270,15 +119355,6 @@ msgstr "点击边栏时发出。"
msgid "Emitted when a gutter is removed."
msgstr "移除边栏时发出。"
-msgid ""
-"Emitted immediately when the text changes.\n"
-"When text is added [param from_line] will be less then [param to_line]. On a "
-"remove [param to_line] will be less then [param from_line]."
-msgstr ""
-"文本改变时立即发出。\n"
-"添加文本时 [param from_line] 小于 [param to_line]。移除文本时 [param to_line] "
-"小于 [param from_line]。"
-
msgid "Emitted when [method clear] is called or [member text] is set."
msgstr "[method clear] 被调用,或 [member text] 被设置时发出。"
@@ -112469,8 +119545,8 @@ msgid ""
"Override ranges should cover full source text without overlaps. BiDi "
"algorithm will be used on each range separately."
msgstr ""
-"重写用于结构化文本的 BiDi。\n"
-"重写范围应覆盖完整的源文本而没有重叠。BiDi 算法将分别被用于每个范围。"
+"覆盖用于结构化文本的 BiDi。\n"
+"覆盖范围应覆盖完整的源文本而没有重叠。BiDi 算法将分别被用于每个范围。"
msgid "Sets text alignment within the line as if the line was horizontal."
msgstr "设置行内的文本对齐方式,始终按照该行为横向的情况设置。"
@@ -113414,7 +120490,7 @@ msgid ""
msgstr ""
"设置所需的文本方向。如果设置为 [constant DIRECTION_AUTO],方向将根据缓冲区的内"
"容和当前的区域设置来检测。\n"
-"[b]注意:[/b] 如果服务器不支持 [constant FEATURE_BIDI_LAYOUT] 特性,则方向会被"
+"[b]注意:[/b]如果服务器不支持 [constant FEATURE_BIDI_LAYOUT] 特性,则方向会被"
"忽略([TextServerAdvanced] 支持)。"
msgid ""
@@ -115588,6 +122664,47 @@ msgstr ""
"是否仍在执行其任务,请使用 [method is_alive]。"
msgid ""
+"Sets whether the thread safety checks the engine normally performs in methods "
+"of certain classes (e.g., [Node]) should happen [b]on the current thread[/"
+"b].\n"
+"The default, for every thread, is that they are enabled (as if called with "
+"[param enabled] being [code]true[/code]).\n"
+"Those checks are conservative. That means that they will only succeed in "
+"considering a call thread-safe (and therefore allow it to happen) if the "
+"engine can guarantee such safety.\n"
+"Because of that, there may be cases where the user may want to disable them "
+"([param enabled] being [code]false[/code]) to make certain operations allowed "
+"again. By doing so, it becomes the user's responsibility to ensure thread "
+"safety (e.g., by using [Mutex]) for those objects that are otherwise "
+"protected by the engine.\n"
+"[b]Note:[/b] This is an advanced usage of the engine. You are advised to use "
+"it only if you know what you are doing and there is no safer way.\n"
+"[b]Note:[/b] This is useful for scripts running on either arbitrary [Thread] "
+"objects or tasks submitted to the [WorkerThreadPool]. It doesn't apply to "
+"code running during [Node] group processing, where the checks will be always "
+"performed.\n"
+"[b]Note:[/b] Even in the case of having disabled the checks in a "
+"[WorkerThreadPool] task, there's no need to re-enable them at the end. The "
+"engine will do so."
+msgstr ""
+"设置是否应该[b]在当前线程[/b]执行线程安全检查,这些检查在一般是在某些类(例如 "
+"[Node])的方法中进行的。\n"
+"每个线程的默认值是启用(就像将 [code]true[/code] 传给 [param enabled] 调用一"
+"样)。\n"
+"这些检查是保守的。也就是说,只有在引擎能够确保安全时才会认为该调用是线程安全"
+"的,检查通过(因此允许进行调用)。\n"
+"因此,某些情况下用于可能会想要将其禁用(让 [param enabled] 为 [code]false[/"
+"code]),允许某些操作。此时引擎不再保护这些对象的线程安全,(通过使用 [Mutex] "
+"等方法来)确保线程安全就是用户自己的责任了。\n"
+"[b]注意:[/b]这是引擎的高阶用法。建议只有在你知道自己在做什么,并且没有其他更"
+"安全的方法时才使用这个方法。\n"
+"[b]注意:[/b]可用于任意 [Thread] 对象中执行的脚本,或者提交至 "
+"[WorkerThreadPool] 的任务。[Node] 分组处理时执行的代码不适用,这种情况下会始终"
+"执行检查。\n"
+"[b]注意:[/b]即使是在 [WorkerThreadPool] 任务中禁用了检查,也不需要在结束后将"
+"其重新启用。引擎会帮你去启用。"
+
+msgid ""
"Starts a new [Thread] that calls [param callable].\n"
"If the method takes some arguments, you can pass them using [method Callable."
"bind].\n"
@@ -117393,10 +124510,10 @@ msgid ""
"The returned values are in the system's local time when [param utc] is "
"[code]false[/code], otherwise they are in UTC."
msgstr ""
-"以字典的形式返回当前时间,包含的键为:[code]hour[/code]、[code]minute[/code]、"
-"[code]second[/code]。\n"
-"当 [code]utc[/code] 为 [code]false[/code] 时,返回的是系统的本地时间,否则为 "
-"UTC 时间。"
+"以字典的形式返回当前时间,包含的键为:[code]year[/code]、[code]month[/code]、"
+"[code]day[/code] 和 [code]weekday[/code]。\n"
+"当 [param utc] 为 [code]false[/code] 时,返回的是系统的本地时间,否则为 UTC 时"
+"间。"
msgid ""
"Converts the given Unix timestamp to a dictionary of keys: [code]year[/code], "
@@ -117819,6 +124936,49 @@ msgstr ""
"[/gdscript]\n"
"[/codeblocks]"
+msgid ""
+"Creates a TLS client configuration which validates certificates and their "
+"common names (fully qualified domain names).\n"
+"You can specify a custom [param trusted_chain] of certification authorities "
+"(the default CA list will be used if [code]null[/code]), and optionally "
+"provide a [param common_name_override] if you expect the certificate to have "
+"a common name other then the server FQDN.\n"
+"[b]Note:[/b] On the Web platform, TLS verification is always enforced against "
+"the CA list of the web browser. This is considered a security feature."
+msgstr ""
+"创建 TLS 客户端配置,验证证书及其通用名称(完整域名)。\n"
+"你可以指定自定义的证书颁发机构信任链 [param trusted_chain](如果为 "
+"[code]null[/code] 则使用默认 CA 列表)。如果你希望证书拥有服务器 FQDN 之外的通"
+"用名称,还可以提供通用名称覆盖 [param common_name_override]。\n"
+"[b]注意:[/b]在 Web 平台上,TLS 验证始终强制使用 Web 浏览器的 CA 列表。这是一"
+"种安全特性。"
+
+msgid ""
+"Creates an [b]unsafe[/b] TLS client configuration where certificate "
+"validation is optional. You can optionally provide a valid [param "
+"trusted_chain], but the common name of the certificates will never be "
+"checked. Using this configuration for purposes other than testing [b]is not "
+"recommended[/b].\n"
+"[b]Note:[/b] On the Web platform, TLS verification is always enforced against "
+"the CA list of the web browser. This is considered a security feature."
+msgstr ""
+"创建[b]不安全[/b]的 TLS 客户端配置,证书验证为可选项。你可以选择提供有效的信任"
+"链 [param trusted_chain],但永远不会对证书的通用名称进行检查。这种配置[b]不推"
+"荐[/b]用于测试之外的用途。\n"
+"[b]注意:[/b]在 Web 平台上,TLS 验证始终强制使用 Web 浏览器的 CA 列表。这是一"
+"种安全特性。"
+
+msgid ""
+"Creates a TLS server configuration using the provided [param key] and [param "
+"certificate].\n"
+"[b]Note:[/b] The [param certificate] should include the full certificate "
+"chain up to the signing CA (certificates file can be concatenated using a "
+"general purpose text editor)."
+msgstr ""
+"使用提供的密钥 [param key] 和证书 [param certificate] 创建 TLS 服务器配置。\n"
+"[b]注意:[/b][param certificate] 中应当包含签名 CA 的完整证书链(可以使用通用"
+"文本编辑器连接证书文件)。"
+
msgid "Class representing a torus [PrimitiveMesh]."
msgstr "表示圆环 [PrimitiveMesh] 的类。"
@@ -119730,8 +126890,7 @@ msgid ""
"If [param enable] is [code]true[/code], the given [param column] is expanded "
"to the right."
msgstr ""
-"如果 [param enabled] 为 [code]true[/code],则给定的列 [param column] 向右扩"
-"展。"
+"如果 [param enable] 为 [code]true[/code],则给定的列 [param column] 向右扩展。"
msgid "Sets the given column's icon [Texture2D]."
msgstr "设置给定列的图标 [Texture2D]。"
@@ -119919,264 +127078,6 @@ msgid ""
msgstr "通过脚本进行通用动画的轻量级对象,使用 [Tweener]。"
msgid ""
-"Tweens are mostly useful for animations requiring a numerical property to be "
-"interpolated over a range of values. The name [i]tween[/i] comes from [i]in-"
-"betweening[/i], an animation technique where you specify [i]keyframes[/i] and "
-"the computer interpolates the frames that appear between them. Animating "
-"something with a [Tween] is called tweening.\n"
-"[Tween] is more suited than [AnimationPlayer] for animations where you don't "
-"know the final values in advance. For example, interpolating a dynamically-"
-"chosen camera zoom value is best done with a [Tween]; it would be difficult "
-"to do the same thing with an [AnimationPlayer] node. Tweens are also more "
-"light-weight than [AnimationPlayer], so they are very much suited for simple "
-"animations or general tasks that don't require visual tweaking provided by "
-"the editor. They can be used in a fire-and-forget manner for some logic that "
-"normally would be done by code. You can e.g. make something shoot "
-"periodically by using a looped [CallbackTweener] with a delay.\n"
-"A [Tween] can be created by using either [method SceneTree.create_tween] or "
-"[method Node.create_tween]. [Tween]s created manually (i.e. by using "
-"[code]Tween.new()[/code]) are invalid and can't be used for tweening values.\n"
-"A tween animation is created by adding [Tweener]s to the [Tween] object, "
-"using [method tween_property], [method tween_interval], [method "
-"tween_callback] or [method tween_method]:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween()\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = GetTree().CreateTween();\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
-"before finally calling [method Node.queue_free] to free the sprite. "
-"[Tweener]s are executed one after another by default. This behavior can be "
-"changed using [method parallel] and [method set_parallel].\n"
-"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
-"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set a different transition type in the above "
-"example, you can use [method set_trans]:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween()\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1).set_trans(Tween."
-"TRANS_SINE)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1).set_trans(Tween."
-"TRANS_BOUNCE)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = GetTree().CreateTween();\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f)."
-"SetTrans(Tween.TransitionType.Sine);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f)."
-"SetTrans(Tween.TransitionType.Bounce);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"Most of the [Tween] methods can be chained this way too. In the following "
-"example the [Tween] is bound to the running script's node and a default "
-"transition is set for its [Tweener]s:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
-"TRANS_ELASTIC)\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"var tween = GetTree().CreateTween().BindNode(this).SetTrans(Tween."
-"TransitionType.Elastic);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"Another interesting use for [Tween]s is animating arbitrary sets of objects:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = create_tween()\n"
-"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = CreateTween();\n"
-"foreach (Node sprite in GetChildren())\n"
-" tween.TweenProperty(sprite, \"position\", Vector2.Zero, 1.0f);\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"In the example above, all children of a node are moved one after another to "
-"position (0, 0).\n"
-"You should avoid using more than one [Tween] per object's property. If two or "
-"more tweens animate one property at the same time, the last one created will "
-"take priority and assign the final value. If you want to interrupt and "
-"restart an animation, consider assigning the [Tween] to a variable:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween\n"
-"func animate():\n"
-" if tween:\n"
-" tween.kill() # Abort the previous animation.\n"
-" tween = create_tween()\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"private Tween _tween;\n"
-"\n"
-"public void Animate()\n"
-"{\n"
-" if (_tween != null)\n"
-" _tween.Kill(); // Abort the previous animation\n"
-" _tween = CreateTween();\n"
-"}\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"Some [Tweener]s use transitions and eases. The first accepts a [enum "
-"TransitionType] constant, and refers to the way the timing of the animation "
-"is handled (see [url=https://easings.net/]easings.net[/url] for some "
-"examples). The second accepts an [enum EaseType] constant, and controls where "
-"the [code]trans_type[/code] is applied to the interpolation (in the "
-"beginning, the end, or both). If you don't know which transition and easing "
-"to pick, you can try different [enum TransitionType] constants with [constant "
-"EASE_IN_OUT], and use the one that looks best.\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.webp]Tween easing and transition types cheatsheet[/url]\n"
-"[b]Note:[/b] Tweens are not designed to be re-used and trying to do so "
-"results in an undefined behavior. Create a new Tween for each animation and "
-"every time you replay an animation from start. Keep in mind that Tweens start "
-"immediately, so only create a Tween when you want to start animating.\n"
-"[b]Note:[/b] The tween is processed after all of the nodes in the current "
-"frame, i.e. node's [method Node._process] method would be called before the "
-"timer (or [method Node._physics_process] depending on the value passed to "
-"[method set_process_mode])."
-msgstr ""
-"Tween 主要用于需要将一个数值属性插值到一系列值的动画。[i]tween[/i] 这个名字来"
-"自 [i]in-betweening[/i],这是一种动画技术,可以在其中指定 [i]关键帧[/i],然后"
-"计算机会插入出现在它们之间的帧。使用 [Tween] 制作动画被称为补间动画。\n"
-"[Tween] 比 [AnimationPlayer] 更适合事先不知道最终值的动画。例如,插入动态选择"
-"的相机缩放值最好使用 [Tween] 完成;很难使用 [AnimationPlayer] 节点做同样的事"
-"情。Tween 也比 [AnimationPlayer] 更轻量级,因此它们非常适合简单的动画,或不需"
-"要编辑器提供的视觉调整的通用任务。对于通常由代码完成的某些逻辑,它们可以以即用"
-"即弃的方式使用。例如,可以使用带延迟的循环 [CallbackTweener] 定期射击。\n"
-"可以使用 [method SceneTree.create_tween] 或 [method Node.create_tween] 创建 "
-"[Tween]。手动创建的 [Tween](即使用 [code]Tween.new()[/code])无效,不能用于对"
-"值进行补间。\n"
-"通过使用 [method tween_property]、[method tween_interval]、[method "
-"tween_callback]、或 [method tween_method],可将 [Tweener] 添加到 [Tween] 对象"
-"来创建一个补间动画:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween()\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = GetTree().CreateTween();\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"该序列将使 [code]$Sprite[/code] 节点变红,然后缩小,最后调用 [method Node."
-"queue_free] 来释放该精灵。默认情况下,[Tweener] 一个接一个地执行。这种行为可以"
-"使用 [method parallel] 和 [method set_parallel] 来更改。\n"
-"当使用 [code]tween_*[/code] 方法之一创建 [Tweener] 时,可以使用链式方法调用来"
-"调整该 [Tweener] 的属性。例如,如果想在上面的例子中设置一个不同的过渡类型,可"
-"以使用 [method set_trans]:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween()\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1).set_trans(Tween."
-"TRANS_SINE)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1).set_trans(Tween."
-"TRANS_BOUNCE)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = GetTree().CreateTween();\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f)."
-"SetTrans(Tween.TransitionType.Sine);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f)."
-"SetTrans(Tween.TransitionType.Bounce);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"大多数 [Tween] 方法也可以这样链式调用。在下面的示例中,[Tween] 被绑定到运行脚"
-"本的节点,并为其 [Tweener] 设置了默认过渡:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
-"TRANS_ELASTIC)\n"
-"tween.tween_property($Sprite, \"modulate\", Color.RED, 1)\n"
-"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
-"tween.tween_callback($Sprite.queue_free)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"var tween = GetTree().CreateTween().BindNode(this).SetTrans(Tween."
-"TransitionType.Elastic);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"modulate\", Colors.Red, 1.0f);\n"
-"tween.TweenProperty(GetNode(\"Sprite\"), \"scale\", Vector2.Zero, 1.0f);\n"
-"tween.TweenCallback(Callable.From(GetNode(\"Sprite\").QueueFree));\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"[Tween] 的另一个有趣用途是动画化任意对象集:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween = create_tween()\n"
-"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"Tween tween = CreateTween();\n"
-"foreach (Node sprite in GetChildren())\n"
-" tween.TweenProperty(sprite, \"position\", Vector2.Zero, 1.0f);\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"在上面的示例中,一个节点的所有子节点都被依次移动到位置 (0, 0)。\n"
-"应该避免为对象的同一属性使用多个 [Tween]。如果两个或多个补间同时为同一个属性设"
-"置动画,则最后创建的补间将优先使用,并分配最终值。如果要中断并重新启动动画,请"
-"考虑将 [Tween] 赋给变量:\n"
-"[codeblocks]\n"
-"[gdscript]\n"
-"var tween\n"
-"func animate():\n"
-" if tween:\n"
-" tween.kill() # 终止之前的补间动画。\n"
-" tween = create_tween()\n"
-"[/gdscript]\n"
-"[csharp]\n"
-"private Tween _tween;\n"
-"\n"
-"public void Animate()\n"
-"{\n"
-" if (_tween != null)\n"
-" _tween.Kill(); // 终止之前的补间动画。\n"
-" _tween = CreateTween();\n"
-"}\n"
-"[/csharp]\n"
-"[/codeblocks]\n"
-"一些 [Tweener] 会使用过渡和缓动。第一个接受一个 [enum TransitionType] 常量,指"
-"的是处理动画时间的方式(有关示例,请参见 [url=https://easings.net/]easings."
-"net[/url])。第二个接受一个 [enum EaseType] 常量,并控制 [code]trans_type[/"
-"code] 应用于插值的位置(在开头、结尾、或两者)。如果不知道该选择哪种过渡和缓"
-"动,可以尝试使用 [constant EASE_IN_OUT] 并配合不同 [enum TransitionType] 常"
-"量,并使用看起来最好的那个。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.webp]补间缓动与过渡类型速查表[/url]\n"
-"[b]注意:[/b]Tween 并不是针对重用设计的,尝试重用会造成未定义行为。每次从头开"
-"始重新播放每个动画都请新建一个 Tween。请记住,Tween 是会立即开始的,所以请只在"
-"需要开始动画时创建 Tween。\n"
-"[b]注意:[/b]Tween 在当前帧中的所有节点之后处理,即节点的 [method Node."
-"_process] 方法会在计时器之前调用(根据传给 [method set_process_mode] 的值,也"
-"可能是 [method Node._physics_process])。"
-
-msgid ""
"Binds this [Tween] with the given [param node]. [Tween]s are processed "
"directly by the [SceneTree], so they run independently of the animated nodes. "
"When you bind a [Node] with the [Tween], the [Tween] will halt the animation "
@@ -120186,10 +127087,10 @@ msgid ""
"For a shorter way to create and bind a [Tween], you can use [method Node."
"create_tween]."
msgstr ""
-"将这个 [Tween] 绑定到给定的 [code]node[/code] 上。[Tween] 是由 [SceneTree] 直"
-"接处理的,所以不依赖被动画的节点运行。将该 [Tween] 绑定到某个 [Node] 后,该对"
-"象不在树中时该 [Tween] 就会暂停动画,绑定对象被释放时该 [Tween] 会被自动销毁。"
-"另外,[constant TWEEN_PAUSE_BOUND] 会让暂停行为依赖于绑定的节点。\n"
+"将这个 [Tween] 绑定到给定的 [param node] 上。[Tween] 是由 [SceneTree] 直接处理"
+"的,所以不依赖被动画的节点运行。将该 [Tween] 绑定到某个 [Node] 后,该对象不在"
+"树中时该 [Tween] 就会暂停动画,绑定对象被释放时该 [Tween] 会被自动销毁。另外,"
+"[constant TWEEN_PAUSE_BOUND] 会让暂停行为依赖于绑定的节点。\n"
"使用 [method Node.create_tween] 来创建并绑定 [Tween] 更简单。"
msgid ""
@@ -120884,7 +127785,7 @@ msgid ""
"can't be created manually, you need to use a dedicated method from [Tween]."
msgstr ""
"Tweener 是执行特定动画化的任务的对象,例如,在给定的时间,插值一个属性或调用一"
-"个方法。[Tweener] 不能被手动创建,您需要使用 [Tween] 中的专用方法。"
+"个方法。[Tweener] 不能被手动创建,你需要使用 [Tween] 中的专用方法。"
msgid "Emitted when the [Tweener] has just finished its job."
msgstr "当该 [Tweener] 刚刚完成其任务时触发。"
@@ -122348,50 +129249,6 @@ msgid ""
msgstr "返回一个新向量,其所有分量都是绝对值,即正值。"
msgid ""
-"Returns this vector's angle with respect to the positive X axis, or [code](1, "
-"0)[/code] vector, in radians.\n"
-"For example, [code]Vector2.RIGHT.angle()[/code] will return zero, "
-"[code]Vector2.DOWN.angle()[/code] will return [code]PI / 2[/code] (a quarter "
-"turn, or 90 degrees), and [code]Vector2(1, -1).angle()[/code] will return "
-"[code]-PI / 4[/code] (a negative eighth turn, or -45 degrees).\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle.png]Illustration of the returned angle.[/url]\n"
-"Equivalent to the result of [method @GlobalScope.atan2] when called with the "
-"vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code]."
-msgstr ""
-"返回该向量与 X 轴正方向的夹角,单位为弧度。X 轴正方向为 [code](1, 0)[/code] 向"
-"量。\n"
-"例如,[code]Vector2.RIGHT.angle()[/code] 将返回 0,[code]Vector2.DOWN.angle()"
-"[/code] 将返回 [code]PI / 2[/code](四分之一圈,即 90 度),[code]Vector2(1, "
-"-1).angle()[/code] 将返回 [code]-PI / 4[/code](负八分之一圈,即 -45 度)。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle.png]返回夹角图示。[/url]\n"
-"相当于使用该向量的 [member y] 和 [member x] 作为参数对 [method @GlobalScope."
-"atan2] 进行调用的结果:[code]atan2(y, x)[/code]。"
-
-msgid ""
-"Returns the angle to the given vector, in radians.\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to.png]Illustration of the returned angle.[/url]"
-msgstr ""
-"返回与给定向量的夹角,单位为弧度。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to.png]返回夹角图示。[/url]"
-
-msgid ""
-"Returns the angle between the line connecting the two points and the X axis, "
-"in radians.\n"
-"[code]a.angle_to_point(b)[/code] is equivalent of doing [code](b - a).angle()"
-"[/code].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to_point.png]Illustration of the returned angle.[/url]"
-msgstr ""
-"返回连接两点的直线与 X 轴之间的夹角,单位为弧度。\n"
-"[code]a.angle_to_point(b)[/code] 等价于 [code](b - a).angle()[/code]。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"vector2_angle_to_point.png]返回夹角图示。[/url]"
-
-msgid ""
"Returns the aspect ratio of this vector, the ratio of [member x] to [member "
"y]."
msgstr "返回该向量的长宽比,即 [member x] 与 [member y] 的比例。"
@@ -126694,8 +133551,8 @@ msgid ""
"Defining this method is [b]required[/b]. If not overridden, the node has no "
"input ports."
msgstr ""
-"重写该方法以定义关联的自定义节点的输入端口数。\n"
-"定义该方法是[b]必需的[/b]。如果没有被重写,则该节点没有输入端口。"
+"覆盖该方法以定义关联的自定义节点的输入端口数。\n"
+"定义该方法是[b]必需的[/b]。如果没有被覆盖,则该节点没有输入端口。"
msgid ""
"Override this method to define the names of input ports of the associated "
@@ -126705,10 +133562,10 @@ msgid ""
"Defining this method is [b]optional[/b], but recommended. If not overridden, "
"input ports are named as [code]\"in\" + str(port)[/code]."
msgstr ""
-"重写此方法来定义相关自定义节点的输入端口的名称。这些名称既用于编辑器中的输入"
+"覆盖此方法来定义相关自定义节点的输入端口的名称。这些名称既用于编辑器中的输入"
"槽,也作为着色器代码中的标识符,并在[method _get_code]中的[code]input_vars[/"
"code]数组中传递。\n"
-"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被重写,输入端口被命名为"
+"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被覆盖,输入端口被命名为"
"[code]\"in\"+str(port)[/code]。"
msgid ""
@@ -126718,9 +133575,9 @@ msgid ""
"Defining this method is [b]optional[/b], but recommended. If not overridden, "
"input ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type."
msgstr ""
-"重写此方法以定义相关自定义节点的每个输入端口的返回类型,参阅[enum "
+"覆盖此方法以定义相关自定义节点的每个输入端口的返回类型,参阅[enum "
"VisualShaderNode.PortType]的可能类型。\n"
-"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被重写,输入端口将返回 "
+"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被覆盖,输入端口将返回 "
"[constant VisualShaderNode.PORT_TYPE_SCALAR] 类型。"
msgid ""
@@ -126729,8 +133586,8 @@ msgid ""
"Defining this method is [b]optional[/b], but recommended. If not overridden, "
"the node will be named as \"Unnamed\"."
msgstr ""
-"重写此方法来定义可视化着色器编辑器的成员对话框和图中的相关自定义节点的名称。\n"
-"定义这个方法是[b]可选的[/b],但推荐使用。如果不重写,节点将被命名为 "
+"覆盖此方法来定义可视化着色器编辑器的成员对话框和图中的相关自定义节点的名称。\n"
+"定义这个方法是[b]可选的[/b],但推荐使用。如果不覆盖,节点将被命名为 "
"\"Unnamed\"。"
msgid ""
@@ -126739,8 +133596,8 @@ msgid ""
"Defining this method is [b]required[/b]. If not overridden, the node has no "
"output ports."
msgstr ""
-"重写该方法以定义关联的自定义节点的输出端口数。\n"
-"定义该方法是[b]必需的[/b]。如果没有被重写,则该节点没有输出端口。"
+"覆盖该方法以定义关联的自定义节点的输出端口数。\n"
+"定义该方法是[b]必需的[/b]。如果没有被覆盖,则该节点没有输出端口。"
msgid ""
"Override this method to define the names of output ports of the associated "
@@ -126750,10 +133607,10 @@ msgid ""
"Defining this method is [b]optional[/b], but recommended. If not overridden, "
"output ports are named as [code]\"out\" + str(port)[/code]."
msgstr ""
-"重写此方法来定义相关自定义节点的输出端口的名称。这些名字既用于编辑器中的输出"
+"覆盖此方法来定义相关自定义节点的输出端口的名称。这些名字既用于编辑器中的输出"
"槽,也作为着色器代码中的标识符,并在[method _get_code]中的[code]output_vars[/"
"code]数组中传递。\n"
-"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被重写,输出端口被命名为"
+"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被覆盖,输出端口被命名为"
"[code]\"out\" + str(port)[/code]。"
msgid ""
@@ -126764,9 +133621,9 @@ msgid ""
"output ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] "
"type."
msgstr ""
-"重写此方法以定义相关自定义节点的每个输出端口的返回类型,参阅[enum "
+"覆盖此方法以定义相关自定义节点的每个输出端口的返回类型,参阅[enum "
"VisualShaderNode.PortType]的可能类型。\n"
-"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被重写,输出端口将返回"
+"定义这个方法是[b]可选的[/b],但推荐使用。如果没有被覆盖,输出端口将返回"
"[constant VisualShaderNode.PORT_TYPE_SCALAR]类型。"
msgid ""
@@ -126775,8 +133632,8 @@ msgid ""
"Defining this method is [b]optional[/b]. If not overridden, no return icon is "
"shown."
msgstr ""
-"重写此方法来定义可视化着色器编辑器的成员对话框中相关自定义节点的返回图标。\n"
-"定义这个方法是[b]可选的[/b]。如果不重写,就不会显示返回图标。"
+"覆盖此方法来定义可视化着色器编辑器的成员对话框中相关自定义节点的返回图标。\n"
+"定义这个方法是[b]可选的[/b]。如果不覆盖,就不会显示返回图标。"
msgid ""
"Override this method to prevent the node to be visible in the member dialog "
@@ -130358,8 +137215,8 @@ msgstr ""
" $Button.visible = false\n"
" # 这告诉 Godot 开始渲染到头戴设备。\n"
" get_viewport().use_xr = true\n"
-" # 这将是您最终获得的参考空间类型,与您在上面请求的类型不同。\n"
-" # 如果您希望游戏在 “bounded-floor” 和 “local-floor”\n"
+" # 这将是你最终获得的参考空间类型,与你在上面请求的类型不同。\n"
+" # 如果你希望游戏在 “bounded-floor” 和 “local-floor”\n"
" # 中的运行方式有所不同,这将很有用。\n"
" print (\"Reference space type: \" + webxr_interface."
"reference_space_type)\n"
@@ -130380,7 +137237,7 @@ msgstr ""
"制器。\n"
"- 使用 [signal select]、[signal squeeze] 和其他相关信号。这种方法适用于高级 "
"VR 控制器和非传统输入源,例如屏幕上的轻敲、语音命令或设备本身的按钮按下。\n"
-"您可以使用这两种方法来让您的游戏或应用程序支持更多或更窄的设备和输入法集,或者"
+"你可以使用这两种方法来让你的游戏或应用程序支持更多或更窄的设备和输入法集,或者"
"允许与更高级的设备进行更高级的交互。"
msgid "How to make a VR game for WebXR with Godot 4"
@@ -131200,7 +138057,7 @@ msgstr ""
msgid ""
"Specifies the initial type of position for the [Window]. See [enum "
"WindowInitialPosition] constants."
-msgstr "指定该 [Windows] 的初始位置类型。见 [enum WindowInitialPosition] 常量。"
+msgstr "指定该 [Window] 的初始位置类型。见 [enum WindowInitialPosition] 常量。"
msgid ""
"If non-zero, the [Window] can't be resized to be bigger than this size.\n"
@@ -131217,7 +138074,7 @@ msgid ""
"size is bigger."
msgstr ""
"如果非零,则调整该 [Window] 的大小时无法小于该尺寸。\n"
-"[b]注意:[/b] 如果启用了 [member wrap_controls] 并且 [method "
+"[b]注意:[/b]如果启用了 [member wrap_controls] 并且 [method "
"get_contents_minimum_size] 更大,则此属性将被忽略。"
msgid ""
@@ -131541,7 +138398,7 @@ msgstr ""
"全屏窗口模式。请注意,这不是[i]独占的[/i]全屏显示。在 Windows 和 Linux 上,无"
"边框窗口用于模拟全屏。在 macOS 上,会创建一个新的桌面用于显示正在运行的项"
"目。\n"
-"无论平台如何,启用全屏都会更改窗口大小以匹配显示器的大小。因此,请确保您的项目"
+"无论平台如何,启用全屏都会更改窗口大小以匹配显示器的大小。因此,请确保你的项目"
"在启用全屏模式时支持[url=$DOCS_URL/tutorials/rendering/multiple_resolutions."
"html]多种分辨率[/url]。"
@@ -132523,7 +139380,7 @@ msgstr ""
"XR 模式。\n"
"如果为处理自己输出的平台(例如 OpenVR)执行该操作,则 Godot 将只显示一只眼睛而"
"不会在屏幕上失真。或者,可以将单独的视口节点添加到场景并在该视口上启用 AR/VR。"
-"它将被用于输出到 HMD,让您可以在主窗口中自由地做任何您喜欢的事情,例如使用单独"
+"它将被用于输出到 HMD,让你可以在主窗口中自由地做任何你喜欢的事情,例如使用单独"
"的相机作为旁观者相机或渲染完全不同的东西。\n"
"虽然当前未使用,但可以激活其他接口。如果想跟踪来自其他平台的控制器,可能会希望"
"这样做。但是,此时只有一个接口可以渲染到 HMD。"
@@ -132563,7 +139420,7 @@ msgid ""
msgstr ""
"设置活动的环境混合模式。\n"
"[param mode] 是从下一帧开始的 [enum XRInterface.EnvironmentBlendMode]。\n"
-"[b]注意:[/b] 并非所有运行时都支持全部的环境混合模式,因此在启动时检查这一点很"
+"[b]注意:[/b]并非所有运行时都支持全部的环境混合模式,因此在启动时检查这一点很"
"重要。例如:\n"
"[codeblock]\n"
" func _ready():\n"
@@ -133081,7 +139938,7 @@ msgstr ""
"示,因为它们是在内部处理的。\n"
"当控制器被打开,并且 [XRInterface] 检测到它们时,此对象的实例会自动被添加到可"
"通过 [XRServer] 访问的活动追踪对象列表中。\n"
-"[XRController3D] 和 [XRAnchor3D] 都使用这种类型的对象,并且应该在您的项目中使"
+"[XRController3D] 和 [XRAnchor3D] 都使用这种类型的对象,并且应该在你的项目中使"
"用。位置追踪器只是使这一切正常工作的底层对象。这些大部分都是公开的,以便基于 "
"GDExtension 的接口,可以与它们交互。"
@@ -133223,14 +140080,14 @@ msgid ""
"teleport mechanism."
msgstr ""
"正确地理解这个函数非常重要。AR 和 VR 平台处理定位的方式略有不同。\n"
-"对于不提供空间跟踪的平台,我们的原点 (0,0,0) 是 HMD 的位置,但您几乎无法控制玩"
+"对于不提供空间跟踪的平台,我们的原点 (0,0,0) 是 HMD 的位置,但你几乎无法控制玩"
"家在现实世界中面对的方向。\n"
"对于提供空间跟踪的平台,我们的原点在很大程度上取决于系统。对于 OpenVR,原点通"
"常是地面上跟踪空间的中心。对于其他平台,它通常是跟踪相机的位置。\n"
-"此方法允许您将跟踪器置于 HMD 的位置。它将获取 HMD 的当前位置并使用它来调整您的"
+"此方法允许你将跟踪器置于 HMD 的位置。它将获取 HMD 的当前位置并使用它来调整你的"
"所有跟踪数据;从本质上讲,将现实世界重新调整到玩家在游戏世界中的当前位置。\n"
"为了使这种方法产生可用的结果,跟踪信息必须可用。这通常在开始游戏后需要几帧。\n"
-"您应该在几秒钟后调用此方法。例如,当用户请求重新调整显示时,按住控制器上的指定"
+"你应该在几秒钟后调用此方法。例如,当用户请求重新调整显示时,按住控制器上的指定"
"按钮一小段时间,或者当实现传送机制时。"
msgid ""
@@ -133308,7 +140165,7 @@ msgid ""
"important to react to this signal to add the appropriate [XRController3D] or "
"[XRAnchor3D] nodes related to this new tracker."
msgstr ""
-"当一个新的追踪器被添加时发出。如果您不使用一个固定数量的控制器,或者如果您将 "
+"当一个新的追踪器被添加时发出。如果你不使用一个固定数量的控制器,或者如果你将 "
"[XRAnchor3D] 用于一个 AR 解决方案,请务必对此信号做出反应,以添加与该新追踪器"
"相适的 [XRController3D] 或 [XRAnchor3D] 节点 。"
@@ -133319,7 +140176,7 @@ msgid ""
"available (i.e. a new controller is switched on that takes the place of the "
"previous one)."
msgstr ""
-"当一个追踪器被移除时发出。如此,您应该移除任何 [XRController3D] 或 "
+"当一个追踪器被移除时发出。如此,你应该移除任何 [XRController3D] 或 "
"[XRAnchor3D] 点。这不是强制性的,这些节点只是变得不活动,并且当一个新的追踪器"
"可用时,将再次激活(即打开一个新的控制器,来代替前一个控制器)。"
diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub
index 91240ce3e3..ce3a598573 100644
--- a/drivers/gl_context/SCsub
+++ b/drivers/gl_context/SCsub
@@ -2,7 +2,7 @@
Import("env")
-if env["platform"] in ["haiku", "macos", "windows", "linuxbsd"]:
+if env["platform"] in ["macos", "windows", "linuxbsd"]:
# Thirdparty source files
thirdparty_dir = "#thirdparty/glad/"
thirdparty_sources = [
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 0156876368..9818674de6 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -2115,7 +2115,7 @@ void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backb
if (render_target && render_target->clear_requested) {
const Color &col = render_target->clear_color;
- glClearColor(col.r, col.g, col.b, col.a);
+ glClearColor(col.r, col.g, col.b, render_target->is_transparent ? col.a : 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
render_target->clear_requested = false;
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index d66e5f51ed..29806bbece 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -63,7 +63,7 @@
#define _EXT_DEBUG_OUTPUT 0x92E0
#ifndef GLAPIENTRY
-#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED)
+#if defined(WINDOWS_ENABLED)
#define GLAPIENTRY APIENTRY
#else
#define GLAPIENTRY
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 7cba77be2f..8d3eabc55b 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -962,7 +962,9 @@ void main() {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
+#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
+#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@@ -1075,6 +1077,7 @@ void main() {
#ifndef MODE_RENDER_DEPTH
+#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
#ifndef DISABLE_FOG
// fog must be processed as early as possible and then packed.
@@ -1088,6 +1091,7 @@ void main() {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
+#endif // !FOG_DISABLED
// Convert colors to linear
albedo = srgb_to_linear(albedo);
@@ -1300,6 +1304,8 @@ void main() {
frag_color.rgb += emission + ambient_light;
#endif
#endif //MODE_UNSHADED
+
+#ifndef FOG_DISABLED
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
#ifndef DISABLE_FOG
@@ -1310,7 +1316,8 @@ void main() {
frag_color.rgb *= (1.0 - fog.a);
#endif // BASE_PASS
}
-#endif
+#endif // !DISABLE_FOG
+#endif // !FOG_DISABLED
// Tonemap before writing as we are writing to an sRGB framebuffer
frag_color.rgb *= exposure;
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index a36004209b..32b62ee605 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1358,6 +1358,7 @@ MaterialStorage::MaterialStorage() {
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+ actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index ec60d9e91a..5987c1675d 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -32,19 +32,21 @@
#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED)
-#include <string.h>
-
#ifdef WINDOWS_ENABLED
-#include <stdio.h>
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
-#ifndef UWP_ENABLED
+
#include <iphlpapi.h>
-#endif
+
+#include <stdio.h>
+
#else // UNIX
+
#include <netdb.h>
+
#ifdef ANDROID_ENABLED
// We could drop this file once we up our API level to 24,
// where the NDK's ifaddrs.h supports to needed getifaddrs.
@@ -55,13 +57,19 @@
#endif
#include <ifaddrs.h>
#endif
+
#include <arpa/inet.h>
#include <sys/socket.h>
+
#ifdef __FreeBSD__
#include <netinet/in.h>
#endif
-#include <net/if.h> // Order is important on OpenBSD, leave as last
-#endif
+
+#include <net/if.h> // Order is important on OpenBSD, leave as last.
+
+#endif // UNIX
+
+#include <string.h>
static IPAddress _sockaddr2ip(struct sockaddr *p_addr) {
IPAddress ip;
@@ -126,42 +134,6 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos
#if defined(WINDOWS_ENABLED)
-#if defined(UWP_ENABLED)
-
-void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
- using namespace Windows::Networking;
- using namespace Windows::Networking::Connectivity;
-
- // Returns addresses, not interfaces.
- auto hostnames = NetworkInformation::GetHostNames();
-
- for (int i = 0; i < hostnames->Size; i++) {
- auto hostname = hostnames->GetAt(i);
-
- if (hostname->Type != HostNameType::Ipv4 && hostname->Type != HostNameType::Ipv6) {
- continue;
- }
-
- String name = hostname->RawName->Data();
- HashMap<String, Interface_Info>::Element *E = r_interfaces->find(name);
- if (!E) {
- Interface_Info info;
- info.name = name;
- info.name_friendly = hostname->DisplayName->Data();
- info.index = String::num_uint64(0);
- E = r_interfaces->insert(name, info);
- ERR_CONTINUE(!E);
- }
-
- Interface_Info &info = E->get();
-
- IPAddress ip = IPAddress(hostname->CanonicalName->Data());
- info.ip_addresses.push_front(ip);
- }
-}
-
-#else
-
void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
ULONG buf_size = 1024;
IP_ADAPTER_ADDRESSES *addrs;
@@ -208,8 +180,6 @@ void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces)
memfree(addrs);
}
-#endif
-
#else // UNIX
void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
@@ -248,7 +218,8 @@ void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces)
freeifaddrs(ifAddrStruct);
}
}
-#endif
+
+#endif // UNIX
void IPUnix::make_default() {
_create = _create_unix;
@@ -261,4 +232,4 @@ IP *IPUnix::_create_unix() {
IPUnix::IPUnix() {
}
-#endif
+#endif // UNIX_ENABLED || WINDOWS_ENABLED
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 88eb89656a..26b8881c39 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -40,23 +40,10 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-/*
-
-[03:57] <reduz> yessopie, so i don't havemak to rely on unicows
-[03:58] <yessopie> reduz- yeah, all of the functions fail, and then you can call GetLastError () which will return 120
-[03:58] <drumstick> CategoryApl, hehe, what? :)
-[03:59] <CategoryApl> didn't Verona lead to some trouble
-[03:59] <yessopie> 120 = ERROR_CALL_NOT_IMPLEMENTED
-[03:59] <yessopie> (you can use that constant if you include winerr.h)
-[03:59] <CategoryApl> well answer with winning a compo
-
-[04:02] <yessopie> if ( SetCurrentDirectoryW ( L"." ) == FALSE && GetLastError () == ERROR_CALL_NOT_IMPLEMENTED ) { use ANSI }
-*/
-
struct DirAccessWindowsPrivate {
- HANDLE h; //handle for findfirstfile
+ HANDLE h; // handle for FindFirstFile.
WIN32_FIND_DATA f;
- WIN32_FIND_DATAW fu; //unicode version
+ WIN32_FIND_DATAW fu; // Unicode version.
};
String DirAccessWindows::fix_path(String p_path) const {
@@ -358,12 +345,6 @@ DirAccessWindows::DirAccessWindows() {
p->h = INVALID_HANDLE_VALUE;
current_dir = ".";
-#ifdef UWP_ENABLED
- Windows::Storage::StorageFolder ^ install_folder = Windows::ApplicationModel::Package::Current->InstalledLocation;
- change_dir(install_folder->Path->Data());
-
-#else
-
DWORD mask = GetLogicalDrives();
for (int i = 0; i < MAX_DRIVES; i++) {
@@ -375,7 +356,6 @@ DirAccessWindows::DirAccessWindows() {
}
change_dir(".");
-#endif
}
DirAccessWindows::~DirAccessWindows() {
@@ -384,4 +364,4 @@ DirAccessWindows::~DirAccessWindows() {
memdelete(p);
}
-#endif //windows DirAccess support
+#endif // WINDOWS_ENABLED
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 36b19198e6..d47b315c40 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/event_listener_line_edit.h"
#include "editor/input_event_configuration_dialog.h"
#include "scene/gui/check_button.h"
@@ -355,7 +356,7 @@ void ActionMapEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- action_list_search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ action_list_search->set_right_icon(get_editor_theme_icon(SNAME("Search")));
if (!actions_cache.is_empty()) {
update_action_list();
}
@@ -442,13 +443,13 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
bool events_eq = Shortcut::is_event_array_equal(action_info.action_initial["events"], action_info.action["events"]);
bool action_eq = deadzone_eq && events_eq;
action_item->set_meta("__action_initial", action_info.action_initial);
- action_item->add_button(2, action_tree->get_theme_icon(SNAME("ReloadSmall"), SNAME("EditorIcons")), BUTTON_REVERT_ACTION, action_eq, action_eq ? TTR("Cannot Revert - Action is same as initial") : TTR("Revert Action"));
+ action_item->add_button(2, action_tree->get_editor_theme_icon(SNAME("ReloadSmall")), BUTTON_REVERT_ACTION, action_eq, action_eq ? TTR("Cannot Revert - Action is same as initial") : TTR("Revert Action"));
}
- action_item->add_button(2, action_tree->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), BUTTON_ADD_EVENT, false, TTR("Add Event"));
- action_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? TTR("Remove Action") : TTR("Cannot Remove Action"));
+ action_item->add_button(2, action_tree->get_editor_theme_icon(SNAME("Add")), BUTTON_ADD_EVENT, false, TTR("Add Event"));
+ action_item->add_button(2, action_tree->get_editor_theme_icon(SNAME("Remove")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? TTR("Remove Action") : TTR("Cannot Remove Action"));
- action_item->set_custom_bg_color(0, action_tree->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
- action_item->set_custom_bg_color(1, action_tree->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ action_item->set_custom_bg_color(0, action_tree->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
+ action_item->set_custom_bg_color(1, action_tree->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
for (int evnt_idx = 0; evnt_idx < events.size(); evnt_idx++) {
Ref<InputEvent> event = events[evnt_idx];
@@ -467,34 +468,34 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
Ref<InputEventKey> k = event;
if (k.is_valid()) {
if (k->get_physical_keycode() == Key::NONE && k->get_keycode() == Key::NONE && k->get_key_label() != Key::NONE) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardLabel"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("KeyboardLabel")));
} else if (k->get_keycode() != Key::NONE) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("Keyboard")));
} else if (k->get_physical_keycode() != Key::NONE) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("KeyboardPhysical")));
} else {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardError"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("KeyboardError")));
}
}
Ref<InputEventMouseButton> mb = event;
if (mb.is_valid()) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("Mouse"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("Mouse")));
}
Ref<InputEventJoypadButton> jb = event;
if (jb.is_valid()) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("JoyButton"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("JoyButton")));
}
Ref<InputEventJoypadMotion> jm = event;
if (jm.is_valid()) {
- event_item->set_icon(0, action_tree->get_theme_icon(SNAME("JoyAxis"), SNAME("EditorIcons")));
+ event_item->set_icon(0, action_tree->get_editor_theme_icon(SNAME("JoyAxis")));
}
// Third Column - Buttons
- event_item->add_button(2, action_tree->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), BUTTON_EDIT_EVENT, false, TTR("Edit Event"));
- event_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_EVENT, false, TTR("Remove Event"));
+ event_item->add_button(2, action_tree->get_editor_theme_icon(SNAME("Edit")), BUTTON_EDIT_EVENT, false, TTR("Edit Event"));
+ event_item->add_button(2, action_tree->get_editor_theme_icon(SNAME("Remove")), BUTTON_REMOVE_EVENT, false, TTR("Remove Event"));
event_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
event_item->set_button_color(2, 1, Color(1, 1, 1, 0.75));
}
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 8defa04ada..23c1665cad 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/view_panner.h"
#include "scene/resources/text_line.h"
@@ -220,9 +221,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- bezier_icon = get_theme_icon(SNAME("KeyBezierPoint"), SNAME("EditorIcons"));
- bezier_handle_icon = get_theme_icon(SNAME("KeyBezierHandle"), SNAME("EditorIcons"));
- selected_icon = get_theme_icon(SNAME("KeyBezierSelected"), SNAME("EditorIcons"));
+ bezier_icon = get_editor_theme_icon(SNAME("KeyBezierPoint"));
+ bezier_handle_icon = get_editor_theme_icon(SNAME("KeyBezierHandle"));
+ selected_icon = get_editor_theme_icon(SNAME("KeyBezierSelected"));
} break;
case NOTIFICATION_DRAW: {
@@ -233,7 +234,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
int limit = timeline->get_name_limit();
if (has_focus()) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
accent.a *= 0.7;
draw_rect(Rect2(Point2(), get_size()), accent, false, Math::round(EDSCALE));
}
@@ -330,20 +331,20 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
}
}
- Color dc = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
+ Color dc = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor));
- Ref<Texture2D> remove = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"));
+ Ref<Texture2D> remove = get_editor_theme_icon(SNAME("Remove"));
float remove_hpos = limit - hsep - remove->get_width();
- Ref<Texture2D> lock = get_theme_icon(SNAME("Lock"), SNAME("EditorIcons"));
- Ref<Texture2D> unlock = get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons"));
+ Ref<Texture2D> lock = get_editor_theme_icon(SNAME("Lock"));
+ Ref<Texture2D> unlock = get_editor_theme_icon(SNAME("Unlock"));
float lock_hpos = remove_hpos - hsep - lock->get_width();
- Ref<Texture2D> visibility_visible = get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"));
- Ref<Texture2D> visibility_hidden = get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"));
+ Ref<Texture2D> visibility_visible = get_editor_theme_icon(SNAME("GuiVisibilityVisible"));
+ Ref<Texture2D> visibility_hidden = get_editor_theme_icon(SNAME("GuiVisibilityHidden"));
float visibility_hpos = lock_hpos - hsep - visibility_visible->get_width();
- Ref<Texture2D> solo = get_theme_icon(SNAME("AudioBusSolo"), SNAME("EditorIcons"));
+ Ref<Texture2D> solo = get_editor_theme_icon(SNAME("AudioBusSolo"));
float solo_hpos = visibility_hpos - hsep - solo->get_width();
float buttons_width = remove->get_width() + lock->get_width() + visibility_visible->get_width() + solo->get_width() + hsep * 3;
@@ -391,7 +392,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
subtracks[current_track] = rect;
} else {
- Color ac = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color ac = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
ac.a = 0.5;
draw_rect(rect, ac);
if (locked_tracks.has(selected_track)) {
@@ -441,7 +442,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
}
}
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
{ //guides
float min_left_scale = font->get_height(font_size) + vsep;
@@ -482,7 +483,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
{ //draw OTHER curves
float scale = timeline->get_zoom_scale();
- Ref<Texture2D> point = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons"));
+ Ref<Texture2D> point = get_editor_theme_icon(SNAME("KeyValue"));
for (const KeyValue<int, Color> &E : subtrack_colors) {
if (hidden_tracks.has(E.key)) {
continue;
@@ -630,10 +631,10 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
}
draw_rect(
Rect2(bs_from, bs_to - bs_from),
- get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")));
+ get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
draw_rect(
Rect2(bs_from, bs_to - bs_from),
- get_theme_color(SNAME("box_selection_stroke_color"), SNAME("Editor")),
+ get_theme_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)),
false,
Math::round(EDSCALE));
}
@@ -681,7 +682,7 @@ void AnimationBezierTrackEdit::_play_position_draw() {
int px = (-timeline->get_value() + play_position_pos) * scale + limit;
if (px >= limit && px < (get_size().width)) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE));
}
}
@@ -945,17 +946,17 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT);
if (selection.size()) {
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE);
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE);
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesFree"), SNAME("EditorIcons")), TTR("Make Handles Free"), MENU_KEY_SET_HANDLE_FREE);
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesLinear"), SNAME("EditorIcons")), TTR("Make Handles Linear"), MENU_KEY_SET_HANDLE_LINEAR);
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesBalanced"), SNAME("EditorIcons")), TTR("Make Handles Balanced"), MENU_KEY_SET_HANDLE_BALANCED);
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesMirror"), SNAME("EditorIcons")), TTR("Make Handles Mirrored"), MENU_KEY_SET_HANDLE_MIRRORED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesFree")), TTR("Make Handles Free"), MENU_KEY_SET_HANDLE_FREE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesLinear")), TTR("Make Handles Linear"), MENU_KEY_SET_HANDLE_LINEAR);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesBalanced")), TTR("Make Handles Balanced"), MENU_KEY_SET_HANDLE_BALANCED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesMirror")), TTR("Make Handles Mirrored"), MENU_KEY_SET_HANDLE_MIRRORED);
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesBalanced"), SNAME("EditorIcons")), TTR("Make Handles Balanced (Auto Tangent)"), MENU_KEY_SET_HANDLE_AUTO_BALANCED);
- menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesMirror"), SNAME("EditorIcons")), TTR("Make Handles Mirrored (Auto Tangent)"), MENU_KEY_SET_HANDLE_AUTO_MIRRORED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesBalanced")), TTR("Make Handles Balanced (Auto Tangent)"), MENU_KEY_SET_HANDLE_AUTO_BALANCED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("BezierHandlesMirror")), TTR("Make Handles Mirrored (Auto Tangent)"), MENU_KEY_SET_HANDLE_AUTO_MIRRORED);
}
if (menu->get_item_count()) {
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 3aa3aa567b..77ab709679 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_spin_slider.h"
#include "editor/gui/scene_tree_editor.h"
@@ -1304,10 +1305,10 @@ void AnimationTimelineEdit::_anim_loop_pressed() {
}
int AnimationTimelineEdit::get_buttons_width() const {
- Ref<Texture2D> interp_mode = get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons"));
- Ref<Texture2D> interp_type = get_theme_icon(SNAME("InterpRaw"), SNAME("EditorIcons"));
- Ref<Texture2D> loop_type = get_theme_icon(SNAME("InterpWrapClamp"), SNAME("EditorIcons"));
- Ref<Texture2D> remove_icon = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"));
+ Ref<Texture2D> interp_mode = get_editor_theme_icon(SNAME("TrackContinuous"));
+ Ref<Texture2D> interp_type = get_editor_theme_icon(SNAME("InterpRaw"));
+ Ref<Texture2D> loop_type = get_editor_theme_icon(SNAME("InterpWrapClamp"));
+ Ref<Texture2D> remove_icon = get_editor_theme_icon(SNAME("Remove"));
Ref<Texture2D> down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree"));
int total_w = interp_mode->get_width() + interp_type->get_width() + loop_type->get_width() + remove_icon->get_width();
@@ -1317,7 +1318,7 @@ int AnimationTimelineEdit::get_buttons_width() const {
}
int AnimationTimelineEdit::get_name_limit() const {
- Ref<Texture2D> hsize_icon = get_theme_icon(SNAME("Hsize"), SNAME("EditorIcons"));
+ Ref<Texture2D> hsize_icon = get_editor_theme_icon(SNAME("Hsize"));
int limit = MAX(name_limit, add_track->get_minimum_size().width + hsize_icon->get_width());
@@ -1331,20 +1332,20 @@ void AnimationTimelineEdit::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
- add_track->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons")));
- time_icon->set_texture(get_theme_icon(SNAME("Time"), SNAME("EditorIcons")));
+ add_track->set_icon(get_editor_theme_icon(SNAME("Add")));
+ loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
+ time_icon->set_texture(get_editor_theme_icon(SNAME("Time")));
add_track->get_popup()->clear();
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")), TTR("Property Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXPosition"), SNAME("EditorIcons")), TTR("3D Position Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXRotation"), SNAME("EditorIcons")), TTR("3D Rotation Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyXScale"), SNAME("EditorIcons")), TTR("3D Scale Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyBlendShape"), SNAME("EditorIcons")), TTR("Blend Shape Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyCall"), SNAME("EditorIcons")), TTR("Call Method Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyBezier"), SNAME("EditorIcons")), TTR("Bezier Curve Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyAudio"), SNAME("EditorIcons")), TTR("Audio Playback Track"));
- add_track->get_popup()->add_icon_item(get_theme_icon(SNAME("KeyAnimation"), SNAME("EditorIcons")), TTR("Animation Playback Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyValue")), TTR("Property Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXPosition")), TTR("3D Position Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXRotation")), TTR("3D Rotation Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXScale")), TTR("3D Scale Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBlendShape")), TTR("Blend Shape Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyCall")), TTR("Call Method Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBezier")), TTR("Bezier Curve Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAudio")), TTR("Audio Playback Track"));
+ add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAnimation")), TTR("Animation Playback Track"));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
@@ -1376,7 +1377,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
l = 0.0001; // Avoid crashor.
}
- Ref<Texture2D> hsize_icon = get_theme_icon(SNAME("Hsize"), SNAME("EditorIcons"));
+ Ref<Texture2D> hsize_icon = get_editor_theme_icon(SNAME("Hsize"));
hsize_rect = Rect2(get_name_limit() - hsize_icon->get_width() - 2 * EDSCALE, (get_size().height - hsize_icon->get_height()) / 2, hsize_icon->get_width(), hsize_icon->get_height());
draw_texture(hsize_icon, hsize_rect.position);
@@ -1417,7 +1418,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
int end_px = (l - get_value()) * scale;
int begin_px = -get_value() * scale;
- Color notimecol = get_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
+ Color notimecol = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor));
Color timecolor = color;
timecolor.a = 0.2;
Color linecolor = color;
@@ -1553,7 +1554,7 @@ Size2 AnimationTimelineEdit::get_minimum_size() const {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
ms.height = MAX(ms.height, font->get_height(font_size));
- ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_theme_icon(SNAME("Hsize"), SNAME("EditorIcons"))->get_width() + 2;
+ ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_editor_theme_icon(SNAME("Hsize"))->get_width() + 2;
return ms;
}
@@ -1602,15 +1603,15 @@ void AnimationTimelineEdit::update_values() {
switch (animation->get_loop_mode()) {
case Animation::LOOP_NONE: {
- loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons")));
+ loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
loop->set_pressed(false);
} break;
case Animation::LOOP_LINEAR: {
- loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons")));
+ loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
loop->set_pressed(true);
} break;
case Animation::LOOP_PINGPONG: {
- loop->set_icon(get_theme_icon(SNAME("PingPongLoop"), SNAME("EditorIcons")));
+ loop->set_icon(get_editor_theme_icon(SNAME("PingPongLoop")));
loop->set_pressed(true);
} break;
default:
@@ -1631,11 +1632,11 @@ void AnimationTimelineEdit::_play_position_draw() {
int px = (-get_value() + play_position_pos) * scale + get_name_limit();
if (px >= get_name_limit() && px < (play_position->get_size().width - get_buttons_width())) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE));
play_position->draw_texture(
- get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons")),
- Point2(px - get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons"))->get_width() * 0.5, 0),
+ get_editor_theme_icon(SNAME("TimelineIndicator")),
+ Point2(px - get_editor_theme_icon(SNAME("TimelineIndicator"))->get_width() * 0.5, 0),
color);
}
}
@@ -1813,7 +1814,7 @@ void AnimationTrackEdit::_notification(int p_what) {
ERR_FAIL_INDEX(track, animation->get_track_count());
type_icon = _get_key_type_icon();
- selected_icon = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons"));
+ selected_icon = get_editor_theme_icon(SNAME("KeySelected"));
} break;
case NOTIFICATION_DRAW: {
@@ -1835,10 +1836,10 @@ void AnimationTrackEdit::_notification(int p_what) {
}
if (has_focus()) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
accent.a *= 0.7;
// Offside so the horizontal sides aren't cutoff.
- draw_style_box(get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles")), Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0)));
+ draw_style_box(get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles)), Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0)));
}
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
@@ -1848,7 +1849,7 @@ void AnimationTrackEdit::_notification(int p_what) {
Color linecolor = color;
linecolor.a = 0.2;
- Color dc = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
+ Color dc = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor));
// NAMES AND ICONS //
@@ -1874,7 +1875,7 @@ void AnimationTrackEdit::_notification(int p_what) {
String text;
Color text_color = color;
if (node && EditorNode::get_singleton()->get_editor_selection()->is_selected(node)) {
- text_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ text_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
}
if (in_group) {
@@ -1949,24 +1950,24 @@ void AnimationTrackEdit::_notification(int p_what) {
{
Ref<Texture2D> wrap_icon[2] = {
- get_theme_icon(SNAME("InterpWrapClamp"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("InterpWrapLoop"), SNAME("EditorIcons")),
+ get_editor_theme_icon(SNAME("InterpWrapClamp")),
+ get_editor_theme_icon(SNAME("InterpWrapLoop")),
};
Ref<Texture2D> interp_icon[5] = {
- get_theme_icon(SNAME("InterpRaw"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("InterpLinear"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("InterpCubic"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("InterpLinearAngle"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("InterpCubicAngle"), SNAME("EditorIcons")),
+ get_editor_theme_icon(SNAME("InterpRaw")),
+ get_editor_theme_icon(SNAME("InterpLinear")),
+ get_editor_theme_icon(SNAME("InterpCubic")),
+ get_editor_theme_icon(SNAME("InterpLinearAngle")),
+ get_editor_theme_icon(SNAME("InterpCubicAngle")),
};
Ref<Texture2D> cont_icon[3] = {
- get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons"))
+ get_editor_theme_icon(SNAME("TrackContinuous")),
+ get_editor_theme_icon(SNAME("TrackDiscrete")),
+ get_editor_theme_icon(SNAME("TrackCapture"))
};
Ref<Texture2D> blend_icon[2] = {
- get_theme_icon(SNAME("UseBlendEnable"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("UseBlendDisable"), SNAME("EditorIcons")),
+ get_editor_theme_icon(SNAME("UseBlendEnable")),
+ get_editor_theme_icon(SNAME("UseBlendDisable")),
};
int ofs = get_size().width - timeline->get_buttons_width();
@@ -2096,7 +2097,7 @@ void AnimationTrackEdit::_notification(int p_what) {
{
// Erase.
- Ref<Texture2D> icon = get_theme_icon(animation->track_is_compressed(track) ? SNAME("Lock") : SNAME("Remove"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(animation->track_is_compressed(track) ? SNAME("Lock") : SNAME("Remove"));
remove_rect.position.x = ofs + ((get_size().width - ofs) - icon->get_width());
remove_rect.position.y = int(get_size().height - icon->get_height()) / 2;
@@ -2117,7 +2118,7 @@ void AnimationTrackEdit::_notification(int p_what) {
}
if (dropping_at != 0) {
- Color drop_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color drop_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
if (dropping_at < 0) {
draw_line(Vector2(0, 0), Vector2(get_size().width, 0), drop_color, Math::round(EDSCALE));
} else {
@@ -2202,7 +2203,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
if (animation->track_get_type(track) == Animation::TYPE_VALUE && !Math::is_equal_approx(animation->track_get_key_transition(track, p_index), real_t(1.0))) {
// Use a different icon for keys with non-linear easing.
- icon_to_draw = get_theme_icon(p_selected ? SNAME("KeyEasedSelected") : SNAME("KeyValueEased"), SNAME("EditorIcons"));
+ icon_to_draw = get_editor_theme_icon(p_selected ? SNAME("KeyEasedSelected") : SNAME("KeyValueEased"));
}
// Override type icon for invalid value keys, unless selected.
@@ -2210,7 +2211,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
const Variant &v = animation->track_get_key_value(track, p_index);
Variant::Type valid_type = Variant::NIL;
if (!_is_value_key_valid(v, valid_type)) {
- icon_to_draw = get_theme_icon(SNAME("KeyInvalid"), SNAME("EditorIcons"));
+ icon_to_draw = get_editor_theme_icon(SNAME("KeyInvalid"));
}
}
@@ -2333,7 +2334,7 @@ void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animati
node_path = animation->track_get_path(p_track);
type_icon = _get_key_type_icon();
- selected_icon = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons"));
+ selected_icon = get_editor_theme_icon(SNAME("KeySelected"));
}
NodePath AnimationTrackEdit::get_path() const {
@@ -2341,7 +2342,7 @@ NodePath AnimationTrackEdit::get_path() const {
}
Size2 AnimationTrackEdit::get_minimum_size() const {
- Ref<Texture2D> texture = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
+ Ref<Texture2D> texture = get_editor_theme_icon(SNAME("Object"));
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList"));
@@ -2374,7 +2375,7 @@ void AnimationTrackEdit::_play_position_draw() {
int px = (-timeline->get_value() + play_position_pos) * scale + timeline->get_name_limit();
if (px >= timeline->get_name_limit() && px < (get_size().width - timeline->get_buttons_width())) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE));
}
}
@@ -2432,15 +2433,15 @@ bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant
Ref<Texture2D> AnimationTrackEdit::_get_key_type_icon() const {
const Ref<Texture2D> type_icons[9] = {
- get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyTrackPosition"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyTrackRotation"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyTrackScale"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyTrackBlendShape"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyCall"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyBezier"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyAudio"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("KeyAnimation"), SNAME("EditorIcons"))
+ get_editor_theme_icon(SNAME("KeyValue")),
+ get_editor_theme_icon(SNAME("KeyTrackPosition")),
+ get_editor_theme_icon(SNAME("KeyTrackRotation")),
+ get_editor_theme_icon(SNAME("KeyTrackScale")),
+ get_editor_theme_icon(SNAME("KeyTrackBlendShape")),
+ get_editor_theme_icon(SNAME("KeyCall")),
+ get_editor_theme_icon(SNAME("KeyBezier")),
+ get_editor_theme_icon(SNAME("KeyAudio")),
+ get_editor_theme_icon(SNAME("KeyAnimation"))
};
return type_icons[animation->track_get_type(track)];
}
@@ -2663,12 +2664,12 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
menu->clear();
if (animation->track_get_type(track) == Animation::TYPE_AUDIO) {
- menu->add_icon_item(get_theme_icon(SNAME("UseBlendEnable"), SNAME("EditorIcons")), TTR("Use Blend"), MENU_USE_BLEND_ENABLED);
- menu->add_icon_item(get_theme_icon(SNAME("UseBlendDisable"), SNAME("EditorIcons")), TTR("Don't Use Blend"), MENU_USE_BLEND_DISABLED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("UseBlendEnable")), TTR("Use Blend"), MENU_USE_BLEND_ENABLED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("UseBlendDisable")), TTR("Don't Use Blend"), MENU_USE_BLEND_DISABLED);
} else {
- menu->add_icon_item(get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")), TTR("Continuous"), MENU_CALL_MODE_CONTINUOUS);
- menu->add_icon_item(get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")), TTR("Discrete"), MENU_CALL_MODE_DISCRETE);
- menu->add_icon_item(get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons")), TTR("Capture"), MENU_CALL_MODE_CAPTURE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("TrackContinuous")), TTR("Continuous"), MENU_CALL_MODE_CONTINUOUS);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("TrackDiscrete")), TTR("Discrete"), MENU_CALL_MODE_DISCRETE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("TrackCapture")), TTR("Capture"), MENU_CALL_MODE_CAPTURE);
}
menu->reset_size();
@@ -2685,9 +2686,9 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
menu->connect("id_pressed", callable_mp(this, &AnimationTrackEdit::_menu_selected));
}
menu->clear();
- menu->add_icon_item(get_theme_icon(SNAME("InterpRaw"), SNAME("EditorIcons")), TTR("Nearest"), MENU_INTERPOLATION_NEAREST);
- menu->add_icon_item(get_theme_icon(SNAME("InterpLinear"), SNAME("EditorIcons")), TTR("Linear"), MENU_INTERPOLATION_LINEAR);
- menu->add_icon_item(get_theme_icon(SNAME("InterpCubic"), SNAME("EditorIcons")), TTR("Cubic"), MENU_INTERPOLATION_CUBIC);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpRaw")), TTR("Nearest"), MENU_INTERPOLATION_NEAREST);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpLinear")), TTR("Linear"), MENU_INTERPOLATION_LINEAR);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpCubic")), TTR("Cubic"), MENU_INTERPOLATION_CUBIC);
// Check whether it is angle property.
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
@@ -2700,8 +2701,8 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
ClassDB::get_property_info(nd->get_class(), prop, &prop_info);
bool is_angle = prop_info.type == Variant::FLOAT && prop_info.hint_string.find("radians") != -1;
if (is_angle) {
- menu->add_icon_item(get_theme_icon(SNAME("InterpLinearAngle"), SNAME("EditorIcons")), TTR("Linear Angle"), MENU_INTERPOLATION_LINEAR_ANGLE);
- menu->add_icon_item(get_theme_icon(SNAME("InterpCubicAngle"), SNAME("EditorIcons")), TTR("Cubic Angle"), MENU_INTERPOLATION_CUBIC_ANGLE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpLinearAngle")), TTR("Linear Angle"), MENU_INTERPOLATION_LINEAR_ANGLE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpCubicAngle")), TTR("Cubic Angle"), MENU_INTERPOLATION_CUBIC_ANGLE);
}
}
}
@@ -2720,8 +2721,8 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
menu->connect("id_pressed", callable_mp(this, &AnimationTrackEdit::_menu_selected));
}
menu->clear();
- menu->add_icon_item(get_theme_icon(SNAME("InterpWrapClamp"), SNAME("EditorIcons")), TTR("Clamp Loop Interp"), MENU_LOOP_CLAMP);
- menu->add_icon_item(get_theme_icon(SNAME("InterpWrapLoop"), SNAME("EditorIcons")), TTR("Wrap Loop Interp"), MENU_LOOP_WRAP);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpWrapClamp")), TTR("Clamp Loop Interp"), MENU_LOOP_CLAMP);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("InterpWrapLoop")), TTR("Wrap Loop Interp"), MENU_LOOP_WRAP);
menu->reset_size();
Vector2 popup_pos = get_screen_position() + loop_wrap_rect.position + Vector2(0, loop_wrap_rect.size.height);
@@ -2818,18 +2819,18 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
menu->clear();
- menu->add_icon_item(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")), TTR("Insert Key"), MENU_KEY_INSERT);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Key"), MENU_KEY_INSERT);
if (editor->is_selection_active()) {
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Duplicate Key(s)"), MENU_KEY_DUPLICATE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Duplicate Key(s)"), MENU_KEY_DUPLICATE);
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
if (!player->has_animation(SceneStringNames::get_singleton()->RESET) || animation != player->get_animation(SceneStringNames::get_singleton()->RESET)) {
- menu->add_icon_item(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), TTR("Add RESET Value(s)"), MENU_KEY_ADD_RESET);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Reload")), TTR("Add RESET Value(s)"), MENU_KEY_ADD_RESET);
}
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Key(s)"), MENU_KEY_DELETE);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Key(s)"), MENU_KEY_DELETE);
}
menu->reset_size();
@@ -3215,11 +3216,11 @@ void AnimationTrackEditGroup::_notification(int p_what) {
if (root && root->has_node(node)) {
Node *n = root->get_node(node);
if (n && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) {
- color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
}
}
- Color bgcol = get_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
+ Color bgcol = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor));
bgcol.a *= 0.6;
draw_rect(Rect2(Point2(), get_size()), bgcol);
Color linecolor = color;
@@ -3237,7 +3238,7 @@ void AnimationTrackEditGroup::_notification(int p_what) {
int px = (-timeline->get_value() + timeline->get_play_position()) * timeline->get_zoom_scale() + timeline->get_name_limit();
if (px >= timeline->get_name_limit() && px < (get_size().width - timeline->get_buttons_width())) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_line(Point2(px, 0), Point2(px, get_size().height), accent, Math::round(2 * EDSCALE));
}
} break;
@@ -4434,7 +4435,7 @@ void AnimationTrackEditor::_update_tracks() {
if (!group_sort.has(base_path)) {
AnimationTrackEditGroup *g = memnew(AnimationTrackEditGroup);
- Ref<Texture2D> icon = get_theme_icon(SNAME("Node"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Node"));
String name = base_path;
String tooltip;
if (root && root->has_node(base_path)) {
@@ -4615,14 +4616,14 @@ void AnimationTrackEditor::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- zoom_icon->set_texture(get_theme_icon(SNAME("Zoom"), SNAME("EditorIcons")));
- bezier_edit_icon->set_icon(get_theme_icon(SNAME("EditBezier"), SNAME("EditorIcons")));
- snap->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- view_group->set_icon(get_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup"), SNAME("EditorIcons")));
- selected_filter->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons")));
- imported_anim_warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
+ zoom_icon->set_texture(get_editor_theme_icon(SNAME("Zoom")));
+ bezier_edit_icon->set_icon(get_editor_theme_icon(SNAME("EditBezier")));
+ snap->set_icon(get_editor_theme_icon(SNAME("Snap")));
+ view_group->set_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
+ selected_filter->set_icon(get_editor_theme_icon(SNAME("AnimationFilter")));
+ imported_anim_warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_editor_theme_icon(SNAME("Reload")));
} break;
case NOTIFICATION_READY: {
@@ -5312,8 +5313,8 @@ float AnimationTrackEditor::get_moving_selection_offset() const {
void AnimationTrackEditor::_box_selection_draw() {
const Rect2 selection_rect = Rect2(Point2(), box_selection->get_size());
- box_selection->draw_rect(selection_rect, get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")));
- box_selection->draw_rect(selection_rect, get_theme_color(SNAME("box_selection_stroke_color"), SNAME("Editor")), false, Math::round(EDSCALE));
+ box_selection->draw_rect(selection_rect, get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
+ box_selection->draw_rect(selection_rect, get_theme_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)), false, Math::round(EDSCALE));
}
void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
@@ -5590,10 +5591,10 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
String text;
- Ref<Texture2D> icon = get_theme_icon(SNAME("Node"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Node"));
if (node) {
- if (has_theme_icon(node->get_class(), SNAME("EditorIcons"))) {
- icon = get_theme_icon(node->get_class(), SNAME("EditorIcons"));
+ if (has_theme_icon(node->get_class(), EditorStringName(EditorIcons))) {
+ icon = get_editor_theme_icon(node->get_class());
}
text = node->get_name();
@@ -6249,7 +6250,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
void AnimationTrackEditor::_view_group_toggle() {
_update_tracks();
- view_group->set_icon(get_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup"), SNAME("EditorIcons")));
+ view_group->set_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
bezier_edit->set_filtered(selected_filter->is_pressed());
}
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 553f391a1d..91a0f213ec 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -33,6 +33,7 @@
#include "editor/audio_stream_preview.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/animated_sprite_2d.h"
#include "scene/2d/sprite_2d.h"
@@ -73,7 +74,7 @@ void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x,
draw_texture(icon, ofs);
if (p_selected) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect_clipped(Rect2(ofs, icon->get_size()), color, false);
}
}
@@ -180,7 +181,7 @@ void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x,
draw_rect_clipped(rect, color);
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect_clipped(rect, accent, false);
}
}
@@ -329,7 +330,7 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
RS::get_singleton()->canvas_item_add_multiline(get_canvas_item(), points, colors);
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect(rect, accent, false);
}
} else {
@@ -342,7 +343,7 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
draw_rect_clipped(rect, color);
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect_clipped(rect, accent, false);
}
}
@@ -541,7 +542,7 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
return;
}
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
Color bg = accent;
bg.a = 0.15;
@@ -700,7 +701,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
}
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect(rect, accent, false);
}
} else {
@@ -713,7 +714,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
draw_rect_clipped(rect, color);
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect_clipped(rect, accent, false);
}
}
@@ -726,12 +727,12 @@ void AnimationTrackEditSubAnim::set_node(Object *p_object) {
//// VOLUME DB ////
int AnimationTrackEditVolumeDB::get_key_height() const {
- Ref<Texture2D> volume_texture = get_theme_icon(SNAME("ColorTrackVu"), SNAME("EditorIcons"));
+ Ref<Texture2D> volume_texture = get_editor_theme_icon(SNAME("ColorTrackVu"));
return volume_texture->get_height() * 1.2;
}
void AnimationTrackEditVolumeDB::draw_bg(int p_clip_left, int p_clip_right) {
- Ref<Texture2D> volume_texture = get_theme_icon(SNAME("ColorTrackVu"), SNAME("EditorIcons"));
+ Ref<Texture2D> volume_texture = get_editor_theme_icon(SNAME("ColorTrackVu"));
int tex_h = volume_texture->get_height();
int y_from = (get_size().height - tex_h) / 2;
@@ -742,7 +743,7 @@ void AnimationTrackEditVolumeDB::draw_bg(int p_clip_left, int p_clip_right) {
}
void AnimationTrackEditVolumeDB::draw_fg(int p_clip_left, int p_clip_right) {
- Ref<Texture2D> volume_texture = get_theme_icon(SNAME("ColorTrackVu"), SNAME("EditorIcons"));
+ Ref<Texture2D> volume_texture = get_editor_theme_icon(SNAME("ColorTrackVu"));
int tex_h = volume_texture->get_height();
int y_from = (get_size().height - tex_h) / 2;
int db0 = y_from + (24 / 80.0) * tex_h;
@@ -777,7 +778,7 @@ void AnimationTrackEditVolumeDB::draw_key_link(int p_index, float p_pixels_sec,
to_x = p_clip_right;
}
- Ref<Texture2D> volume_texture = get_theme_icon(SNAME("ColorTrackVu"), SNAME("EditorIcons"));
+ Ref<Texture2D> volume_texture = get_editor_theme_icon(SNAME("ColorTrackVu"));
int tex_h = volume_texture->get_height();
int y_from = (get_size().height - tex_h) / 2;
@@ -936,7 +937,7 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
RS::get_singleton()->canvas_item_add_multiline(get_canvas_item(), points, colors);
- Color cut_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color cut_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
cut_color.a = 0.7;
if (start_ofs > 0 && pixel_begin > p_clip_left) {
draw_rect(Rect2(pixel_begin, rect.position.y, 1, rect.size.y), cut_color);
@@ -946,7 +947,7 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
}
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect(rect, accent, false);
}
}
@@ -1307,7 +1308,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
}
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect(rect, accent, false);
}
} else {
@@ -1320,7 +1321,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
draw_rect_clipped(rect, color);
if (p_selected) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect_clipped(rect, accent, false);
}
}
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 2123e79475..876fef078b 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -36,6 +36,7 @@
#include "core/templates/pair.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/script_editor_plugin.h"
#include "scene/resources/font.h"
@@ -93,11 +94,11 @@ void FindReplaceBar::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
- find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
- hide_button->set_texture_normal(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_texture_hover(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_texture_pressed(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ find_prev->set_icon(get_editor_theme_icon(SNAME("MoveUp")));
+ find_next->set_icon(get_editor_theme_icon(SNAME("MoveDown")));
+ hide_button->set_texture_normal(get_editor_theme_icon(SNAME("Close")));
+ hide_button->set_texture_hover(get_editor_theme_icon(SNAME("Close")));
+ hide_button->set_texture_pressed(get_editor_theme_icon(SNAME("Close")));
hide_button->set_custom_minimum_size(hide_button->get_texture_normal()->get_size());
} break;
@@ -106,7 +107,7 @@ void FindReplaceBar::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
case NOTIFICATION_PREDELETE: {
@@ -311,7 +312,7 @@ void FindReplaceBar::_replace_all() {
}
text_editor->set_v_scroll(vsval);
- matches_label->add_theme_color_override("font_color", rc > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ matches_label->add_theme_color_override("font_color", rc > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
matches_label->set_text(vformat(TTR("%d replaced."), rc));
text_editor->call_deferred(SNAME("connect"), "text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
@@ -407,7 +408,7 @@ void FindReplaceBar::_update_matches_label() {
} else {
matches_label->show();
- matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
if (results_count == 0) {
matches_label->set_text(TTR("No match"));
@@ -954,41 +955,41 @@ Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptLanguage::CodeCo
Ref<Texture2D> tex;
switch (p_option.kind) {
case ScriptLanguage::CODE_COMPLETION_KIND_CLASS: {
- if (has_theme_icon(p_option.display, SNAME("EditorIcons"))) {
- tex = get_theme_icon(p_option.display, SNAME("EditorIcons"));
+ if (has_theme_icon(p_option.display, EditorStringName(EditorIcons))) {
+ tex = get_editor_theme_icon(p_option.display);
} else {
- tex = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("Object"));
}
} break;
case ScriptLanguage::CODE_COMPLETION_KIND_ENUM:
- tex = get_theme_icon(SNAME("Enum"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("Enum"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH:
- tex = get_theme_icon(SNAME("File"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("File"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH:
- tex = get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("NodePath"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE:
- tex = get_theme_icon(SNAME("Variant"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("Variant"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT:
- tex = get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("MemberConstant"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_MEMBER:
- tex = get_theme_icon(SNAME("MemberProperty"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("MemberProperty"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL:
- tex = get_theme_icon(SNAME("MemberSignal"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("MemberSignal"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION:
- tex = get_theme_icon(SNAME("MemberMethod"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("MemberMethod"));
break;
case ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT:
- tex = get_theme_icon(SNAME("BoxMesh"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("BoxMesh"));
break;
default:
- tex = get_theme_icon(SNAME("String"), SNAME("EditorIcons"));
+ tex = get_editor_theme_icon(SNAME("String"));
break;
}
return tex;
@@ -1679,12 +1680,12 @@ void CodeTextEditor::_update_text_editor_theme() {
emit_signal(SNAME("load_theme_settings"));
error->begin_bulk_theme_override();
- error->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
- error->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ error->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
+ error->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
- Ref<Font> status_bar_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts"));
- int status_bar_font_size = get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"));
+ Ref<Font> status_bar_font = get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts));
+ int status_bar_font_size = get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts));
error->add_theme_font_override("font", status_bar_font);
error->add_theme_font_size_override("font_size", status_bar_font_size);
int count = status_bar->get_child_count();
@@ -1802,18 +1803,18 @@ void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) {
}
void CodeTextEditor::_update_status_bar_theme() {
- error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
- error_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- error_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+ error_button->set_icon(get_editor_theme_icon(SNAME("StatusError")));
+ error_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ error_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ error_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
- warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- warning_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- warning_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- warning_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+ warning_button->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ warning_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ warning_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ warning_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
- line_and_col_txt->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- line_and_col_txt->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+ line_and_col_txt->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ line_and_col_txt->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
}
void CodeTextEditor::_notification(int p_what) {
@@ -1949,9 +1950,9 @@ void CodeTextEditor::show_toggle_scripts_button() {
void CodeTextEditor::update_toggle_scripts_button() {
if (is_layout_rtl()) {
- toggle_scripts_button->set_icon(get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons")));
+ toggle_scripts_button->set_icon(get_editor_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Forward") : SNAME("Back")));
} else {
- toggle_scripts_button->set_icon(get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons")));
+ toggle_scripts_button->set_icon(get_editor_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Back") : SNAME("Forward")));
}
toggle_scripts_button->set_tooltip_text(vformat("%s (%s)", TTR("Toggle Scripts Panel"), ED_GET_SHORTCUT("script_editor/toggle_scripts_panel")->get_as_text()));
}
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index b3ca04420f..11fc5efd62 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/node_dock.h"
@@ -323,7 +324,7 @@ List<MethodInfo> ConnectDialog::_filter_method_list(const List<MethodInfo> &p_me
void ConnectDialog::_update_method_tree() {
method_tree->clear();
- Color disabled_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")) * 0.7;
+ Color disabled_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)) * 0.7;
String search_string = method_search->get_text();
Node *target = tree->get_selected();
if (!target) {
@@ -359,7 +360,7 @@ void ConnectDialog::_update_method_tree() {
if (!methods.is_empty()) {
TreeItem *si_item = method_tree->create_item(root_item);
si_item->set_text(0, TTR("Attached Script"));
- si_item->set_icon(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")));
+ si_item->set_icon(0, get_editor_theme_icon(SNAME("Script")));
si_item->set_selectable(0, false);
_create_method_tree_items(methods, si_item);
@@ -376,9 +377,9 @@ void ConnectDialog::_update_method_tree() {
do {
TreeItem *class_item = method_tree->create_item(root_item);
class_item->set_text(0, current_class);
- Ref<Texture2D> icon = get_theme_icon(SNAME("Node"), SNAME("EditorIcons"));
- if (has_theme_icon(current_class, SNAME("EditorIcons"))) {
- icon = get_theme_icon(current_class, SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Node"));
+ if (has_theme_icon(current_class, EditorStringName(EditorIcons))) {
+ icon = get_editor_theme_icon(current_class);
}
class_item->set_icon(0, icon);
class_item->set_selectable(0, false);
@@ -443,7 +444,7 @@ void ConnectDialog::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
for (int i = 0; i < type_list->get_item_count(); i++) {
String type_name = Variant::get_type_name((Variant::Type)type_list->get_item_id(i));
- type_list->set_item_icon(i, get_theme_icon(type_name, SNAME("EditorIcons")));
+ type_list->set_item_icon(i, get_editor_theme_icon(type_name));
}
Ref<StyleBox> style = get_theme_stylebox("normal", "LineEdit")->duplicate();
@@ -451,8 +452,8 @@ void ConnectDialog::_notification(int p_what) {
style->set_content_margin(SIDE_TOP, style->get_content_margin(SIDE_TOP) + 1.0);
from_signal->add_theme_style_override("normal", style);
}
- method_search->set_right_icon(get_theme_icon("Search", "EditorIcons"));
- open_method_tree->set_icon(get_theme_icon("Edit", "EditorIcons"));
+ method_search->set_right_icon(get_editor_theme_icon("Search"));
+ open_method_tree->set_icon(get_editor_theme_icon("Edit"));
} break;
}
}
@@ -592,7 +593,7 @@ void ConnectDialog::init(const ConnectionData &p_cd, const PackedStringArray &p_
void ConnectDialog::popup_dialog(const String p_for_signal) {
from_signal->set_text(p_for_signal);
- error_label->add_theme_color_override("font_color", error_label->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", error_label->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
filter_nodes->clear();
if (!advanced->is_pressed()) {
@@ -995,15 +996,15 @@ void ConnectionsDock::_tree_item_selected() {
TreeItem *item = tree->get_selected();
if (item && _get_item_type(*item) == TREE_ITEM_TYPE_SIGNAL) {
connect_button->set_text(TTR("Connect..."));
- connect_button->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
+ connect_button->set_icon(get_editor_theme_icon(SNAME("Instance")));
connect_button->set_disabled(false);
} else if (item && _get_item_type(*item) == TREE_ITEM_TYPE_CONNECTION) {
connect_button->set_text(TTR("Disconnect"));
- connect_button->set_icon(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons")));
+ connect_button->set_icon(get_editor_theme_icon(SNAME("Unlinked")));
connect_button->set_disabled(false);
} else {
connect_button->set_text(TTR("Connect..."));
- connect_button->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
+ connect_button->set_icon(get_editor_theme_icon(SNAME("Instance")));
connect_button->set_disabled(true);
}
}
@@ -1261,18 +1262,18 @@ void ConnectionsDock::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- class_menu->set_item_icon(class_menu->get_item_index(CLASS_MENU_OPEN_DOCS), get_theme_icon(SNAME("Help"), SNAME("EditorIcons")));
+ class_menu->set_item_icon(class_menu->get_item_index(CLASS_MENU_OPEN_DOCS), get_editor_theme_icon(SNAME("Help")));
- signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_CONNECT), get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
- signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_DISCONNECT_ALL), get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons")));
- signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_COPY_NAME), get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
- signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_OPEN_DOCS), get_theme_icon(SNAME("Help"), SNAME("EditorIcons")));
+ signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_CONNECT), get_editor_theme_icon(SNAME("Instance")));
+ signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_DISCONNECT_ALL), get_editor_theme_icon(SNAME("Unlinked")));
+ signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_COPY_NAME), get_editor_theme_icon(SNAME("ActionCopy")));
+ signal_menu->set_item_icon(signal_menu->get_item_index(SIGNAL_MENU_OPEN_DOCS), get_editor_theme_icon(SNAME("Help")));
- slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_EDIT), get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_GO_TO_METHOD), get_theme_icon(SNAME("ArrowRight"), SNAME("EditorIcons")));
- slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_DISCONNECT), get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons")));
+ slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_EDIT), get_editor_theme_icon(SNAME("Edit")));
+ slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_GO_TO_METHOD), get_editor_theme_icon(SNAME("ArrowRight")));
+ slot_menu->set_item_icon(slot_menu->get_item_index(SLOT_MENU_DISCONNECT), get_editor_theme_icon(SNAME("Unlinked")));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
@@ -1342,8 +1343,8 @@ void ConnectionsDock::update_tree() {
}
class_icon = editor_data.get_script_icon(script_base);
- if (class_icon.is_null() && has_theme_icon(native_base, SNAME("EditorIcons"))) {
- class_icon = get_theme_icon(native_base, SNAME("EditorIcons"));
+ if (class_icon.is_null() && has_theme_icon(native_base, EditorStringName(EditorIcons))) {
+ class_icon = get_editor_theme_icon(native_base);
}
script_base->get_script_signal_list(&class_signals);
@@ -1382,8 +1383,8 @@ void ConnectionsDock::update_tree() {
doc_class_name = String();
}
- if (has_theme_icon(native_base, SNAME("EditorIcons"))) {
- class_icon = get_theme_icon(native_base, SNAME("EditorIcons"));
+ if (has_theme_icon(native_base, EditorStringName(EditorIcons))) {
+ class_icon = get_editor_theme_icon(native_base);
}
ClassDB::get_signal_list(native_base, &class_signals, true);
@@ -1392,7 +1393,7 @@ void ConnectionsDock::update_tree() {
}
if (class_icon.is_null()) {
- class_icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
+ class_icon = get_editor_theme_icon(SNAME("Object"));
}
TreeItem *section_item = nullptr;
@@ -1408,7 +1409,7 @@ void ConnectionsDock::update_tree() {
section_item->set_icon(0, class_icon);
section_item->set_selectable(0, false);
section_item->set_editable(0, false);
- section_item->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ section_item->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
section_item->set_metadata(0, doc_class_name);
}
@@ -1434,7 +1435,7 @@ void ConnectionsDock::update_tree() {
sinfo["name"] = signal_name;
sinfo["args"] = argnames;
signal_item->set_metadata(0, sinfo);
- signal_item->set_icon(0, get_theme_icon(SNAME("Signal"), SNAME("EditorIcons")));
+ signal_item->set_icon(0, get_editor_theme_icon(SNAME("Signal")));
// Set tooltip with the signal's documentation.
{
@@ -1491,11 +1492,11 @@ void ConnectionsDock::update_tree() {
TreeItem *connection_item = tree->create_item(signal_item);
connection_item->set_text(0, path);
connection_item->set_metadata(0, connection);
- connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
+ connection_item->set_icon(0, get_editor_theme_icon(SNAME("Slot")));
if (_is_connection_inherited(connection)) {
// The scene inherits this connection.
- connection_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ connection_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
connection_item->set_meta("_inherited_connection", true);
}
}
@@ -1503,7 +1504,7 @@ void ConnectionsDock::update_tree() {
}
connect_button->set_text(TTR("Connect..."));
- connect_button->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
+ connect_button->set_icon(get_editor_theme_icon(SNAME("Instance")));
connect_button->set_disabled(true);
}
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index e2cb989e6a..a8a2ac0c20 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -37,11 +37,12 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_current_type, const String &p_current_name) {
_fill_type_list();
- icon_fallback = search_options->has_theme_icon(base_type, SNAME("EditorIcons")) ? base_type : "Object";
+ icon_fallback = search_options->has_theme_icon(base_type, EditorStringName(EditorIcons)) ? base_type : "Object";
if (p_dont_clear) {
search_box->select_all();
@@ -170,7 +171,7 @@ void CreateDialog::_update_search() {
TreeItem *root = search_options->create_item();
root->set_text(0, base_type);
- root->set_icon(0, search_options->get_theme_icon(icon_fallback, SNAME("EditorIcons")));
+ root->set_icon(0, search_options->get_editor_theme_icon(icon_fallback));
search_options_types[base_type] = root;
_configure_search_option_item(root, base_type, ClassDB::class_exists(base_type) ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE);
@@ -295,16 +296,16 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type));
if (!instantiable) {
- r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
}
bool is_deprecated = EditorHelp::get_doc_data()->class_list[p_type].is_deprecated;
bool is_experimental = EditorHelp::get_doc_data()->class_list[p_type].is_experimental;
if (is_deprecated) {
- r_item->add_button(0, get_theme_icon("StatusError", SNAME("EditorIcons")), 0, false, TTR("This class is marked as deprecated."));
+ r_item->add_button(0, get_editor_theme_icon("StatusError"), 0, false, TTR("This class is marked as deprecated."));
} else if (is_experimental) {
- r_item->add_button(0, get_theme_icon("NodeWarning", SNAME("EditorIcons")), 0, false, TTR("This class is marked as experimental."));
+ r_item->add_button(0, get_editor_theme_icon("NodeWarning"), 0, false, TTR("This class is marked as experimental."));
}
if (!search_box->get_text().is_empty()) {
@@ -450,8 +451,8 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
}
void CreateDialog::_update_theme() {
- search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- favorite->set_icon(search_options->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+ search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
+ favorite->set_icon(search_options->get_editor_theme_icon(SNAME("Favorites")));
}
void CreateDialog::_notification(int p_what) {
@@ -475,7 +476,7 @@ void CreateDialog::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- const int icon_width = get_theme_constant(SNAME("class_icon_size"), SNAME("Editor"));
+ const int icon_width = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
search_options->add_theme_constant_override("icon_max_width", icon_width);
favorites->add_theme_constant_override("icon_max_width", icon_width);
recent->set_fixed_icon_size(Size2(icon_width, icon_width));
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 6143f5ac00..99c66261e4 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_run_bar.h"
#include "editor/inspector_dock.h"
@@ -62,8 +63,8 @@ EditorDebuggerNode::EditorDebuggerNode() {
singleton = this;
}
- add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT));
- add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT));
+ add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
+ add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
tabs = memnew(TabContainer);
tabs->set_tabs_visible(false);
@@ -118,7 +119,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
if (tabs->get_tab_count() > 1) {
node->clear_style();
tabs->set_tabs_visible(true);
- tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles")));
+ tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
}
if (!debugger_plugins.is_empty()) {
@@ -283,10 +284,10 @@ void EditorDebuggerNode::_notification(int p_what) {
switch (p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (tabs->get_tab_count() > 1) {
- add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT));
- add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT));
+ add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
+ add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
- tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles")));
+ tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
}
} break;
@@ -386,15 +387,15 @@ void EditorDebuggerNode::_update_errors() {
} else {
debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")");
if (error_count >= 1 && warning_count >= 1) {
- debugger_button->set_icon(get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons")));
+ debugger_button->set_icon(get_editor_theme_icon(SNAME("ErrorWarning")));
// Use error color to represent the highest level of severity reported.
- debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} else if (error_count >= 1) {
- debugger_button->set_icon(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
- debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ debugger_button->set_icon(get_editor_theme_icon(SNAME("Error")));
+ debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} else {
- debugger_button->set_icon(get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
- debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ debugger_button->set_icon(get_editor_theme_icon(SNAME("Warning")));
+ debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
}
}
last_error_count = error_count;
diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h
index e855fa6ee0..8ca709dd9b 100644
--- a/editor/debugger/editor_debugger_node.h
+++ b/editor/debugger/editor_debugger_node.h
@@ -31,6 +31,7 @@
#ifndef EDITOR_DEBUGGER_NODE_H
#define EDITOR_DEBUGGER_NODE_H
+#include "core/object/script_language.h"
#include "editor/debugger/editor_debugger_server.h"
#include "scene/gui/margin_container.h"
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index 65f8951c30..2e24a233a1 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -115,8 +115,8 @@ void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position, Mou
item->select(0);
item_menu->clear();
- item_menu->add_icon_item(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), TTR("Save Branch as Scene"), ITEM_MENU_SAVE_REMOTE_NODE);
- item_menu->add_icon_item(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), TTR("Copy Node Path"), ITEM_MENU_COPY_NODE_PATH);
+ item_menu->add_icon_item(get_editor_theme_icon(SNAME("CreateNewSceneFrom")), TTR("Save Branch as Scene"), ITEM_MENU_SAVE_REMOTE_NODE);
+ item_menu->add_icon_item(get_editor_theme_icon(SNAME("CopyNodePath")), TTR("Copy Node Path"), ITEM_MENU_COPY_NODE_PATH);
item_menu->set_position(get_screen_position() + get_local_mouse_position());
item_menu->reset_size();
item_menu->popup();
@@ -198,7 +198,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
const Color remote_button_color = Color(1, 1, 1, 0.8);
if (!node.scene_file_path.is_empty()) {
String node_scene_file_path = node.scene_file_path;
- Ref<Texture2D> button_icon = get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons"));
+ Ref<Texture2D> button_icon = get_editor_theme_icon(SNAME("InstanceOptions"));
String tooltip = vformat(TTR("This node has been instantiated from a PackedScene file:\n%s\nClick to open the original file in the Editor."), node_scene_file_path);
item->set_meta("scene_file_path", node_scene_file_path);
@@ -209,7 +209,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
if (node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_HAS_VISIBLE_METHOD) {
bool node_visible = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE;
bool node_visible_in_tree = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE_IN_TREE;
- Ref<Texture2D> button_icon = get_theme_icon(node_visible ? SNAME("GuiVisibilityVisible") : SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"));
+ Ref<Texture2D> button_icon = get_editor_theme_icon(node_visible ? SNAME("GuiVisibilityVisible") : SNAME("GuiVisibilityHidden"));
String tooltip = TTR("Toggle Visibility");
item->set_meta("visible", node_visible);
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index 641c7d3114..e6e9d4e33d 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "main/performance.h"
EditorPerformanceProfiler::Monitor::Monitor() {}
@@ -131,7 +132,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
rect.position += graph_style_box->get_offset();
rect.size -= graph_style_box->get_minimum_size();
- Color draw_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color draw_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_color.set_hsv(Math::fmod(hue_shift * float(current.frame_index), 0.9f), draw_color.get_s() * 0.9f, draw_color.get_v() * value_multiplier, 0.6f);
monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color);
@@ -235,7 +236,7 @@ TreeItem *EditorPerformanceProfiler::_get_monitor_base(const StringName &p_base_
base->set_selectable(0, false);
base->set_expand_right(0, true);
if (is_inside_tree()) {
- base->set_custom_font(0, get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ base->set_custom_font(0, get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
}
base_map.insert(p_base_name, base);
return base;
@@ -374,7 +375,7 @@ void EditorPerformanceProfiler::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
for (KeyValue<StringName, TreeItem *> &E : base_map) {
- E.value->set_custom_font(0, get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ E.value->set_custom_font(0, get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
}
} break;
}
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index e59fc6186a..f72538e3de 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -33,6 +33,7 @@
#include "core/os/os.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/image_texture.h"
void EditorProfiler::_make_metric_ptrs(Metric &m) {
@@ -140,11 +141,11 @@ String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_ca
}
Color EditorProfiler::_get_color_from_signature(const StringName &p_signature) const {
- Color bc = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ Color bc = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
double rot = ABS(double(p_signature.hash()) / double(0x7FFFFFFF));
Color c;
c.set_hsv(rot, bc.get_s(), bc.get_v());
- return c.lerp(get_theme_color(SNAME("base_color"), SNAME("Editor")), 0.07);
+ return c.lerp(get_theme_color(SNAME("base_color"), EditorStringName(Editor)), 0.07);
}
void EditorProfiler::_item_edited() {
@@ -185,7 +186,7 @@ void EditorProfiler::_update_plot() {
}
uint8_t *wr = graph_image.ptrw();
- const Color background_color = get_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
+ const Color background_color = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor));
// Clear the previous frame and set the background color.
for (int i = 0; i < desired_len; i += 4) {
@@ -379,10 +380,10 @@ void EditorProfiler::_update_frame() {
void EditorProfiler::_update_button_text() {
if (activate->is_pressed()) {
- activate->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Stop")));
activate->set_text(TTR("Stop"));
} else {
- activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Play")));
activate->set_text(TTR("Start"));
}
}
@@ -409,8 +410,8 @@ void EditorProfiler::_notification(int p_what) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
- activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
- clear_button->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Play")));
+ clear_button->set_icon(get_editor_theme_icon(SNAME("Clear")));
} break;
}
}
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index 984d8e33c5..7df942e288 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -33,6 +33,7 @@
#include "core/os/os.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/image_texture.h"
void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) {
@@ -124,11 +125,11 @@ String EditorVisualProfiler::_get_time_as_text(float p_time) {
}
Color EditorVisualProfiler::_get_color_from_signature(const StringName &p_signature) const {
- Color bc = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ Color bc = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
double rot = ABS(double(p_signature.hash()) / double(0x7FFFFFFF));
Color c;
c.set_hsv(rot, bc.get_s(), bc.get_v());
- return c.lerp(get_theme_color(SNAME("base_color"), SNAME("Editor")), 0.07);
+ return c.lerp(get_theme_color(SNAME("base_color"), EditorStringName(Editor)), 0.07);
}
void EditorVisualProfiler::_item_selected() {
@@ -158,7 +159,7 @@ void EditorVisualProfiler::_update_plot() {
}
uint8_t *wr = graph_image.ptrw();
- const Color background_color = get_theme_color("dark_color_2", "Editor");
+ const Color background_color = get_theme_color("dark_color_2", EditorStringName(Editor));
// Clear the previous frame and set the background color.
for (int i = 0; i < desired_len; i += 4) {
@@ -318,7 +319,7 @@ void EditorVisualProfiler::_update_plot() {
void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
int cursor_metric = _get_cursor_index();
- Ref<Texture> track_icon = get_theme_icon(SNAME("TrackColor"), SNAME("EditorIcons"));
+ Ref<Texture> track_icon = get_editor_theme_icon(SNAME("TrackColor"));
ERR_FAIL_INDEX(cursor_metric, frame_metrics.size());
@@ -407,12 +408,12 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
void EditorVisualProfiler::_activate_pressed() {
if (activate->is_pressed()) {
- activate->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Stop")));
activate->set_text(TTR("Stop"));
_clear_pressed(); //always clear on start
clear_button->set_disabled(false);
} else {
- activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Play")));
activate->set_text(TTR("Start"));
}
emit_signal(SNAME("enable_profiling"), activate->is_pressed());
@@ -431,11 +432,11 @@ void EditorVisualProfiler::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
if (is_layout_rtl()) {
- activate->set_icon(get_theme_icon(SNAME("PlayBackwards"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("PlayBackwards")));
} else {
- activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Play")));
}
- clear_button->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
+ clear_button->set_icon(get_editor_theme_icon(SNAME("Clear")));
} break;
}
}
@@ -447,7 +448,7 @@ void EditorVisualProfiler::_graph_tex_draw() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- const Color color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ const Color color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
if (seeking) {
int max_frames = frame_metrics.size();
@@ -653,10 +654,10 @@ void EditorVisualProfiler::_bind_methods() {
void EditorVisualProfiler::_update_button_text() {
if (activate->is_pressed()) {
- activate->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Stop")));
activate->set_text(TTR("Stop"));
} else {
- activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ activate->set_icon(get_editor_theme_icon(SNAME("Play")));
activate->set_text(TTR("Start"));
}
}
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index ff59911159..c55942acef 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -46,6 +46,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/inspector_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -93,9 +94,9 @@ void ScriptEditorDebugger::debug_copy() {
void ScriptEditorDebugger::debug_skip_breakpoints() {
skip_breakpoints_value = !skip_breakpoints_value;
if (skip_breakpoints_value) {
- skip_breakpoints->set_icon(get_theme_icon(SNAME("DebugSkipBreakpointsOn"), SNAME("EditorIcons")));
+ skip_breakpoints->set_icon(get_editor_theme_icon(SNAME("DebugSkipBreakpointsOn")));
} else {
- skip_breakpoints->set_icon(get_theme_icon(SNAME("DebugSkipBreakpointsOff"), SNAME("EditorIcons")));
+ skip_breakpoints->set_icon(get_editor_theme_icon(SNAME("DebugSkipBreakpointsOff")));
}
Array msg;
@@ -143,11 +144,11 @@ void ScriptEditorDebugger::update_tabs() {
} else {
errors_tab->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")");
if (error_count >= 1 && warning_count >= 1) {
- tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons")));
+ tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_editor_theme_icon(SNAME("ErrorWarning")));
} else if (error_count >= 1) {
- tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_editor_theme_icon(SNAME("Error")));
} else {
- tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
+ tabs->set_tab_icon(tabs->get_tab_idx_from_control(errors_tab), get_editor_theme_icon(SNAME("Warning")));
}
}
}
@@ -420,8 +421,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, uint64_t p_thread
it->set_text(3, String::humanize_size(bytes));
total += bytes;
- if (has_theme_icon(type, SNAME("EditorIcons"))) {
- it->set_icon(0, get_theme_icon(type, SNAME("EditorIcons")));
+ if (has_theme_icon(type, EditorStringName(EditorIcons))) {
+ it->set_icon(0, get_editor_theme_icon(type));
}
}
@@ -560,11 +561,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, uint64_t p_thread
}
error->set_collapsed(true);
- error->set_icon(0, get_theme_icon(oe.warning ? SNAME("Warning") : SNAME("Error"), SNAME("EditorIcons")));
+ error->set_icon(0, get_editor_theme_icon(oe.warning ? SNAME("Warning") : SNAME("Error")));
error->set_text(0, time);
error->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
- const Color color = get_theme_color(oe.warning ? SNAME("warning_color") : SNAME("error_color"), SNAME("Editor"));
+ const Color color = get_theme_color(oe.warning ? SNAME("warning_color") : SNAME("error_color"), EditorStringName(Editor));
error->set_custom_color(0, color);
error->set_custom_color(1, color);
@@ -821,13 +822,13 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, uint64_t p_thread
void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType p_type) {
switch (p_type) {
case MESSAGE_ERROR:
- reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
break;
case MESSAGE_WARNING:
- reason->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ reason->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
break;
default:
- reason->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ reason->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
}
reason->set_text(p_reason);
@@ -853,32 +854,32 @@ void ScriptEditorDebugger::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- tabs->add_theme_style_override("panel", get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles")));
+ tabs->add_theme_style_override("panel", get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
- skip_breakpoints->set_icon(get_theme_icon(skip_breakpoints_value ? SNAME("DebugSkipBreakpointsOn") : SNAME("DebugSkipBreakpointsOff"), SNAME("EditorIcons")));
- copy->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
- step->set_icon(get_theme_icon(SNAME("DebugStep"), SNAME("EditorIcons")));
- next->set_icon(get_theme_icon(SNAME("DebugNext"), SNAME("EditorIcons")));
- dobreak->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
- docontinue->set_icon(get_theme_icon(SNAME("DebugContinue"), SNAME("EditorIcons")));
- vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
- vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
- search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ skip_breakpoints->set_icon(get_editor_theme_icon(skip_breakpoints_value ? SNAME("DebugSkipBreakpointsOn") : SNAME("DebugSkipBreakpointsOff")));
+ copy->set_icon(get_editor_theme_icon(SNAME("ActionCopy")));
+ step->set_icon(get_editor_theme_icon(SNAME("DebugStep")));
+ next->set_icon(get_editor_theme_icon(SNAME("DebugNext")));
+ dobreak->set_icon(get_editor_theme_icon(SNAME("Pause")));
+ docontinue->set_icon(get_editor_theme_icon(SNAME("DebugContinue")));
+ vmem_refresh->set_icon(get_editor_theme_icon(SNAME("Reload")));
+ vmem_export->set_icon(get_editor_theme_icon(SNAME("Save")));
+ search->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
TreeItem *error_root = error_tree->get_root();
if (error_root) {
TreeItem *error = error_root->get_first_child();
while (error) {
if (error->has_meta("_is_warning")) {
- error->set_icon(0, get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
- error->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- error->set_custom_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ error->set_icon(0, get_editor_theme_icon(SNAME("Warning")));
+ error->set_custom_color(0, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ error->set_custom_color(1, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} else if (error->has_meta("_is_error")) {
- error->set_icon(0, get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
- error->set_custom_color(0, get_theme_color(SNAME("error_color"), SNAME("Editor")));
- error->set_custom_color(1, get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error->set_icon(0, get_editor_theme_icon(SNAME("Error")));
+ error->set_custom_color(0, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ error->set_custom_color(1, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
}
error = error->get_next();
@@ -1598,11 +1599,11 @@ void ScriptEditorDebugger::_breakpoints_item_rmb_selected(const Vector2 &p_pos,
const TreeItem *selected = breakpoints_tree->get_selected();
String file = selected->get_text(0);
if (selected->has_meta("line")) {
- breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Breakpoint"), ACTION_DELETE_BREAKPOINT);
+ breakpoints_menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Breakpoint"), ACTION_DELETE_BREAKPOINT);
file = selected->get_parent()->get_text(0);
}
- breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints in:") + " " + file, ACTION_DELETE_BREAKPOINTS_IN_FILE);
- breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints"), ACTION_DELETE_ALL_BREAKPOINTS);
+ breakpoints_menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete All Breakpoints in:") + " " + file, ACTION_DELETE_BREAKPOINTS_IN_FILE);
+ breakpoints_menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete All Breakpoints"), ACTION_DELETE_ALL_BREAKPOINTS);
breakpoints_menu->set_position(breakpoints_tree->get_global_position() + p_pos);
breakpoints_menu->popup();
@@ -1618,8 +1619,8 @@ void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos, M
item_menu->reset_size();
if (error_tree->is_anything_selected()) {
- item_menu->add_icon_item(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), TTR("Copy Error"), ACTION_COPY_ERROR);
- item_menu->add_icon_item(get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), TTR("Open C++ Source on GitHub"), ACTION_OPEN_SOURCE);
+ item_menu->add_icon_item(get_editor_theme_icon(SNAME("ActionCopy")), TTR("Copy Error"), ACTION_COPY_ERROR);
+ item_menu->add_icon_item(get_editor_theme_icon(SNAME("ExternalLink")), TTR("Open C++ Source on GitHub"), ACTION_OPEN_SOURCE);
}
if (item_menu->get_item_count() > 0) {
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index 7e9a767273..79224061ff 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -31,6 +31,7 @@
#ifndef SCRIPT_EDITOR_DEBUGGER_H
#define SCRIPT_EDITOR_DEBUGGER_H
+#include "core/object/script_language.h"
#include "core/os/os.h"
#include "editor/debugger/editor_debugger_inspector.h"
#include "editor/debugger/editor_debugger_node.h"
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 3660e7f285..26779f5b52 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -304,9 +304,9 @@ void DependencyEditorOwners::_list_rmb_clicked(int p_item, const Vector2 &p_pos,
}
if (only_scenes_selected) {
- file_options->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTRN("Open Scene", "Open Scenes", selected_items.size()), FILE_OPEN);
+ file_options->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTRN("Open Scene", "Open Scenes", selected_items.size()), FILE_OPEN);
} else if (selected_items.size() == 1) {
- file_options->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open"), FILE_OPEN);
+ file_options->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open"), FILE_OPEN);
} else {
return;
}
@@ -508,17 +508,17 @@ void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<Removed
if (!tree_items.has(rd.dependency_folder)) {
TreeItem *folder_item = owners->create_item(owners->get_root());
folder_item->set_text(0, rd.dependency_folder);
- folder_item->set_icon(0, owners->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ folder_item->set_icon(0, owners->get_editor_theme_icon(SNAME("Folder")));
tree_items[rd.dependency_folder] = folder_item;
}
TreeItem *dependency_item = owners->create_item(tree_items[rd.dependency_folder]);
dependency_item->set_text(0, rd.dependency);
- dependency_item->set_icon(0, owners->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
+ dependency_item->set_icon(0, owners->get_editor_theme_icon(SNAME("Warning")));
tree_items[rd.dependency] = dependency_item;
} else {
TreeItem *dependency_item = owners->create_item(owners->get_root());
dependency_item->set_text(0, rd.dependency);
- dependency_item->set_icon(0, owners->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
+ dependency_item->set_icon(0, owners->get_editor_theme_icon(SNAME("Warning")));
tree_items[rd.dependency] = dependency_item;
}
}
@@ -804,7 +804,7 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa
int ds = efsd->get_file_deps(i).size();
ti->set_text(1, itos(ds));
if (ds) {
- ti->add_button(1, files->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")), -1, false, TTR("Show Dependencies"));
+ ti->add_button(1, files->get_editor_theme_icon(SNAME("GuiVisibilityVisible")), -1, false, TTR("Show Dependencies"));
}
ti->set_metadata(0, path);
has_children = true;
diff --git a/editor/directory_create_dialog.cpp b/editor/directory_create_dialog.cpp
index fed7cb82c9..0efd11a6c1 100644
--- a/editor/directory_create_dialog.cpp
+++ b/editor/directory_create_dialog.cpp
@@ -51,13 +51,20 @@ String DirectoryCreateDialog::_validate_path(const String &p_path) const {
return TTR("Folder name cannot be empty.");
}
+ if (p_path.contains("\\") || p_path.contains(":") || p_path.contains("*") ||
+ p_path.contains("|") || p_path.contains(">")) {
+ return TTR("Folder name contains invalid characters.");
+ }
+
for (const String &part : p_path.split("/")) {
if (part.is_empty()) {
return TTR("Folder name cannot be empty.");
}
- if (p_path.contains("\\") || p_path.contains(":") || p_path.contains("*") ||
- p_path.contains("|") || p_path.contains(">") || p_path.ends_with(".") || p_path.ends_with(" ")) {
- return TTR("Folder name contains invalid characters.");
+ if (part.ends_with(" ") || part[0] == ' ') {
+ return TTR("Folder name cannot begin or end with a space.");
+ }
+ if (part[0] == '.') {
+ return TTR("Folder name cannot begin with a dot.");
}
}
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index a4147acade..848510f9c3 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -34,20 +34,21 @@
#include "core/donors.gen.h"
#include "core/license.gen.h"
#include "core/version.h"
+#include "editor/editor_string_names.h"
// The metadata key used to store and retrieve the version text to copy to the clipboard.
const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";
void EditorAbout::_theme_changed() {
- const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts"));
- const int font_size = get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"));
+ const Ref<Font> font = get_theme_font(SNAME("source"), EditorStringName(EditorFonts));
+ const int font_size = get_theme_font_size(SNAME("source_size"), EditorStringName(EditorFonts));
_tpl_text->add_theme_font_override("normal_font", font);
_tpl_text->add_theme_font_size_override("normal_font_size", font_size);
_tpl_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_license_text->add_theme_font_override("normal_font", font);
_license_text->add_theme_font_size_override("normal_font_size", font_size);
_license_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
- _logo->set_texture(get_theme_icon(SNAME("Logo"), SNAME("EditorIcons")));
+ _logo->set_texture(get_editor_theme_icon(SNAME("Logo")));
}
void EditorAbout::_notification(int p_what) {
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index a5bc90159a..27833ea499 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -35,6 +35,7 @@
#include "core/io/zip_io.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/progress_dialog.h"
void EditorAssetInstaller::_item_edited() {
@@ -89,56 +90,56 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
HashMap<String, Ref<Texture2D>> extension_guess;
{
- extension_guess["bmp"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["dds"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["exr"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["hdr"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["jpg"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["jpeg"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["png"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["svg"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["tga"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
- extension_guess["webp"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons"));
-
- extension_guess["wav"] = tree->get_theme_icon(SNAME("AudioStreamWAV"), SNAME("EditorIcons"));
- extension_guess["ogg"] = tree->get_theme_icon(SNAME("AudioStreamOggVorbis"), SNAME("EditorIcons"));
- extension_guess["mp3"] = tree->get_theme_icon(SNAME("AudioStreamMP3"), SNAME("EditorIcons"));
-
- extension_guess["scn"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
- extension_guess["tscn"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
- extension_guess["escn"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
- extension_guess["dae"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
- extension_guess["gltf"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
- extension_guess["glb"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
-
- extension_guess["gdshader"] = tree->get_theme_icon(SNAME("Shader"), SNAME("EditorIcons"));
- extension_guess["gdshaderinc"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["gd"] = tree->get_theme_icon(SNAME("GDScript"), SNAME("EditorIcons"));
+ extension_guess["bmp"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["dds"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["exr"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["hdr"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["jpg"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["jpeg"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["png"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["svg"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["tga"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+ extension_guess["webp"] = tree->get_editor_theme_icon(SNAME("ImageTexture"));
+
+ extension_guess["wav"] = tree->get_editor_theme_icon(SNAME("AudioStreamWAV"));
+ extension_guess["ogg"] = tree->get_editor_theme_icon(SNAME("AudioStreamOggVorbis"));
+ extension_guess["mp3"] = tree->get_editor_theme_icon(SNAME("AudioStreamMP3"));
+
+ extension_guess["scn"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+ extension_guess["tscn"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+ extension_guess["escn"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+ extension_guess["dae"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+ extension_guess["gltf"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+ extension_guess["glb"] = tree->get_editor_theme_icon(SNAME("PackedScene"));
+
+ extension_guess["gdshader"] = tree->get_editor_theme_icon(SNAME("Shader"));
+ extension_guess["gdshaderinc"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["gd"] = tree->get_editor_theme_icon(SNAME("GDScript"));
if (Engine::get_singleton()->has_singleton("GodotSharp")) {
- extension_guess["cs"] = tree->get_theme_icon(SNAME("CSharpScript"), SNAME("EditorIcons"));
+ extension_guess["cs"] = tree->get_editor_theme_icon(SNAME("CSharpScript"));
} else {
// Mark C# support as unavailable.
- extension_guess["cs"] = tree->get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ extension_guess["cs"] = tree->get_editor_theme_icon(SNAME("ImportFail"));
}
- extension_guess["res"] = tree->get_theme_icon(SNAME("Resource"), SNAME("EditorIcons"));
- extension_guess["tres"] = tree->get_theme_icon(SNAME("Resource"), SNAME("EditorIcons"));
- extension_guess["atlastex"] = tree->get_theme_icon(SNAME("AtlasTexture"), SNAME("EditorIcons"));
+ extension_guess["res"] = tree->get_editor_theme_icon(SNAME("Resource"));
+ extension_guess["tres"] = tree->get_editor_theme_icon(SNAME("Resource"));
+ extension_guess["atlastex"] = tree->get_editor_theme_icon(SNAME("AtlasTexture"));
// By default, OBJ files are imported as Mesh resources rather than PackedScenes.
- extension_guess["obj"] = tree->get_theme_icon(SNAME("Mesh"), SNAME("EditorIcons"));
-
- extension_guess["txt"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["md"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["rst"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["json"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["yml"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["yaml"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["toml"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["cfg"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
- extension_guess["ini"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
+ extension_guess["obj"] = tree->get_editor_theme_icon(SNAME("Mesh"));
+
+ extension_guess["txt"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["md"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["rst"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["json"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["yml"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["yaml"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["toml"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["cfg"] = tree->get_editor_theme_icon(SNAME("TextFile"));
+ extension_guess["ini"] = tree->get_editor_theme_icon(SNAME("TextFile"));
}
- Ref<Texture2D> generic_extension = tree->get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
+ Ref<Texture2D> generic_extension = tree->get_editor_theme_icon(SNAME("Object"));
unzClose(pkg);
@@ -213,7 +214,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
String res_path = "res://" + path;
if (FileAccess::exists(res_path)) {
num_file_conflicts += 1;
- ti->set_custom_color(0, tree->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ ti->set_custom_color(0, tree->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
ti->set_tooltip_text(0, vformat(TTR("%s (already exists)"), res_path));
ti->set_checked(0, false);
ti->propagate_check(0);
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 93788dc8b1..8b60ac405a 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
@@ -69,7 +70,7 @@ void EditorAudioBus::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- Ref<Texture2D> active_bus_texture = get_theme_icon(SNAME("BusVuActive"), SNAME("EditorIcons"));
+ Ref<Texture2D> active_bus_texture = get_editor_theme_icon(SNAME("BusVuActive"));
for (int i = 0; i < CHANNELS_MAX; i++) {
channel[i].vu_l->set_under_texture(active_bus_texture);
channel[i].vu_l->set_tint_under(Color(0.75, 0.75, 0.75));
@@ -81,20 +82,20 @@ void EditorAudioBus::_notification(int p_what) {
channel[i].prev_active = true;
}
- disabled_vu = get_theme_icon(SNAME("BusVuFrozen"), SNAME("EditorIcons"));
+ disabled_vu = get_editor_theme_icon(SNAME("BusVuFrozen"));
Color solo_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.89, 0.22) : Color(1.0, 0.92, 0.44);
Color mute_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.16, 0.16) : Color(1.0, 0.44, 0.44);
Color bypass_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(0.44, 0.87, 1.0);
- solo->set_icon(get_theme_icon(SNAME("AudioBusSolo"), SNAME("EditorIcons")));
+ solo->set_icon(get_editor_theme_icon(SNAME("AudioBusSolo")));
solo->add_theme_color_override("icon_pressed_color", solo_color);
- mute->set_icon(get_theme_icon(SNAME("AudioBusMute"), SNAME("EditorIcons")));
+ mute->set_icon(get_editor_theme_icon(SNAME("AudioBusMute")));
mute->add_theme_color_override("icon_pressed_color", mute_color);
- bypass->set_icon(get_theme_icon(SNAME("AudioBusBypass"), SNAME("EditorIcons")));
+ bypass->set_icon(get_editor_theme_icon(SNAME("AudioBusBypass")));
bypass->add_theme_color_override("icon_pressed_color", bypass_color);
- bus_options->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ bus_options->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
audio_value_preview_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("TooltipLabel")));
audio_value_preview_label->add_theme_color_override("font_shadow_color", get_theme_color(SNAME("font_shadow_color"), SNAME("TooltipLabel")));
@@ -122,7 +123,7 @@ void EditorAudioBus::_notification(int p_what) {
}
if (get_index() != 0 && hovering_drop) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
accent.a *= 0.7;
draw_rect(Rect2(Point2(), get_size()), accent, false);
}
@@ -970,7 +971,7 @@ void EditorAudioBusDrop::_notification(int p_what) {
draw_style_box(get_theme_stylebox(SNAME("normal"), SNAME("Button")), Rect2(Vector2(), get_size()));
if (hovering_drop) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
accent.a *= 0.7;
draw_rect(Rect2(Point2(), get_size()), accent, false);
}
@@ -1443,7 +1444,7 @@ Size2 EditorAudioMeterNotches::get_minimum_size() const {
void EditorAudioMeterNotches::_update_theme_item_cache() {
Control::_update_theme_item_cache();
- theme_cache.notch_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ theme_cache.notch_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
theme_cache.font = get_theme_font(SNAME("font"), SNAME("Label"));
theme_cache.font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 5bcef467f6..57172142e3 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -34,6 +34,7 @@
#include "core/core_constants.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
@@ -59,11 +60,11 @@ void EditorAutoloadSettings::_notification(int p_what) {
get_tree()->get_root()->call_deferred(SNAME("add_child"), info.node);
}
}
- browse_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ browse_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
case NOTIFICATION_THEME_CHANGED: {
- browse_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ browse_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -517,10 +518,10 @@ void EditorAutoloadSettings::update_autoload() {
item->set_editable(2, true);
item->set_text(2, TTR("Enable"));
item->set_checked(2, info.is_singleton);
- item->add_button(3, get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), BUTTON_OPEN);
- item->add_button(3, get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")), BUTTON_MOVE_UP);
- item->add_button(3, get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")), BUTTON_MOVE_DOWN);
- item->add_button(3, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_DELETE);
+ item->add_button(3, get_editor_theme_icon(SNAME("Load")), BUTTON_OPEN);
+ item->add_button(3, get_editor_theme_icon(SNAME("MoveUp")), BUTTON_MOVE_UP);
+ item->add_button(3, get_editor_theme_icon(SNAME("MoveDown")), BUTTON_MOVE_DOWN);
+ item->add_button(3, get_editor_theme_icon(SNAME("Remove")), BUTTON_DELETE);
item->set_selectable(3, false);
}
@@ -881,7 +882,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
error_message = memnew(Label);
error_message->hide();
error_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
- error_message->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_message->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
add_child(error_message);
Label *l = memnew(Label);
diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp
index 1377537245..bca30b2d2d 100644
--- a/editor/editor_build_profile.cpp
+++ b/editor/editor_build_profile.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = {
@@ -600,7 +601,7 @@ void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const Str
bool disabled = edited->is_class_disabled(p_class);
if (disabled) {
- class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
}
class_item->set_text(0, text);
diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp
index b44792bf0f..168fe5a7ac 100644
--- a/editor/editor_command_palette.cpp
+++ b/editor/editor_command_palette.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/control.h"
#include "scene/gui/tree.h"
@@ -127,8 +128,8 @@ void EditorCommandPalette::_update_command_search(const String &search_text) {
section->set_text(0, item_name);
section->set_selectable(0, false);
section->set_selectable(1, false);
- section->set_custom_bg_color(0, search_options->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
- section->set_custom_bg_color(1, search_options->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ section->set_custom_bg_color(0, search_options->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
+ section->set_custom_bg_color(1, search_options->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
sections[section_name] = section;
}
@@ -139,7 +140,7 @@ void EditorCommandPalette::_update_command_search(const String &search_text) {
ti->set_metadata(0, entries[i].key_name);
ti->set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT);
ti->set_text(1, shortcut_text);
- Color c = get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5);
+ Color c = get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5);
ti->set_custom_color(1, c);
}
@@ -294,7 +295,7 @@ Ref<Shortcut> EditorCommandPalette::add_shortcut_command(const String &p_command
}
void EditorCommandPalette::_theme_changed() {
- command_search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ command_search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
}
void EditorCommandPalette::_save_history() const {
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index 6019e9e895..50406bea6a 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = {
@@ -502,7 +503,7 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S
bool disabled_editor = edited->is_class_editor_disabled(p_class);
bool disabled_properties = edited->has_class_properties_disabled(p_class);
if (disabled) {
- class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
} else if (disabled_editor && disabled_properties) {
text += " " + TTR("(Editor Disabled, Properties Disabled)");
} else if (disabled_properties) {
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index bc8bcb1134..6c51be8361 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -34,6 +34,7 @@
#include "core/io/dir_access.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/font.h"
Ref<FontFile> load_external_font(const String &p_path, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
@@ -157,11 +158,11 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<FontFile> georgian_font = load_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> hebrew_font = load_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> malayalam_font = load_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
- Ref<FontFile> oriya_font = load_internal_font(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> oriya_font = load_internal_font(_font_NotoSansOriya_Regular, _font_NotoSansOriya_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> sinhala_font = load_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> tamil_font = load_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> telugu_font = load_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
- Ref<FontFile> thai_font = load_internal_font(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> thai_font = load_internal_font(_font_NotoSansThai_Regular, _font_NotoSansThai_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> fallback_font = load_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
Ref<FontFile> japanese_font = load_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks);
default_font->set_fallbacks(fallbacks);
@@ -177,11 +178,11 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<FontFile> georgian_font_bold = load_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontFile> hebrew_font_bold = load_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontFile> malayalam_font_bold = load_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
- Ref<FontFile> oriya_font_bold = load_internal_font(_font_NotoSansOriyaUI_Bold, _font_NotoSansOriyaUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> oriya_font_bold = load_internal_font(_font_NotoSansOriya_Bold, _font_NotoSansOriya_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontFile> sinhala_font_bold = load_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontFile> tamil_font_bold = load_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontFile> telugu_font_bold = load_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
- Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThai_Bold, _font_NotoSansThai_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontVariation> fallback_font_bold = make_bold_font(fallback_font, embolden_strength, &fallbacks_bold);
Ref<FontVariation> japanese_font_bold = make_bold_font(japanese_font, embolden_strength, &fallbacks_bold);
@@ -377,21 +378,21 @@ void editor_register_fonts(Ref<Theme> p_theme) {
// Main font.
- p_theme->set_font("main", "EditorFonts", default_fc);
- p_theme->set_font("main_msdf", "EditorFonts", default_fc_msdf);
- p_theme->set_font_size("main_size", "EditorFonts", default_font_size);
+ p_theme->set_font("main", EditorStringName(EditorFonts), default_fc);
+ p_theme->set_font("main_msdf", EditorStringName(EditorFonts), default_fc_msdf);
+ p_theme->set_font_size("main_size", EditorStringName(EditorFonts), default_font_size);
- p_theme->set_font("bold", "EditorFonts", bold_fc);
- p_theme->set_font("main_bold_msdf", "EditorFonts", bold_fc_msdf);
- p_theme->set_font_size("bold_size", "EditorFonts", default_font_size);
+ p_theme->set_font("bold", EditorStringName(EditorFonts), bold_fc);
+ p_theme->set_font("main_bold_msdf", EditorStringName(EditorFonts), bold_fc_msdf);
+ p_theme->set_font_size("bold_size", EditorStringName(EditorFonts), default_font_size);
// Title font.
- p_theme->set_font("title", "EditorFonts", bold_fc);
- p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 1 * EDSCALE);
+ p_theme->set_font("title", EditorStringName(EditorFonts), bold_fc);
+ p_theme->set_font_size("title_size", EditorStringName(EditorFonts), default_font_size + 1 * EDSCALE);
- p_theme->set_font("main_button_font", "EditorFonts", bold_fc);
- p_theme->set_font_size("main_button_font_size", "EditorFonts", default_font_size + 1 * EDSCALE);
+ p_theme->set_font("main_button_font", EditorStringName(EditorFonts), bold_fc);
+ p_theme->set_font_size("main_button_font_size", EditorStringName(EditorFonts), default_font_size + 1 * EDSCALE);
p_theme->set_font("font", "Label", default_fc);
@@ -408,41 +409,41 @@ void editor_register_fonts(Ref<Theme> p_theme) {
p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE);
// Documentation fonts
- p_theme->set_font_size("doc_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
- p_theme->set_font("doc", "EditorFonts", default_fc);
- p_theme->set_font("doc_bold", "EditorFonts", bold_fc);
- p_theme->set_font("doc_italic", "EditorFonts", italic_fc);
- p_theme->set_font_size("doc_title_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE);
- p_theme->set_font("doc_title", "EditorFonts", bold_fc);
- p_theme->set_font_size("doc_source_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE);
- p_theme->set_font("doc_source", "EditorFonts", mono_fc);
- p_theme->set_font_size("doc_keyboard_size", "EditorFonts", (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE);
- p_theme->set_font("doc_keyboard", "EditorFonts", mono_fc);
+ p_theme->set_font_size("doc_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
+ p_theme->set_font("doc", EditorStringName(EditorFonts), default_fc);
+ p_theme->set_font("doc_bold", EditorStringName(EditorFonts), bold_fc);
+ p_theme->set_font("doc_italic", EditorStringName(EditorFonts), italic_fc);
+ p_theme->set_font_size("doc_title_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE);
+ p_theme->set_font("doc_title", EditorStringName(EditorFonts), bold_fc);
+ p_theme->set_font_size("doc_source_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE);
+ p_theme->set_font("doc_source", EditorStringName(EditorFonts), mono_fc);
+ p_theme->set_font_size("doc_keyboard_size", EditorStringName(EditorFonts), (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE);
+ p_theme->set_font("doc_keyboard", EditorStringName(EditorFonts), mono_fc);
// Ruler font
- p_theme->set_font_size("rulers_size", "EditorFonts", 8 * EDSCALE);
- p_theme->set_font("rulers", "EditorFonts", default_fc);
+ p_theme->set_font_size("rulers_size", EditorStringName(EditorFonts), 8 * EDSCALE);
+ p_theme->set_font("rulers", EditorStringName(EditorFonts), default_fc);
// Rotation widget font
- p_theme->set_font_size("rotation_control_size", "EditorFonts", 14 * EDSCALE);
- p_theme->set_font("rotation_control", "EditorFonts", default_fc);
+ p_theme->set_font_size("rotation_control_size", EditorStringName(EditorFonts), 14 * EDSCALE);
+ p_theme->set_font("rotation_control", EditorStringName(EditorFonts), default_fc);
// Code font
- p_theme->set_font_size("source_size", "EditorFonts", int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE);
- p_theme->set_font("source", "EditorFonts", mono_fc);
+ p_theme->set_font_size("source_size", EditorStringName(EditorFonts), int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE);
+ p_theme->set_font("source", EditorStringName(EditorFonts), mono_fc);
- p_theme->set_font_size("expression_size", "EditorFonts", (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE);
- p_theme->set_font("expression", "EditorFonts", mono_other_fc);
+ p_theme->set_font_size("expression_size", EditorStringName(EditorFonts), (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE);
+ p_theme->set_font("expression", EditorStringName(EditorFonts), mono_other_fc);
- p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE);
- p_theme->set_font("output_source", "EditorFonts", mono_other_fc);
- p_theme->set_font("output_source_bold", "EditorFonts", mono_other_fc_bold);
- p_theme->set_font("output_source_italic", "EditorFonts", mono_other_fc_italic);
- p_theme->set_font("output_source_bold_italic", "EditorFonts", mono_other_fc_bold_italic);
- p_theme->set_font("output_source_mono", "EditorFonts", mono_other_fc_mono);
+ p_theme->set_font_size("output_source_size", EditorStringName(EditorFonts), int(EDITOR_GET("run/output/font_size")) * EDSCALE);
+ p_theme->set_font("output_source", EditorStringName(EditorFonts), mono_other_fc);
+ p_theme->set_font("output_source_bold", EditorStringName(EditorFonts), mono_other_fc_bold);
+ p_theme->set_font("output_source_italic", EditorStringName(EditorFonts), mono_other_fc_italic);
+ p_theme->set_font("output_source_bold_italic", EditorStringName(EditorFonts), mono_other_fc_bold_italic);
+ p_theme->set_font("output_source_mono", EditorStringName(EditorFonts), mono_other_fc_mono);
- p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size);
- p_theme->set_font("status_source", "EditorFonts", mono_other_fc);
+ p_theme->set_font_size("status_source_size", EditorStringName(EditorFonts), default_font_size);
+ p_theme->set_font("status_source", EditorStringName(EditorFonts), mono_other_fc);
OS::get_singleton()->benchmark_end_measure("editor_register_fonts");
}
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 14d80334b3..e35b305837 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/script_editor_plugin.h"
#include "scene/gui/line_edit.h"
@@ -143,17 +144,17 @@ void EditorHelp::_update_theme_item_cache() {
theme_cache.qualifier_color = get_theme_color(SNAME("qualifier_color"), SNAME("EditorHelp"));
theme_cache.type_color = get_theme_color(SNAME("type_color"), SNAME("EditorHelp"));
- theme_cache.doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts"));
- theme_cache.doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"));
- theme_cache.doc_italic_font = get_theme_font(SNAME("doc_italic"), SNAME("EditorFonts"));
- theme_cache.doc_title_font = get_theme_font(SNAME("doc_title"), SNAME("EditorFonts"));
- theme_cache.doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
- theme_cache.doc_kbd_font = get_theme_font(SNAME("doc_keyboard"), SNAME("EditorFonts"));
+ theme_cache.doc_font = get_theme_font(SNAME("doc"), EditorStringName(EditorFonts));
+ theme_cache.doc_bold_font = get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts));
+ theme_cache.doc_italic_font = get_theme_font(SNAME("doc_italic"), EditorStringName(EditorFonts));
+ theme_cache.doc_title_font = get_theme_font(SNAME("doc_title"), EditorStringName(EditorFonts));
+ theme_cache.doc_code_font = get_theme_font(SNAME("doc_source"), EditorStringName(EditorFonts));
+ theme_cache.doc_kbd_font = get_theme_font(SNAME("doc_keyboard"), EditorStringName(EditorFonts));
- theme_cache.doc_font_size = get_theme_font_size(SNAME("doc_size"), SNAME("EditorFonts"));
- theme_cache.doc_title_font_size = get_theme_font_size(SNAME("doc_title_size"), SNAME("EditorFonts"));
- theme_cache.doc_code_font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts"));
- theme_cache.doc_kbd_font_size = get_theme_font_size(SNAME("doc_keyboard_size"), SNAME("EditorFonts"));
+ theme_cache.doc_font_size = get_theme_font_size(SNAME("doc_size"), EditorStringName(EditorFonts));
+ theme_cache.doc_title_font_size = get_theme_font_size(SNAME("doc_title_size"), EditorStringName(EditorFonts));
+ theme_cache.doc_code_font_size = get_theme_font_size(SNAME("doc_source_size"), EditorStringName(EditorFonts));
+ theme_cache.doc_kbd_font_size = get_theme_font_size(SNAME("doc_keyboard_size"), EditorStringName(EditorFonts));
theme_cache.background_style = get_theme_stylebox(SNAME("background"), SNAME("EditorHelp"));
@@ -393,17 +394,17 @@ String EditorHelp::_fix_constant(const String &p_constant) const {
}
// Macros for assigning the deprecation/experimental information to class members
-#define DEPRECATED_DOC_TAG \
- class_desc->push_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); \
- Ref<Texture2D> error_icon = get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")); \
- class_desc->add_text(" "); \
- class_desc->add_image(error_icon, error_icon->get_width(), error_icon->get_height()); \
- class_desc->add_text(" (" + TTR("Deprecated") + ")"); \
+#define DEPRECATED_DOC_TAG \
+ class_desc->push_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor))); \
+ Ref<Texture2D> error_icon = get_editor_theme_icon(SNAME("StatusError")); \
+ class_desc->add_text(" "); \
+ class_desc->add_image(error_icon, error_icon->get_width(), error_icon->get_height()); \
+ class_desc->add_text(" (" + TTR("Deprecated") + ")"); \
class_desc->pop();
#define EXPERIMENTAL_DOC_TAG \
- class_desc->push_color(get_theme_color(SNAME("warning_color"), SNAME("Editor"))); \
- Ref<Texture2D> warning_icon = get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")); \
+ class_desc->push_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); \
+ Ref<Texture2D> warning_icon = get_editor_theme_icon(SNAME("NodeWarning")); \
class_desc->add_text(" "); \
class_desc->add_image(warning_icon, warning_icon->get_width(), warning_icon->get_height()); \
class_desc->add_text(" (" + TTR("Experimental") + ")"); \
@@ -641,7 +642,7 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods)
class_desc->add_newline();
}
-void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, const String &p_method_type) {
+void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, MethodType p_method_type) {
String link_color_text = theme_cache.title_color.to_html(false);
class_desc->add_newline();
@@ -696,14 +697,27 @@ void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc,
if (!methods_filtered[i].description.strip_edges().is_empty()) {
_add_text(DTR(methods_filtered[i].description));
} else {
- class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ class_desc->add_image(get_editor_theme_icon(SNAME("Error")));
class_desc->add_text(" ");
class_desc->push_color(theme_cache.comment_color);
+
+ String message;
if (p_classdoc.is_script_doc) {
- class_desc->append_text(vformat(TTR("There is currently no description for this %s."), p_method_type));
+ static const char *messages_by_type[METHOD_TYPE_MAX] = {
+ TTRC("There is currently no description for this method."),
+ TTRC("There is currently no description for this constructor."),
+ TTRC("There is currently no description for this operator."),
+ };
+ message = TTRGET(messages_by_type[p_method_type]);
} else {
- class_desc->append_text(vformat(TTR("There is currently no description for this %s. Please help us by [color=$color][url=$url]contributing one[/url][/color]!"), p_method_type).replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text));
+ static const char *messages_by_type[METHOD_TYPE_MAX] = {
+ TTRC("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!"),
+ TTRC("There is currently no description for this constructor. Please help us by [color=$color][url=$url]contributing one[/url][/color]!"),
+ TTRC("There is currently no description for this operator. Please help us by [color=$color][url=$url]contributing one[/url][/color]!"),
+ };
+ message = TTRGET(messages_by_type[p_method_type]).replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text);
}
+ class_desc->append_text(message);
class_desc->pop();
}
@@ -746,12 +760,12 @@ void EditorHelp::_update_doc() {
if (cd.is_deprecated) {
class_desc->add_text(" ");
- Ref<Texture2D> error_icon = get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"));
+ Ref<Texture2D> error_icon = get_editor_theme_icon(SNAME("StatusError"));
class_desc->add_image(error_icon, error_icon->get_width(), error_icon->get_height());
}
if (cd.is_experimental) {
class_desc->add_text(" ");
- Ref<Texture2D> warning_icon = get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"));
+ Ref<Texture2D> warning_icon = get_editor_theme_icon(SNAME("NodeWarning"));
class_desc->add_image(warning_icon, warning_icon->get_width(), warning_icon->get_height());
}
class_desc->add_newline();
@@ -818,8 +832,8 @@ void EditorHelp::_update_doc() {
// Note if deprecated.
if (cd.is_deprecated) {
- Ref<Texture2D> error_icon = get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"));
- class_desc->push_color(get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ Ref<Texture2D> error_icon = get_editor_theme_icon(SNAME("StatusError"));
+ class_desc->push_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
class_desc->add_image(error_icon, error_icon->get_width(), error_icon->get_height());
class_desc->add_text(String(" ") + TTR("This class is marked as deprecated. It will be removed in future versions."));
class_desc->pop();
@@ -828,8 +842,8 @@ void EditorHelp::_update_doc() {
// Note if experimental.
if (cd.is_experimental) {
- Ref<Texture2D> warning_icon = get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"));
- class_desc->push_color(get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ Ref<Texture2D> warning_icon = get_editor_theme_icon(SNAME("NodeWarning"));
+ class_desc->push_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
class_desc->add_image(warning_icon, warning_icon->get_width(), warning_icon->get_height());
class_desc->add_text(String(" ") + TTR("This class is marked as experimental. It is subject to likely change or possible removal in future versions. Use at your own discretion."));
class_desc->pop();
@@ -884,7 +898,7 @@ void EditorHelp::_update_doc() {
}
if (!has_description) {
- class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ class_desc->add_image(get_editor_theme_icon(SNAME("Error")));
class_desc->add_text(" ");
class_desc->push_color(theme_cache.comment_color);
@@ -1633,7 +1647,7 @@ void EditorHelp::_update_doc() {
class_desc->pop(); // color
} else {
class_desc->push_indent(1);
- class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ class_desc->add_image(get_editor_theme_icon(SNAME("Error")));
class_desc->add_text(" ");
class_desc->push_color(theme_cache.comment_color);
if (cd.is_script_doc) {
@@ -1815,7 +1829,7 @@ void EditorHelp::_update_doc() {
if (!cd.properties[i].description.strip_edges().is_empty()) {
_add_text(DTR(cd.properties[i].description));
} else {
- class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ class_desc->add_image(get_editor_theme_icon(SNAME("Error")));
class_desc->add_text(" ");
class_desc->push_color(theme_cache.comment_color);
if (cd.is_script_doc) {
@@ -1842,7 +1856,7 @@ void EditorHelp::_update_doc() {
class_desc->add_text(TTR("Constructor Descriptions"));
_pop_title_font();
- _update_method_descriptions(cd, cd.constructors, "constructor");
+ _update_method_descriptions(cd, cd.constructors, METHOD_TYPE_CONSTRUCTOR);
}
// Method descriptions
@@ -1852,7 +1866,7 @@ void EditorHelp::_update_doc() {
class_desc->add_text(TTR("Method Descriptions"));
_pop_title_font();
- _update_method_descriptions(cd, methods, "method");
+ _update_method_descriptions(cd, methods, METHOD_TYPE_METHOD);
}
// Operator descriptions
@@ -1862,7 +1876,7 @@ void EditorHelp::_update_doc() {
class_desc->add_text(TTR("Operator Descriptions"));
_pop_title_font();
- _update_method_descriptions(cd, cd.operators, "operator");
+ _update_method_descriptions(cd, cd.operators, METHOD_TYPE_OPERATOR);
}
// Free the scroll.
@@ -1949,14 +1963,14 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control
DocTools *doc = EditorHelp::get_doc_data();
String base_path;
- Ref<Font> doc_font = p_owner_node->get_theme_font(SNAME("doc"), SNAME("EditorFonts"));
- Ref<Font> doc_bold_font = p_owner_node->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"));
- Ref<Font> doc_italic_font = p_owner_node->get_theme_font(SNAME("doc_italic"), SNAME("EditorFonts"));
- Ref<Font> doc_code_font = p_owner_node->get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
- Ref<Font> doc_kbd_font = p_owner_node->get_theme_font(SNAME("doc_keyboard"), SNAME("EditorFonts"));
+ Ref<Font> doc_font = p_owner_node->get_theme_font(SNAME("doc"), EditorStringName(EditorFonts));
+ Ref<Font> doc_bold_font = p_owner_node->get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts));
+ Ref<Font> doc_italic_font = p_owner_node->get_theme_font(SNAME("doc_italic"), EditorStringName(EditorFonts));
+ Ref<Font> doc_code_font = p_owner_node->get_theme_font(SNAME("doc_source"), EditorStringName(EditorFonts));
+ Ref<Font> doc_kbd_font = p_owner_node->get_theme_font(SNAME("doc_keyboard"), EditorStringName(EditorFonts));
- int doc_code_font_size = p_owner_node->get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts"));
- int doc_kbd_font_size = p_owner_node->get_theme_font_size(SNAME("doc_keyboard_size"), SNAME("EditorFonts"));
+ int doc_code_font_size = p_owner_node->get_theme_font_size(SNAME("doc_source_size"), EditorStringName(EditorFonts));
+ int doc_kbd_font_size = p_owner_node->get_theme_font_size(SNAME("doc_keyboard_size"), EditorStringName(EditorFonts));
const Color type_color = p_owner_node->get_theme_color(SNAME("type_color"), SNAME("EditorHelp"));
const Color code_color = p_owner_node->get_theme_color(SNAME("code_color"), SNAME("EditorHelp"));
@@ -1964,9 +1978,9 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control
const Color code_dark_color = Color(code_color, 0.8);
const Color link_color = p_owner_node->get_theme_color(SNAME("link_color"), SNAME("EditorHelp"));
- const Color link_method_color = p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor"));
- const Color link_property_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor")), 0.25);
- const Color link_annotation_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor")), 0.5);
+ const Color link_method_color = p_owner_node->get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
+ const Color link_property_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)), 0.25);
+ const Color link_annotation_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)), 0.5);
const Color code_bg_color = p_owner_node->get_theme_color(SNAME("code_bg_color"), SNAME("EditorHelp"));
const Color kbd_bg_color = p_owner_node->get_theme_color(SNAME("kbd_bg_color"), SNAME("EditorHelp"));
@@ -2187,7 +2201,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control
p_rt->push_font(doc_code_font);
p_rt->push_font_size(doc_code_font_size);
p_rt->push_bgcolor(code_bg_color);
- p_rt->push_color(code_color.lerp(p_owner_node->get_theme_color(SNAME("error_color"), SNAME("Editor")), 0.6));
+ p_rt->push_color(code_color.lerp(p_owner_node->get_theme_color(SNAME("error_color"), EditorStringName(Editor)), 0.6));
code_tag = true;
pos = brk_end + 1;
@@ -2486,9 +2500,9 @@ void EditorHelp::set_scroll(int p_scroll) {
void EditorHelp::update_toggle_scripts_button() {
if (is_layout_rtl()) {
- toggle_scripts_button->set_icon(get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons")));
+ toggle_scripts_button->set_icon(get_editor_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Forward") : SNAME("Back")));
} else {
- toggle_scripts_button->set_icon(get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons")));
+ toggle_scripts_button->set_icon(get_editor_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Back") : SNAME("Forward")));
}
toggle_scripts_button->set_tooltip_text(vformat("%s (%s)", TTR("Toggle Scripts Panel"), ED_GET_SHORTCUT("script_editor/toggle_scripts_panel")->get_as_text()));
}
@@ -2668,13 +2682,13 @@ void FindBar::popup_search() {
void FindBar::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
- find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
- hide_button->set_texture_normal(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_texture_hover(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- hide_button->set_texture_pressed(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ find_prev->set_icon(get_editor_theme_icon(SNAME("MoveUp")));
+ find_next->set_icon(get_editor_theme_icon(SNAME("MoveDown")));
+ hide_button->set_texture_normal(get_editor_theme_icon(SNAME("Close")));
+ hide_button->set_texture_hover(get_editor_theme_icon(SNAME("Close")));
+ hide_button->set_texture_pressed(get_editor_theme_icon(SNAME("Close")));
hide_button->set_custom_minimum_size(hide_button->get_texture_normal()->get_size());
- matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -2742,7 +2756,7 @@ void FindBar::_update_matches_label() {
} else {
matches_label->show();
- matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
}
}
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 0aa8302b27..1f1528945b 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -86,14 +86,11 @@ public:
class EditorHelp : public VBoxContainer {
GDCLASS(EditorHelp, VBoxContainer);
- enum Page {
- PAGE_CLASS_LIST,
- PAGE_CLASS_DESC,
- PAGE_CLASS_PREV,
- PAGE_CLASS_NEXT,
- PAGE_SEARCH,
- CLASS_SEARCH,
-
+ enum MethodType {
+ METHOD_TYPE_METHOD,
+ METHOD_TYPE_CONSTRUCTOR,
+ METHOD_TYPE_OPERATOR,
+ METHOD_TYPE_MAX
};
bool select_locked = false;
@@ -181,7 +178,7 @@ class EditorHelp : public VBoxContainer {
Error _goto_desc(const String &p_class);
//void _update_history_buttons();
void _update_method_list(const Vector<DocData::MethodDoc> p_methods);
- void _update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, const String &p_method_type);
+ void _update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, MethodType p_method_type);
void _update_doc();
void _request_help(const String &p_string);
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index f06a23607e..c0459e9496 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -35,13 +35,14 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
void EditorHelpSearch::_update_icons() {
- search_box->set_right_icon(results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(results_tree->get_editor_theme_icon(SNAME("Search")));
search_box->set_clear_button_enabled(true);
- search_box->add_theme_icon_override("right_icon", results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- case_sensitive_button->set_icon(results_tree->get_theme_icon(SNAME("MatchCase"), SNAME("EditorIcons")));
- hierarchy_button->set_icon(results_tree->get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons")));
+ search_box->add_theme_icon_override("right_icon", results_tree->get_editor_theme_icon(SNAME("Search")));
+ case_sensitive_button->set_icon(results_tree->get_editor_theme_icon(SNAME("MatchCase")));
+ hierarchy_button->set_icon(results_tree->get_editor_theme_icon(SNAME("ClassList")));
if (is_visible()) {
_update_results();
@@ -608,10 +609,10 @@ TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const
}
if (p_doc->is_deprecated) {
- Ref<Texture2D> error_icon = ui_service->get_theme_icon("StatusError", SNAME("EditorIcons"));
+ Ref<Texture2D> error_icon = ui_service->get_editor_theme_icon("StatusError");
item->add_button(0, error_icon, 0, false, TTR("This class is marked as deprecated."));
} else if (p_doc->is_experimental) {
- Ref<Texture2D> warning_icon = ui_service->get_theme_icon("NodeWarning", SNAME("EditorIcons"));
+ Ref<Texture2D> warning_icon = ui_service->get_editor_theme_icon("NodeWarning");
item->add_button(0, warning_icon, 0, false, TTR("This class is marked as experimental."));
}
@@ -656,10 +657,10 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons
Ref<Texture2D> icon;
String text;
if (search_flags & SEARCH_SHOW_HIERARCHY) {
- icon = ui_service->get_theme_icon(p_icon, SNAME("EditorIcons"));
+ icon = ui_service->get_editor_theme_icon(p_icon);
text = p_text;
} else {
- icon = ui_service->get_theme_icon(p_icon, SNAME("EditorIcons"));
+ icon = ui_service->get_editor_theme_icon(p_icon);
text = p_class_name + "." + p_text;
}
@@ -672,10 +673,10 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons
item->set_metadata(0, "class_" + p_metatype + ":" + p_class_name + ":" + p_name);
if (is_deprecated) {
- Ref<Texture2D> error_icon = ui_service->get_theme_icon("StatusError", SNAME("EditorIcons"));
+ Ref<Texture2D> error_icon = ui_service->get_editor_theme_icon("StatusError");
item->add_button(0, error_icon, 0, false, TTR("This member is marked as deprecated."));
} else if (is_experimental) {
- Ref<Texture2D> warning_icon = ui_service->get_theme_icon("NodeWarning", SNAME("EditorIcons"));
+ Ref<Texture2D> warning_icon = ui_service->get_editor_theme_icon("NodeWarning");
item->add_button(0, warning_icon, 0, false, TTR("This member is marked as experimental."));
}
@@ -700,5 +701,5 @@ EditorHelpSearch::Runner::Runner(Control *p_icon_service, Tree *p_results_tree,
results_tree(p_results_tree),
term((p_search_flags & SEARCH_CASE_SENSITIVE) == 0 ? p_term.strip_edges().to_lower() : p_term.strip_edges()),
search_flags(p_search_flags),
- disabled_color(ui_service->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))) {
+ disabled_color(ui_service->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))) {
}
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 3c14dedb2d..3aba59246f 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_validation_panel.h"
#include "editor/inspector_dock.h"
@@ -89,12 +90,12 @@ Size2 EditorProperty::get_minimum_size() const {
}
if (keying) {
- Ref<Texture2D> key = get_theme_icon(SNAME("Key"), SNAME("EditorIcons"));
+ Ref<Texture2D> key = get_editor_theme_icon(SNAME("Key"));
ms.width += key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
}
if (deletable) {
- Ref<Texture2D> key = get_theme_icon(SNAME("Close"), SNAME("EditorIcons"));
+ Ref<Texture2D> key = get_editor_theme_icon(SNAME("Close"));
ms.width += key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
}
@@ -180,9 +181,9 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> key;
if (use_keying_next()) {
- key = get_theme_icon(SNAME("KeyNext"), SNAME("EditorIcons"));
+ key = get_editor_theme_icon(SNAME("KeyNext"));
} else {
- key = get_theme_icon(SNAME("Key"), SNAME("EditorIcons"));
+ key = get_editor_theme_icon(SNAME("Key"));
}
rect.size.x -= key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
@@ -198,7 +199,7 @@ void EditorProperty::_notification(int p_what) {
if (deletable) {
Ref<Texture2D> close;
- close = get_theme_icon(SNAME("Close"), SNAME("EditorIcons"));
+ close = get_editor_theme_icon(SNAME("Close"));
rect.size.x -= close->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
@@ -278,9 +279,9 @@ void EditorProperty::_notification(int p_what) {
if (checkable) {
Ref<Texture2D> checkbox;
if (checked) {
- checkbox = get_theme_icon(SNAME("GuiChecked"), SNAME("EditorIcons"));
+ checkbox = get_editor_theme_icon(SNAME("GuiChecked"));
} else {
- checkbox = get_theme_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"));
+ checkbox = get_editor_theme_icon(SNAME("GuiUnchecked"));
}
Color color2(1, 1, 1);
@@ -303,7 +304,7 @@ void EditorProperty::_notification(int p_what) {
}
if (can_revert && !is_read_only()) {
- Ref<Texture2D> reload_icon = get_theme_icon(SNAME("ReloadSmall"), SNAME("EditorIcons"));
+ Ref<Texture2D> reload_icon = get_editor_theme_icon(SNAME("ReloadSmall"));
text_limit -= reload_icon->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
revert_rect = Rect2(ofs + text_limit, (size.height - reload_icon->get_height()) / 2, reload_icon->get_width(), reload_icon->get_height());
@@ -323,7 +324,7 @@ void EditorProperty::_notification(int p_what) {
}
if (!pin_hidden && pinned) {
- Ref<Texture2D> pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"));
+ Ref<Texture2D> pinned_icon = get_editor_theme_icon(SNAME("Pin"));
int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
int total_icon_w = margin_w + pinned_icon->get_width();
int text_w = font->get_string_size(label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w, font_size).x;
@@ -349,9 +350,9 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> key;
if (use_keying_next()) {
- key = get_theme_icon(SNAME("KeyNext"), SNAME("EditorIcons"));
+ key = get_editor_theme_icon(SNAME("KeyNext"));
} else {
- key = get_theme_icon(SNAME("Key"), SNAME("EditorIcons"));
+ key = get_editor_theme_icon(SNAME("Key"));
}
ofs -= key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
@@ -376,7 +377,7 @@ void EditorProperty::_notification(int p_what) {
if (deletable) {
Ref<Texture2D> close;
- close = get_theme_icon(SNAME("Close"), SNAME("EditorIcons"));
+ close = get_editor_theme_icon(SNAME("Close"));
ofs -= close->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree"));
@@ -757,10 +758,10 @@ void EditorProperty::shortcut_input(const Ref<InputEvent> &p_event) {
const Color *EditorProperty::_get_property_colors() {
static Color c[4];
- c[0] = get_theme_color(SNAME("property_color_x"), SNAME("Editor"));
- c[1] = get_theme_color(SNAME("property_color_y"), SNAME("Editor"));
- c[2] = get_theme_color(SNAME("property_color_z"), SNAME("Editor"));
- c[3] = get_theme_color(SNAME("property_color_w"), SNAME("Editor"));
+ c[0] = get_theme_color(SNAME("property_color_x"), EditorStringName(Editor));
+ c[1] = get_theme_color(SNAME("property_color_y"), EditorStringName(Editor));
+ c[2] = get_theme_color(SNAME("property_color_z"), EditorStringName(Editor));
+ c[3] = get_theme_color(SNAME("property_color_w"), EditorStringName(Editor));
return c;
}
@@ -1047,17 +1048,17 @@ void EditorProperty::_update_popup() {
add_child(menu);
menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
}
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_value"), MENU_COPY_VALUE);
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/paste_value"), MENU_PASTE_VALUE);
- menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionCopy")), ED_GET_SHORTCUT("property_editor/copy_value"), MENU_COPY_VALUE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionPaste")), ED_GET_SHORTCUT("property_editor/paste_value"), MENU_PASTE_VALUE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("CopyNodePath")), ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
menu->set_item_disabled(MENU_PASTE_VALUE, is_read_only());
if (!pin_hidden) {
menu->add_separator();
if (can_pin) {
- menu->add_icon_check_item(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), TTR("Pin Value"), MENU_PIN_VALUE);
+ menu->add_icon_check_item(get_editor_theme_icon(SNAME("Pin")), TTR("Pin Value"), MENU_PIN_VALUE);
menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned);
} else {
- menu->add_icon_check_item(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), vformat(TTR("Pin Value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
+ menu->add_icon_check_item(get_editor_theme_icon(SNAME("Pin")), vformat(TTR("Pin Value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
menu->set_item_disabled(menu->get_item_index(MENU_PIN_VALUE), true);
}
menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
@@ -1065,7 +1066,7 @@ void EditorProperty::_update_popup() {
if (!doc_path.is_empty()) {
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Help"), SNAME("EditorIcons")), TTR("Open Documentation"), MENU_OPEN_DOCUMENTATION);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Help")), TTR("Open Documentation"), MENU_OPEN_DOCUMENTATION);
}
}
@@ -1142,18 +1143,18 @@ void EditorInspectorCategory::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- menu->set_item_icon(menu->get_item_index(MENU_OPEN_DOCS), get_theme_icon(SNAME("Help"), SNAME("EditorIcons")));
+ menu->set_item_icon(menu->get_item_index(MENU_OPEN_DOCS), get_editor_theme_icon(SNAME("Help")));
} break;
case NOTIFICATION_DRAW: {
Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
draw_style_box(sb, Rect2(Vector2(), get_size()));
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
int hs = get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
- int icon_size = get_theme_constant(SNAME("class_icon_size"), SNAME("Editor"));
+ int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
int w = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
if (icon.is_valid()) {
@@ -1181,8 +1182,8 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons
}
Size2 EditorInspectorCategory::get_minimum_size() const {
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
Size2 ms;
ms.height = font->get_height(font_size);
@@ -1255,8 +1256,8 @@ Ref<Texture2D> EditorInspectorSection::_get_arrow() {
}
int EditorInspectorSection::_get_header_height() {
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
int header_height = font->get_height(font_size);
Ref<Texture2D> arrow = _get_arrow();
@@ -1279,7 +1280,7 @@ void EditorInspectorSection::_notification(int p_what) {
return;
}
- int inspector_margin = get_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
+ int inspector_margin = get_theme_constant(SNAME("inspector_margin"), EditorStringName(Editor));
int section_indent_size = get_theme_constant(SNAME("indent_size"), SNAME("EditorInspectorSection"));
if (indent_depth > 0 && section_indent_size > 0) {
inspector_margin += indent_depth * section_indent_size;
@@ -1362,16 +1363,16 @@ void EditorInspectorSection::_notification(int p_what) {
bool folded = foldable && !object->editor_is_section_unfolded(section);
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
- Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
+ Color font_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
if (folded && revertable_properties.size()) {
int label_width = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, available, font_size, TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS).x;
- Ref<Font> light_font = get_theme_font(SNAME("main"), SNAME("EditorFonts"));
- int light_font_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"));
- Color light_font_color = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
+ Ref<Font> light_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts));
+ int light_font_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts));
+ Color light_font_color = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor));
// Can we fit the long version of the revertable count text?
num_revertable_str = vformat(TTRN("(%d change)", "(%d changes)", revertable_properties.size()), revertable_properties.size());
@@ -1406,7 +1407,7 @@ void EditorInspectorSection::_notification(int p_what) {
// Draw dropping highlight.
if (dropping && !vbox->is_visible_in_tree()) {
- Color accent_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
draw_rect(Rect2(Point2(), get_size()), accent_color, false);
}
@@ -1467,7 +1468,7 @@ Size2 EditorInspectorSection::get_minimum_size() const {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree"));
ms.height += font->get_height(font_size) + get_theme_constant(SNAME("v_separation"), SNAME("Tree"));
- ms.width += get_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
+ ms.width += get_theme_constant(SNAME("inspector_margin"), EditorStringName(Editor));
int section_indent_size = get_theme_constant(SNAME("indent_size"), SNAME("EditorInspectorSection"));
if (indent_depth > 0 && section_indent_size > 0) {
@@ -1686,7 +1687,7 @@ void EditorInspectorArray::_control_dropping_draw() {
from = xform.xform(Vector2(0, child->get_size().y));
to = xform.xform(Vector2(elements_vbox->get_size().x, child->get_size().y));
}
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
control_dropping->draw_line(from, to, color, 2);
}
}
@@ -1698,7 +1699,7 @@ void EditorInspectorArray::_vbox_visibility_changed() {
void EditorInspectorArray::_panel_draw(int p_index) {
ERR_FAIL_INDEX(p_index, (int)array_elements.size());
- Ref<StyleBox> style = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"));
+ Ref<StyleBox> style = get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles));
if (!style.is_valid()) {
return;
}
@@ -2103,7 +2104,7 @@ void EditorInspectorArray::_setup() {
int numbers_min_w = 0;
if (numbered) {
- numbers_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
+ numbers_font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
int digits_found = count;
String test;
while (digits_found) {
@@ -2121,8 +2122,10 @@ void EditorInspectorArray::_setup() {
ae.panel->set_focus_mode(FOCUS_ALL);
ae.panel->set_mouse_filter(MOUSE_FILTER_PASS);
SET_DRAG_FORWARDING_GCD(ae.panel, EditorInspectorArray);
- ae.panel->set_meta("index", begin_array_index + i);
- ae.panel->set_tooltip_text(vformat(TTR("Element %d: %s%d*"), i, array_element_prefix, i));
+
+ int element_position = begin_array_index + i;
+ ae.panel->set_meta("index", element_position);
+ ae.panel->set_tooltip_text(vformat(TTR("Element %d: %s%d*"), element_position, array_element_prefix, element_position));
ae.panel->connect("focus_entered", callable_mp((CanvasItem *)ae.panel, &PanelContainer::queue_redraw));
ae.panel->connect("focus_exited", callable_mp((CanvasItem *)ae.panel, &PanelContainer::queue_redraw));
ae.panel->connect("draw", callable_mp(this, &EditorInspectorArray::_panel_draw).bind(i));
@@ -2133,7 +2136,7 @@ void EditorInspectorArray::_setup() {
ae.margin = memnew(MarginContainer);
ae.margin->set_mouse_filter(MOUSE_FILTER_PASS);
if (is_inside_tree()) {
- Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size();
+ Size2 min_size = get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles))->get_minimum_size();
ae.margin->add_theme_constant_override("margin_left", min_size.x / 2);
ae.margin->add_theme_constant_override("margin_top", min_size.y / 2);
ae.margin->add_theme_constant_override("margin_right", min_size.x / 2);
@@ -2148,7 +2151,6 @@ void EditorInspectorArray::_setup() {
// Move button.
if (movable) {
- int element_position = begin_array_index + i;
VBoxContainer *move_vbox = memnew(VBoxContainer);
move_vbox->set_v_size_flags(SIZE_EXPAND_FILL);
move_vbox->set_alignment(BoxContainer::ALIGNMENT_CENTER);
@@ -2156,7 +2158,7 @@ void EditorInspectorArray::_setup() {
if (element_position > 0) {
ae.move_up = memnew(Button);
- ae.move_up->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
+ ae.move_up->set_icon(get_editor_theme_icon(SNAME("MoveUp")));
ae.move_up->connect("pressed", callable_mp(this, &EditorInspectorArray::_move_element).bind(element_position, element_position - 1));
move_vbox->add_child(ae.move_up);
}
@@ -2166,13 +2168,13 @@ void EditorInspectorArray::_setup() {
ae.move_texture_rect->set_default_cursor_shape(Control::CURSOR_MOVE);
if (is_inside_tree()) {
- ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons")));
+ ae.move_texture_rect->set_texture(get_editor_theme_icon(SNAME("TripleBar")));
}
move_vbox->add_child(ae.move_texture_rect);
if (element_position < _get_array_count() - 1) {
ae.move_down = memnew(Button);
- ae.move_down->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
+ ae.move_down->set_icon(get_editor_theme_icon(SNAME("MoveDown")));
ae.move_down->connect("pressed", callable_mp(this, &EditorInspectorArray::_move_element).bind(element_position, element_position + 2));
move_vbox->add_child(ae.move_down);
}
@@ -2184,7 +2186,7 @@ void EditorInspectorArray::_setup() {
ae.number->set_custom_minimum_size(Size2(numbers_min_w, 0));
ae.number->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
ae.number->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
- ae.number->set_text(itos(begin_array_index + i));
+ ae.number->set_text(itos(element_position));
ae.hbox->add_child(ae.number);
}
@@ -2195,9 +2197,9 @@ void EditorInspectorArray::_setup() {
ae.hbox->add_child(ae.vbox);
ae.erase = memnew(Button);
- ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ ae.erase->set_icon(get_editor_theme_icon(SNAME("Remove")));
ae.erase->set_v_size_flags(SIZE_SHRINK_CENTER);
- ae.erase->connect("pressed", callable_mp(this, &EditorInspectorArray::_remove_item).bind(begin_array_index + i));
+ ae.erase->connect("pressed", callable_mp(this, &EditorInspectorArray::_remove_item).bind(element_position));
ae.hbox->add_child(ae.erase);
}
@@ -2268,32 +2270,32 @@ void EditorInspectorArray::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- Color color = get_theme_color(SNAME("dark_color_1"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("dark_color_1"), EditorStringName(Editor));
odd_style->set_bg_color(color.darkened(-0.08));
even_style->set_bg_color(color.darkened(0.08));
for (ArrayElement &ae : array_elements) {
if (ae.move_texture_rect) {
- ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons")));
+ ae.move_texture_rect->set_texture(get_editor_theme_icon(SNAME("TripleBar")));
}
if (ae.move_up) {
- ae.move_up->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
+ ae.move_up->set_icon(get_editor_theme_icon(SNAME("MoveUp")));
}
if (ae.move_down) {
- ae.move_down->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
+ ae.move_down->set_icon(get_editor_theme_icon(SNAME("MoveDown")));
}
- Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size();
+ Size2 min_size = get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles))->get_minimum_size();
ae.margin->add_theme_constant_override("margin_left", min_size.x / 2);
ae.margin->add_theme_constant_override("margin_top", min_size.y / 2);
ae.margin->add_theme_constant_override("margin_right", min_size.x / 2);
ae.margin->add_theme_constant_override("margin_bottom", min_size.y / 2);
if (ae.erase) {
- ae.erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ ae.erase->set_icon(get_editor_theme_icon(SNAME("Remove")));
}
}
- add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ add_button->set_icon(get_editor_theme_icon(SNAME("Add")));
update_minimum_size();
} break;
@@ -2462,10 +2464,10 @@ void EditorPaginator::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- first_page_button->set_icon(get_theme_icon(SNAME("PageFirst"), SNAME("EditorIcons")));
- prev_page_button->set_icon(get_theme_icon(SNAME("PagePrevious"), SNAME("EditorIcons")));
- next_page_button->set_icon(get_theme_icon(SNAME("PageNext"), SNAME("EditorIcons")));
- last_page_button->set_icon(get_theme_icon(SNAME("PageLast"), SNAME("EditorIcons")));
+ first_page_button->set_icon(get_editor_theme_icon(SNAME("PageFirst")));
+ prev_page_button->set_icon(get_editor_theme_icon(SNAME("PagePrevious")));
+ next_page_button->set_icon(get_editor_theme_icon(SNAME("PageNext")));
+ last_page_button->set_icon(get_editor_theme_icon(SNAME("PageLast")));
} break;
}
}
@@ -2748,7 +2750,7 @@ void EditorInspector::update_tree() {
HashMap<VBoxContainer *, HashMap<String, VBoxContainer *>> vbox_per_path;
HashMap<String, EditorInspectorArray *> editor_inspector_array_per_prefix;
- Color sscolor = get_theme_color(SNAME("prop_subsection"), SNAME("Editor"));
+ Color sscolor = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor));
// Get the lists of editors to add the beginning.
for (Ref<EditorInspectorPlugin> &ped : valid_plugins) {
@@ -3417,7 +3419,7 @@ void EditorInspector::update_tree() {
main_vbox->add_child(spacer);
Button *add_md = EditorInspector::create_inspector_action_button(TTR("Add Metadata"));
- add_md->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ add_md->set_icon(get_editor_theme_icon(SNAME("Add")));
add_md->connect(SNAME("pressed"), callable_mp(this, &EditorInspector::_show_add_meta_dialog));
main_vbox->add_child(add_md);
if (all_read_only) {
@@ -3679,7 +3681,7 @@ void EditorInspector::_update_inspector_bg() {
n = n->get_parent();
}
count_subinspectors = MIN(15, count_subinspectors);
- add_theme_style_override("panel", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), SNAME("Editor")));
+ add_theme_style_override("panel", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), EditorStringName(Editor)));
} else {
add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
}
@@ -4200,7 +4202,7 @@ void EditorInspector::_show_add_meta_dialog() {
}
String type = i == Variant::OBJECT ? String("Resource") : Variant::get_type_name(Variant::Type(i));
- add_meta_type->add_icon_item(get_theme_icon(type, "EditorIcons"), type, i);
+ add_meta_type->add_icon_item(get_editor_theme_icon(type), type, i);
}
hbc->add_child(add_meta_type);
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 4c2f6b3176..3cd5bbfad6 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/center_container.h"
#include "scene/gui/separator.h"
#include "scene/resources/font.h"
@@ -65,27 +66,27 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f
}
void EditorLog::_update_theme() {
- const Ref<Font> normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts"));
+ const Ref<Font> normal_font = get_theme_font(SNAME("output_source"), EditorStringName(EditorFonts));
if (normal_font.is_valid()) {
log->add_theme_font_override("normal_font", normal_font);
}
- const Ref<Font> bold_font = get_theme_font(SNAME("output_source_bold"), SNAME("EditorFonts"));
+ const Ref<Font> bold_font = get_theme_font(SNAME("output_source_bold"), EditorStringName(EditorFonts));
if (bold_font.is_valid()) {
log->add_theme_font_override("bold_font", bold_font);
}
- const Ref<Font> italics_font = get_theme_font(SNAME("output_source_italic"), SNAME("EditorFonts"));
+ const Ref<Font> italics_font = get_theme_font(SNAME("output_source_italic"), EditorStringName(EditorFonts));
if (italics_font.is_valid()) {
log->add_theme_font_override("italics_font", italics_font);
}
- const Ref<Font> bold_italics_font = get_theme_font(SNAME("output_source_bold_italic"), SNAME("EditorFonts"));
+ const Ref<Font> bold_italics_font = get_theme_font(SNAME("output_source_bold_italic"), EditorStringName(EditorFonts));
if (bold_italics_font.is_valid()) {
log->add_theme_font_override("bold_italics_font", bold_italics_font);
}
- const Ref<Font> mono_font = get_theme_font(SNAME("output_source_mono"), SNAME("EditorFonts"));
+ const Ref<Font> mono_font = get_theme_font(SNAME("output_source_mono"), EditorStringName(EditorFonts));
if (mono_font.is_valid()) {
log->add_theme_font_override("mono_font", mono_font);
}
@@ -95,33 +96,33 @@ void EditorLog::_update_theme() {
log->add_theme_constant_override("text_highlight_h_padding", 0);
log->add_theme_constant_override("text_highlight_v_padding", 0);
- const int font_size = get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"));
+ const int font_size = get_theme_font_size(SNAME("output_source_size"), EditorStringName(EditorFonts));
log->add_theme_font_size_override("normal_font_size", font_size);
log->add_theme_font_size_override("bold_font_size", font_size);
log->add_theme_font_size_override("italics_font_size", font_size);
log->add_theme_font_size_override("mono_font_size", font_size);
- type_filter_map[MSG_TYPE_STD]->toggle_button->set_icon(get_theme_icon(SNAME("Popup"), SNAME("EditorIcons")));
- type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
- type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_icon(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- type_filter_map[MSG_TYPE_EDITOR]->toggle_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ type_filter_map[MSG_TYPE_STD]->toggle_button->set_icon(get_editor_theme_icon(SNAME("Popup")));
+ type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_icon(get_editor_theme_icon(SNAME("StatusError")));
+ type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_icon(get_editor_theme_icon(SNAME("StatusWarning")));
+ type_filter_map[MSG_TYPE_EDITOR]->toggle_button->set_icon(get_editor_theme_icon(SNAME("Edit")));
type_filter_map[MSG_TYPE_STD]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_EDITOR]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
- clear_button->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
- copy_button->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
- collapse_button->set_icon(get_theme_icon(SNAME("CombineLines"), SNAME("EditorIcons")));
- show_search_button->set_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
-
- theme_cache.error_color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
- theme_cache.error_icon = get_theme_icon(SNAME("Error"), SNAME("EditorIcons"));
- theme_cache.warning_color = get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- theme_cache.warning_icon = get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"));
- theme_cache.message_color = get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.6);
+ clear_button->set_icon(get_editor_theme_icon(SNAME("Clear")));
+ copy_button->set_icon(get_editor_theme_icon(SNAME("ActionCopy")));
+ collapse_button->set_icon(get_editor_theme_icon(SNAME("CombineLines")));
+ show_search_button->set_icon(get_editor_theme_icon(SNAME("Search")));
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+
+ theme_cache.error_color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ theme_cache.error_icon = get_editor_theme_icon(SNAME("Error"));
+ theme_cache.warning_color = get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+ theme_cache.warning_icon = get_editor_theme_icon(SNAME("Warning"));
+ theme_cache.message_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6);
}
void EditorLog::_notification(int p_what) {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ea743fe470..6dc8d4e152 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -44,6 +44,7 @@
#include "core/string/print_string.h"
#include "core/string/translation.h"
#include "core/version.h"
+#include "editor/editor_string_names.h"
#include "main/main.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/dialogs.h"
@@ -62,6 +63,7 @@
#include "scene/resources/image_texture.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/portable_compressed_texture.h"
+#include "scene/theme/theme_db.h"
#include "servers/display_server.h"
#include "servers/navigation_server_3d.h"
#include "servers/physics_server_2d.h"
@@ -453,6 +455,119 @@ void EditorNode::_select_default_main_screen_plugin() {
editor_select(-1);
}
+void EditorNode::_update_theme(bool p_skip_creation) {
+ if (!p_skip_creation) {
+ theme = create_custom_theme(theme);
+ DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
+ }
+
+ List<Ref<Theme>> editor_themes;
+ editor_themes.push_back(theme);
+ editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme());
+
+ ThemeContext *node_tc = ThemeDB::get_singleton()->get_theme_context(this);
+ if (node_tc) {
+ node_tc->set_themes(editor_themes);
+ } else {
+ ThemeDB::get_singleton()->create_theme_context(this, editor_themes);
+ }
+
+ Window *window = get_window();
+ if (window) {
+ ThemeContext *window_tc = ThemeDB::get_singleton()->get_theme_context(window);
+ if (window_tc) {
+ window_tc->set_themes(editor_themes);
+ } else {
+ ThemeDB::get_singleton()->create_theme_context(window, editor_themes);
+ }
+ }
+
+ if (CanvasItemEditor::get_singleton()->get_theme_preview() == CanvasItemEditor::THEME_PREVIEW_EDITOR) {
+ update_preview_themes(CanvasItemEditor::THEME_PREVIEW_EDITOR);
+ }
+
+ gui_base->add_theme_style_override("panel", theme->get_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
+ main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, theme->get_constant(SNAME("window_border_margin"), EditorStringName(Editor)));
+ main_vbox->add_theme_constant_override("separation", theme->get_constant(SNAME("top_bar_separation"), EditorStringName(Editor)));
+
+ scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
+ main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles)));
+ prev_scene->set_icon(theme->get_icon(SNAME("PrevScene"), EditorStringName(EditorIcons)));
+ distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons)));
+ bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons)));
+
+ if (gui_base->is_layout_rtl()) {
+ dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons)));
+ dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons)));
+ } else {
+ dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons)));
+ dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons)));
+ }
+
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)));
+
+ for (int i = 0; i < main_editor_buttons.size(); i++) {
+ main_editor_buttons.write[i]->add_theme_font_override("font", theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts)));
+ main_editor_buttons.write[i]->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts)));
+ }
+
+ if (EditorDebuggerNode::get_singleton()->is_visible()) {
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles)));
+ }
+
+ for (int i = 0; i < main_editor_buttons.size(); i++) {
+ Button *tb = main_editor_buttons[i];
+ EditorPlugin *p_editor = editor_table[i];
+ Ref<Texture2D> icon = p_editor->get_icon();
+
+ if (icon.is_valid()) {
+ tb->set_icon(icon);
+ } else if (theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
+ tb->set_icon(theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
+ }
+ }
+}
+
+void EditorNode::update_preview_themes(int p_mode) {
+ if (!scene_root->is_inside_tree()) {
+ return; // Too early.
+ }
+
+ List<Ref<Theme>> preview_themes;
+
+ switch (p_mode) {
+ case CanvasItemEditor::THEME_PREVIEW_PROJECT:
+ preview_themes.push_back(ThemeDB::get_singleton()->get_project_theme());
+ break;
+
+ case CanvasItemEditor::THEME_PREVIEW_EDITOR:
+ preview_themes.push_back(get_editor_theme());
+ break;
+
+ default:
+ break;
+ }
+
+ preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme());
+
+ ThemeContext *preview_context = ThemeDB::get_singleton()->get_theme_context(scene_root);
+ if (preview_context) {
+ preview_context->set_themes(preview_themes);
+ } else {
+ ThemeDB::get_singleton()->create_theme_context(scene_root, preview_themes);
+ }
+}
+
void EditorNode::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_PROCESS: {
@@ -486,7 +601,7 @@ void EditorNode::_notification(int p_what) {
// Update the icon itself only when the spinner is visible.
if (EDITOR_GET("interface/editor/show_update_spinner")) {
- update_spinner->set_icon(gui_base->get_theme_icon("Progress" + itos(update_spinner_step + 1), SNAME("EditorIcons")));
+ update_spinner->set_icon(theme->get_icon("Progress" + itos(update_spinner_step + 1), EditorStringName(EditorIcons)));
}
}
@@ -506,9 +621,11 @@ void EditorNode::_notification(int p_what) {
if (window) {
// Handle macOS fullscreen and extend-to-title changes.
window->connect("titlebar_changed", callable_mp(this, &EditorNode::_titlebar_resized));
- window->set_theme(theme);
}
+ // Theme has already been created in the constructor, so we can skip that step.
+ _update_theme(true);
+
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
get_tree()->get_root()->set_as_audio_listener_3d(false);
get_tree()->get_root()->set_as_audio_listener_2d(false);
@@ -523,6 +640,7 @@ void EditorNode::_notification(int p_what) {
command_palette->register_shortcuts_as_command();
MessageQueue::get_singleton()->push_callable(callable_mp(this, &EditorNode::_begin_first_scan));
+
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break;
@@ -584,6 +702,10 @@ void EditorNode::_notification(int p_what) {
_titlebar_resized();
+ // Set up a theme context for the 2D preview viewport using the stored preview theme.
+ CanvasItemEditor::ThemePreviewMode theme_preview_mode = (CanvasItemEditor::ThemePreviewMode)(int)EditorSettings::get_singleton()->get_project_metadata("2d_editor", "theme_preview", CanvasItemEditor::THEME_PREVIEW_PROJECT);
+ update_preview_themes(theme_preview_mode);
+
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break;
@@ -631,73 +753,14 @@ void EditorNode::_notification(int p_what) {
EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles");
if (theme_changed) {
- theme = create_custom_theme(theme_base->get_theme());
- DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), SNAME("Editor")));
-
- theme_base->set_theme(theme);
- gui_base->set_theme(theme);
- get_window()->set_theme(theme);
-
- gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles")));
- main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, gui_base->get_theme_constant(SNAME("window_border_margin"), SNAME("Editor")));
- main_vbox->add_theme_constant_override("separation", gui_base->get_theme_constant(SNAME("top_bar_separation"), SNAME("Editor")));
- scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles")));
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), SNAME("EditorStyles")));
- main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles")));
+ _update_theme();
}
scene_tabs->update_scene_tabs();
recent_scenes->reset_size();
- // Update debugger area.
- if (EditorDebuggerNode::get_singleton()->is_visible()) {
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles")));
- }
-
- // Update icons.
- for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
- Button *tb = singleton->main_editor_buttons[i];
- EditorPlugin *p_editor = singleton->editor_table[i];
- Ref<Texture2D> icon = p_editor->get_icon();
-
- if (icon.is_valid()) {
- tb->set_icon(icon);
- } else if (singleton->gui_base->has_theme_icon(p_editor->get_name(), SNAME("EditorIcons"))) {
- tb->set_icon(singleton->gui_base->get_theme_icon(p_editor->get_name(), SNAME("EditorIcons")));
- }
- }
-
_build_icon_type_cache();
- prev_scene->set_icon(gui_base->get_theme_icon(SNAME("PrevScene"), SNAME("EditorIcons")));
- distraction_free->set_icon(gui_base->get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons")));
-
- bottom_panel_raise->set_icon(gui_base->get_theme_icon(SNAME("ExpandBottomDock"), SNAME("EditorIcons")));
-
- if (gui_base->is_layout_rtl()) {
- dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), SNAME("EditorIcons")));
- dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), SNAME("EditorIcons")));
- } else {
- dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), SNAME("EditorIcons")));
- dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), SNAME("EditorIcons")));
- }
-
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), gui_base->get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), gui_base->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), gui_base->get_theme_icon(SNAME("Godot"), SNAME("EditorIcons")));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), gui_base->get_theme_icon(SNAME("Heart"), SNAME("EditorIcons")));
-
- for (int i = 0; i < main_editor_buttons.size(); i++) {
- main_editor_buttons.write[i]->add_theme_font_override("font", gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts")));
- main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts")));
- }
-
HashSet<String> updated_textfile_extensions;
bool extensions_match = true;
const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false);
@@ -734,8 +797,7 @@ void EditorNode::_update_update_spinner() {
// Make the icon modulate color overbright because icons are not completely white on a dark theme.
// On a light theme, icons are dark, so we need to modulate them with an even brighter color.
const bool dark_theme = EditorSettings::get_singleton()->is_dark_theme();
- update_spinner->set_self_modulate(
- gui_base->get_theme_color(SNAME("error_color"), SNAME("Editor")) * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25)));
+ update_spinner->set_self_modulate(theme->get_color(SNAME("error_color"), EditorStringName(Editor)) * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25)));
} else {
update_spinner->set_tooltip_text(TTR("Spins when the editor window redraws."));
update_spinner->set_self_modulate(Color(1, 1, 1));
@@ -3130,12 +3192,12 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed
tb->set_icon(icon);
// Make sure the control is updated if the icon is reimported.
icon->connect_changed(callable_mp((Control *)tb, &Control::update_minimum_size));
- } else if (singleton->gui_base->has_theme_icon(p_editor->get_name(), SNAME("EditorIcons"))) {
- tb->set_icon(singleton->gui_base->get_theme_icon(p_editor->get_name(), SNAME("EditorIcons")));
+ } else if (singleton->theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
+ tb->set_icon(singleton->theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
}
- tb->add_theme_font_override("font", singleton->gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts")));
- tb->add_theme_font_size_override("font_size", singleton->gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts")));
+ tb->add_theme_font_override("font", singleton->theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts)));
+ tb->add_theme_font_size_override("font_size", singleton->theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts)));
singleton->main_editor_buttons.push_back(tb);
singleton->main_editor_button_hb->add_child(tb);
@@ -4066,14 +4128,14 @@ void EditorNode::notify_all_debug_sessions_exited() {
void EditorNode::add_io_error(const String &p_error) {
DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id());
- singleton->load_errors->add_image(singleton->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ singleton->load_errors->add_image(singleton->theme->get_icon(SNAME("Error"), EditorStringName(EditorIcons)));
singleton->load_errors->add_text(p_error + "\n");
EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
}
void EditorNode::add_io_warning(const String &p_warning) {
DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id());
- singleton->load_errors->add_image(singleton->gui_base->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
+ singleton->load_errors->add_image(singleton->theme->get_icon(SNAME("Warning"), EditorStringName(EditorIcons)));
singleton->load_errors->add_text(p_warning + "\n");
EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
}
@@ -4207,12 +4269,12 @@ Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, cons
}
if (p_fallback_script_to_theme) {
- // Look for the base type in the editor theme.
- // This is only relevant for built-in classes.
- String base_type;
- p_script->get_language()->get_global_class_name(p_script->get_path(), &base_type);
- if (gui_base && gui_base->has_theme_icon(base_type, SNAME("EditorIcons"))) {
- return gui_base->get_theme_icon(base_type, SNAME("EditorIcons"));
+ // Look for the native base type in the editor theme. This is relevant for
+ // scripts extending other scripts and for built-in classes.
+ String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path());
+ String base_type = ScriptServer::get_global_class_native_base(script_class_name);
+ if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) {
+ return theme->get_icon(base_type, EditorStringName(EditorIcons));
}
}
}
@@ -4235,22 +4297,22 @@ Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, cons
// Look up the class name or the fallback name in the editor theme.
// This is only relevant for built-in classes.
- if (gui_base) {
- if (gui_base->has_theme_icon(p_class, SNAME("EditorIcons"))) {
- return gui_base->get_theme_icon(p_class, SNAME("EditorIcons"));
+ if (theme.is_valid()) {
+ if (theme->has_icon(p_class, EditorStringName(EditorIcons))) {
+ return theme->get_icon(p_class, EditorStringName(EditorIcons));
}
- if (!p_fallback.is_empty() && gui_base->has_theme_icon(p_fallback, SNAME("EditorIcons"))) {
- return gui_base->get_theme_icon(p_fallback, SNAME("EditorIcons"));
+ if (!p_fallback.is_empty() && theme->has_icon(p_fallback, EditorStringName(EditorIcons))) {
+ return theme->get_icon(p_fallback, EditorStringName(EditorIcons));
}
// If the fallback is empty or wasn't found, use the default fallback.
if (ClassDB::class_exists(p_class)) {
bool instantiable = !ClassDB::is_virtual(p_class) && ClassDB::can_instantiate(p_class);
if (ClassDB::is_parent_class(p_class, SNAME("Node"))) {
- return gui_base->get_theme_icon(instantiable ? "Node" : "NodeDisabled", SNAME("EditorIcons"));
+ return theme->get_icon(instantiable ? "Node" : "NodeDisabled", EditorStringName(EditorIcons));
} else {
- return gui_base->get_theme_icon(instantiable ? "Object" : "ObjectDisabled", SNAME("EditorIcons"));
+ return theme->get_icon(instantiable ? "Object" : "ObjectDisabled", EditorStringName(EditorIcons));
}
}
}
@@ -4463,12 +4525,12 @@ Ref<Texture2D> EditorNode::_file_dialog_get_icon(const String &p_path) {
void EditorNode::_build_icon_type_cache() {
List<StringName> tl;
- theme_base->get_theme()->get_icon_list(SNAME("EditorIcons"), &tl);
+ theme->get_icon_list(EditorStringName(EditorIcons), &tl);
for (const StringName &E : tl) {
if (!ClassDB::class_exists(E)) {
continue;
}
- icon_type_cache[E] = theme_base->get_theme()->get_icon(E, SNAME("EditorIcons"));
+ icon_type_cache[E] = theme->get_icon(E, EditorStringName(EditorIcons));
}
}
@@ -4727,7 +4789,7 @@ void EditorNode::_dock_select_draw() {
Color used = Color(0.6, 0.6, 0.6, 0.8);
Color used_selected = Color(0.8, 0.8, 0.8, 0.8);
- Color tab_selected = theme_base->get_theme_color(SNAME("mono_color"), SNAME("Editor"));
+ Color tab_selected = theme->get_color(SNAME("mono_color"), EditorStringName(Editor));
Color unused = used;
unused.a = 0.4;
Color unusable = unused;
@@ -5665,9 +5727,9 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
}
if (EditorDebuggerNode::get_singleton() == bottom_panel_items[p_idx].control) {
// This is the debug panel which uses tabs, so the top section should be smaller.
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles")));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles)));
} else {
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), SNAME("EditorStyles")));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
}
center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE);
center_split->set_collapsed(false);
@@ -5676,7 +5738,7 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
}
bottom_panel_raise->show();
} else {
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), SNAME("EditorStyles")));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
bottom_panel_items[p_idx].button->set_pressed(false);
bottom_panel_items[p_idx].control->set_visible(false);
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
@@ -5765,7 +5827,7 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
{
// TODO: make proper previews
- Ref<ImageTexture> texture = gui_base->get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons"));
+ Ref<ImageTexture> texture = theme->get_icon(SNAME("FileBigThumb"), EditorStringName(EditorIcons));
Ref<Image> img = texture->get_image();
img = img->duplicate();
img->resize(48, 48); // meh
@@ -5815,10 +5877,10 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control *
if (p_paths[i].ends_with("/")) {
label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file());
- icon->set_texture(gui_base->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ icon->set_texture(theme->get_icon(SNAME("Folder"), EditorStringName(EditorIcons)));
} else {
label->set_text(p_paths[i].get_file());
- icon->set_texture(gui_base->get_theme_icon(SNAME("File"), SNAME("EditorIcons")));
+ icon->set_texture(theme->get_icon(SNAME("File"), EditorStringName(EditorIcons)));
}
icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
icon->set_size(Size2(16, 16));
@@ -6834,7 +6896,7 @@ EditorNode::EditorNode() {
// Exporters might need the theme.
EditorColorMap::create();
theme = create_custom_theme();
- DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), SNAME("Editor")));
+ DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
register_exporters();
@@ -6874,32 +6936,22 @@ EditorNode::EditorNode() {
textfile_extensions.insert(E);
}
- theme_base = memnew(Control);
- add_child(theme_base);
- theme_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
-
- gui_base = memnew(Panel);
- theme_base->add_child(gui_base);
- gui_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
-
- theme_base->set_theme(theme);
- gui_base->set_theme(theme);
- gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles")));
-
resource_preview = memnew(EditorResourcePreview);
add_child(resource_preview);
progress_dialog = memnew(ProgressDialog);
progress_dialog->set_unparent_when_invisible(true);
+ gui_base = memnew(Panel);
+ add_child(gui_base);
+
// Take up all screen.
+ gui_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
gui_base->set_anchor(SIDE_RIGHT, Control::ANCHOR_END);
gui_base->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END);
gui_base->set_end(Point2(0, 0));
main_vbox = memnew(VBoxContainer);
gui_base->add_child(main_vbox);
- main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, gui_base->get_theme_constant(SNAME("window_border_margin"), SNAME("Editor")));
- main_vbox->add_theme_constant_override("separation", gui_base->get_theme_constant(SNAME("top_bar_separation"), SNAME("Editor")));
title_bar = memnew(EditorTitleBar);
main_vbox->add_child(title_bar);
@@ -6977,11 +7029,6 @@ EditorNode::EditorNode() {
HBoxContainer *dock_hb = memnew(HBoxContainer);
dock_tab_move_left = memnew(Button);
dock_tab_move_left->set_flat(true);
- if (gui_base->is_layout_rtl()) {
- dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), SNAME("EditorIcons")));
- } else {
- dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), SNAME("EditorIcons")));
- }
dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE);
dock_tab_move_left->connect("pressed", callable_mp(this, &EditorNode::_dock_move_left));
dock_hb->add_child(dock_tab_move_left);
@@ -6994,11 +7041,6 @@ EditorNode::EditorNode() {
dock_tab_move_right = memnew(Button);
dock_tab_move_right->set_flat(true);
- if (gui_base->is_layout_rtl()) {
- dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), SNAME("EditorIcons")));
- } else {
- dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), SNAME("EditorIcons")));
- }
dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE);
dock_tab_move_right->connect("pressed", callable_mp(this, &EditorNode::_dock_move_right));
@@ -7015,7 +7057,7 @@ EditorNode::EditorNode() {
if (!SceneTree::get_singleton()->get_root()->is_embedding_subwindows() && !EDITOR_GET("interface/editor/single_window_mode") && EDITOR_GET("interface/multi_window/enable")) {
dock_float = memnew(Button);
- dock_float->set_icon(theme->get_icon("MakeFloating", "EditorIcons"));
+ dock_float->set_icon(theme->get_icon("MakeFloating", EditorStringName(EditorIcons)));
dock_float->set_text(TTR("Make Floating"));
dock_float->set_focus_mode(Control::FOCUS_NONE);
dock_float->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
@@ -7064,14 +7106,13 @@ EditorNode::EditorNode() {
ED_SHORTCUT_OVERRIDE("editor/distraction_free_mode", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::D);
distraction_free->set_shortcut(ED_GET_SHORTCUT("editor/distraction_free_mode"));
distraction_free->set_tooltip_text(TTR("Toggle distraction-free mode."));
- distraction_free->set_icon(gui_base->get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons")));
distraction_free->set_toggle_mode(true);
scene_tabs->add_extra_button(distraction_free);
distraction_free->connect("pressed", callable_mp(this, &EditorNode::_toggle_distraction_free_mode));
scene_root_parent = memnew(PanelContainer);
scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
- scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles")));
+ scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
scene_root_parent->set_draw_behind_parent(true);
srt->add_child(scene_root_parent);
scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -7079,7 +7120,6 @@ EditorNode::EditorNode() {
scene_root = memnew(SubViewport);
scene_root->set_embedding_subwindows(true);
scene_root->set_disable_3d(true);
-
scene_root->set_disable_input(true);
scene_root->set_as_audio_listener_2d(true);
@@ -7102,7 +7142,7 @@ EditorNode::EditorNode() {
main_menu = memnew(MenuBar);
title_bar->add_child(main_menu);
- main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles")));
+ main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles)));
main_menu->set_flat(true);
main_menu->set_start_index(0); // Main menu, add to the start of global menu.
main_menu->set_prefer_global_menu(global_menu);
@@ -7115,7 +7155,6 @@ EditorNode::EditorNode() {
prev_scene = memnew(Button);
prev_scene->set_flat(true);
- prev_scene->set_icon(gui_base->get_theme_icon(SNAME("PrevScene"), SNAME("EditorIcons")));
prev_scene->set_tooltip_text(TTR("Go to previously opened scene."));
prev_scene->set_disabled(true);
prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_OPEN_PREV));
@@ -7276,8 +7315,8 @@ EditorNode::EditorNode() {
if (can_expand && global_menu) {
project_title = memnew(Label);
- project_title->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
- project_title->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")));
+ project_title->add_theme_font_override("font", theme->get_font(SNAME("bold"), EditorStringName(EditorFonts)));
+ project_title->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts)));
project_title->set_focus_mode(Control::FOCUS_NONE);
project_title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
project_title->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
@@ -7353,22 +7392,23 @@ EditorNode::EditorNode() {
ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTR("Search Help"), Key::F1);
ED_SHORTCUT_OVERRIDE("editor/editor_help", "macos", KeyModifierMask::ALT | Key::SPACE);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons)), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH);
+ help_menu->add_separator();
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/community", TTR("Community")), HELP_COMMUNITY);
help_menu->add_separator();
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTR("Copy System Info")), HELP_COPY_SYSTEM_INFO);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTR("Copy System Info")), HELP_COPY_SYSTEM_INFO);
help_menu->set_item_tooltip(-1, TTR("Copies the system info as a single-line text into the clipboard."));
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTR("Suggest a Feature")), HELP_SUGGEST_A_FEATURE);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK);
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/community", TTR("Community")), HELP_COMMUNITY);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTR("Suggest a Feature")), HELP_SUGGEST_A_FEATURE);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK);
help_menu->add_separator();
if (!global_menu || !OS::get_singleton()->has_feature("macos")) {
// On macOS "Quit" and "About" options are in the "app" menu.
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("Godot"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/about", TTR("About Godot")), HELP_ABOUT);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/about", TTR("About Godot")), HELP_ABOUT);
}
- help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("Heart"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTR("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT);
+ help_menu->add_icon_shortcut(theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTR("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT);
// Spacer to center 2D / 3D / Script buttons.
Control *right_spacer = memnew(Control);
@@ -7390,8 +7430,8 @@ EditorNode::EditorNode() {
renderer->set_fit_to_longest_item(false);
renderer->set_focus_mode(Control::FOCUS_NONE);
renderer->connect("item_selected", callable_mp(this, &EditorNode::_renderer_selected));
- renderer->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
- renderer->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")));
+ renderer->add_theme_font_override("font", theme->get_font(SNAME("bold"), EditorStringName(EditorFonts)));
+ renderer->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts)));
renderer->set_tooltip_text(TTR("Choose a renderer."));
right_menu_hb->add_child(renderer);
@@ -7452,7 +7492,7 @@ EditorNode::EditorNode() {
update_spinner = memnew(MenuButton);
right_menu_hb->add_child(update_spinner);
- update_spinner->set_icon(gui_base->get_theme_icon(SNAME("Progress1"), SNAME("EditorIcons")));
+ update_spinner->set_icon(theme->get_icon(SNAME("Progress1"), EditorStringName(EditorIcons)));
update_spinner->get_popup()->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
PopupMenu *p = update_spinner->get_popup();
p->add_radio_check_item(TTR("Update Continuously"), SETTINGS_UPDATE_CONTINUOUSLY);
@@ -7535,7 +7575,7 @@ EditorNode::EditorNode() {
// Bottom panels.
bottom_panel = memnew(PanelContainer);
- bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), SNAME("EditorStyles")));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
center_split->add_child(bottom_panel);
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
@@ -7580,14 +7620,11 @@ EditorNode::EditorNode() {
bottom_panel_hb->add_child(h_spacer);
bottom_panel_raise = memnew(Button);
- bottom_panel_raise->set_flat(true);
- bottom_panel_raise->set_icon(gui_base->get_theme_icon(SNAME("ExpandBottomDock"), SNAME("EditorIcons")));
-
- bottom_panel_raise->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12));
-
bottom_panel_hb->add_child(bottom_panel_raise);
bottom_panel_raise->hide();
+ bottom_panel_raise->set_flat(true);
bottom_panel_raise->set_toggle_mode(true);
+ bottom_panel_raise->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12));
bottom_panel_raise->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_raise_toggled));
log = memnew(EditorLog);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 4a529afc50..a83570b2ea 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -295,7 +295,6 @@ private:
bool is_main_screen_editing = false;
PanelContainer *scene_root_parent = nullptr;
- Control *theme_base = nullptr;
Control *gui_base = nullptr;
VBoxContainer *main_vbox = nullptr;
OptionButton *renderer = nullptr;
@@ -525,6 +524,7 @@ private:
static void _resource_saved(Ref<Resource> p_resource, const String &p_path);
static void _resource_loaded(Ref<Resource> p_resource, const String &p_path);
+ void _update_theme(bool p_skip_creation = false);
void _build_icon_type_cache();
void _enable_pending_addons();
@@ -851,6 +851,8 @@ public:
void stop_child_process(OS::ProcessID p_pid);
Ref<Theme> get_editor_theme() const { return theme; }
+ void update_preview_themes(int p_mode);
+
Ref<Script> get_object_custom_type_base(const Object *p_object) const;
StringName get_object_custom_type_name(const Object *p_object) const;
Ref<Texture2D> get_object_icon(const Object *p_object, const String &p_fallback = "Object");
@@ -867,7 +869,6 @@ public:
Error export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only);
Control *get_gui_base() { return gui_base; }
- Control *get_theme_base() { return gui_base->get_parent_control(); }
void save_scene_to_path(String p_file, bool p_with_preview = true) {
if (p_with_preview) {
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index 453ae76266..167a151419 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -123,7 +123,7 @@ void EditorPluginSettings::update_plugins() {
bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(path);
item->set_checked(3, is_active);
item->set_editable(3, true);
- item->add_button(4, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));
+ item->add_button(4, get_editor_theme_icon(SNAME("Edit")), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));
}
}
}
@@ -245,7 +245,7 @@ EditorPluginSettings::EditorPluginSettings() {
plugin_list->set_column_custom_minimum_width(3, 80 * EDSCALE);
plugin_list->set_column_custom_minimum_width(4, 40 * EDSCALE);
plugin_list->set_hide_root(true);
- plugin_list->connect("item_edited", callable_mp(this, &EditorPluginSettings::_plugin_activity_changed));
+ plugin_list->connect("item_edited", callable_mp(this, &EditorPluginSettings::_plugin_activity_changed), CONNECT_DEFERRED);
VBoxContainer *mc = memnew(VBoxContainer);
mc->add_child(plugin_list);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 92789275a9..2a82b2cde4 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_resource_picker.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/gui/editor_spin_slider.h"
#include "editor/gui/scene_tree_editor.h"
@@ -162,8 +163,8 @@ void EditorPropertyMultilineText::_open_big_text() {
big_text = memnew(TextEdit);
if (expression) {
big_text->set_syntax_highlighter(text->get_syntax_highlighter());
- big_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts")));
- big_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")));
+ big_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), EditorStringName(EditorFonts)));
+ big_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), EditorStringName(EditorFonts)));
}
big_text->connect("text_changed", callable_mp(this, &EditorPropertyMultilineText::_big_text_changed));
big_text->set_line_wrapping_mode(TextEdit::LineWrappingMode::LINE_WRAPPING_BOUNDARY);
@@ -192,14 +193,14 @@ void EditorPropertyMultilineText::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
- Ref<Texture2D> df = get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons"));
+ Ref<Texture2D> df = get_editor_theme_icon(SNAME("DistractionFree"));
open_big_text->set_icon(df);
Ref<Font> font;
int font_size;
if (expression) {
- font = get_theme_font(SNAME("expression"), SNAME("EditorFonts"));
- font_size = get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"));
+ font = get_theme_font(SNAME("expression"), EditorStringName(EditorFonts));
+ font_size = get_theme_font_size(SNAME("expression_size"), EditorStringName(EditorFonts));
text->add_theme_font_override("font", font);
text->add_theme_font_size_override("font_size", font_size);
@@ -347,9 +348,9 @@ void EditorPropertyTextEnum::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- edit_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- accept_button->set_icon(get_theme_icon(SNAME("ImportCheck"), SNAME("EditorIcons")));
- cancel_button->set_icon(get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons")));
+ edit_button->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ accept_button->set_icon(get_editor_theme_icon(SNAME("ImportCheck")));
+ cancel_button->set_icon(get_editor_theme_icon(SNAME("ImportFail")));
} break;
}
}
@@ -435,7 +436,7 @@ void EditorPropertyLocale::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- locale_edit->set_icon(get_theme_icon(SNAME("Translation"), SNAME("EditorIcons")));
+ locale_edit->set_icon(get_editor_theme_icon(SNAME("Translation")));
} break;
}
}
@@ -531,7 +532,7 @@ void EditorPropertyPath::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- path_edit->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ path_edit->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
}
}
@@ -989,12 +990,12 @@ void EditorPropertyLayersGrid::_notification(int p_what) {
const int bsize = (grid_size.height * 80 / 100) / 2;
const int h = bsize * 2 + 1;
- Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor"));
+ Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), EditorStringName(Editor));
- Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor"));
+ Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), EditorStringName(Editor));
text_color.a *= 0.5;
- Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor"));
+ Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), EditorStringName(Editor));
text_color_on.a *= 0.7;
const int vofs = (grid_size.height - h) / 2;
@@ -1080,7 +1081,7 @@ void EditorPropertyLayersGrid::_notification(int p_what) {
Ref<Texture2D> arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree"));
ERR_FAIL_COND(arrow.is_null());
- Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
+ Color arrow_color = get_theme_color(SNAME("highlight_color"), EditorStringName(Editor));
arrow_color.a = expand_hovered ? 1.0 : 0.6;
arrow_pos.x += 2.0;
@@ -1117,9 +1118,9 @@ void EditorPropertyLayers::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- button->set_texture_normal(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- button->set_texture_pressed(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- button->set_texture_disabled(get_theme_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons")));
+ button->set_texture_normal(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ button->set_texture_pressed(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ button->set_texture_disabled(get_editor_theme_icon(SNAME("GuiTabMenu")));
} break;
}
}
@@ -1244,7 +1245,7 @@ void EditorPropertyLayers::_button_pressed() {
layers->set_item_disabled(0, true);
}
layers->add_separator();
- layers->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit Layer Names"), grid->layer_count);
+ layers->add_icon_item(get_editor_theme_icon("Edit"), TTR("Edit Layer Names"), grid->layer_count);
Rect2 gp = button->get_screen_rect();
layers->reset_size();
@@ -1408,7 +1409,7 @@ void EditorPropertySignal::update_property() {
edit->set_text("Signal: " + signal.get_name());
edit->set_disabled(false);
- edit->set_icon(get_theme_icon(SNAME("Signals"), SNAME("EditorIcons")));
+ edit->set_icon(get_editor_theme_icon(SNAME("Signals")));
}
void EditorPropertySignal::_bind_methods() {
@@ -1430,7 +1431,7 @@ void EditorPropertyCallable::update_property() {
edit->set_text("Callable");
edit->set_disabled(true);
- edit->set_icon(get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")));
+ edit->set_icon(get_editor_theme_icon(SNAME("Callable")));
}
void EditorPropertyCallable::_bind_methods() {
@@ -1579,7 +1580,7 @@ void EditorPropertyEasing::_draw_easing() {
const Color font_color = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit"));
Color line_color;
if (dragging) {
- line_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ line_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
} else {
line_color = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit")) * Color(1, 1, 1, 0.9);
}
@@ -1672,13 +1673,13 @@ void EditorPropertyEasing::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
preset->clear();
- preset->add_icon_item(get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")), "Linear", EASING_LINEAR);
- preset->add_icon_item(get_theme_icon(SNAME("CurveIn"), SNAME("EditorIcons")), "Ease In", EASING_IN);
- preset->add_icon_item(get_theme_icon(SNAME("CurveOut"), SNAME("EditorIcons")), "Ease Out", EASING_OUT);
- preset->add_icon_item(get_theme_icon(SNAME("CurveConstant"), SNAME("EditorIcons")), "Zero", EASING_ZERO);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveLinear")), "Linear", EASING_LINEAR);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveIn")), "Ease In", EASING_IN);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveOut")), "Ease Out", EASING_OUT);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveConstant")), "Zero", EASING_ZERO);
if (!positive_only) {
- preset->add_icon_item(get_theme_icon(SNAME("CurveInOut"), SNAME("EditorIcons")), "Ease In-Out", EASING_IN_OUT);
- preset->add_icon_item(get_theme_icon(SNAME("CurveOutIn"), SNAME("EditorIcons")), "Ease Out-In", EASING_OUT_IN);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveInOut")), "Ease In-Out", EASING_IN_OUT);
+ preset->add_icon_item(get_editor_theme_icon(SNAME("CurveOutIn")), "Ease Out-In", EASING_OUT_IN);
}
easing_draw->set_custom_minimum_size(Size2(0, get_theme_font(SNAME("font"), SNAME("Label"))->get_height(get_theme_font_size(SNAME("font_size"), SNAME("Label"))) * 2));
} break;
@@ -2114,10 +2115,10 @@ void EditorPropertyQuaternion::_notification(int p_what) {
for (int i = 0; i < 3; i++) {
euler[i]->add_theme_color_override("label_color", colors[i]);
}
- edit_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- euler_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("property_color"), SNAME("Editor")));
- warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ edit_button->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ euler_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("property_color"), EditorStringName(Editor)));
+ warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} break;
}
}
@@ -2724,7 +2725,7 @@ void EditorPropertyColor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- picker->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
+ picker->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
} break;
}
}
@@ -2921,7 +2922,7 @@ void EditorPropertyNodePath::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- Ref<Texture2D> t = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
+ Ref<Texture2D> t = get_editor_theme_icon(SNAME("Clear"));
clear->set_icon(t);
} break;
}
@@ -3210,9 +3211,9 @@ void EditorPropertyResource::_update_property_bg() {
}
count_subinspectors = MIN(15, count_subinspectors);
- add_theme_color_override("property_color", get_theme_color(SNAME("sub_inspector_property_color"), SNAME("Editor")));
- add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor")));
- add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor")));
+ add_theme_color_override("property_color", get_theme_color(SNAME("sub_inspector_property_color"), EditorStringName(Editor)));
+ add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), EditorStringName(Editor)));
+ add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), EditorStringName(Editor)));
add_theme_constant_override("v_separation", 0);
} else {
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 3a84fcb785..61c6c0bcdb 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_properties_vector.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_spin_slider.h"
#include "editor/inspector_dock.h"
#include "scene/gui/button.h"
@@ -312,7 +313,7 @@ void EditorPropertyArray::update_property() {
vbox->add_child(property_vbox);
button_add_item = EditorInspector::create_inspector_action_button(TTR("Add Element"));
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
button_add_item->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyArray::_add_element));
button_add_item->set_disabled(is_read_only());
vbox->add_child(button_add_item);
@@ -357,7 +358,7 @@ void EditorPropertyArray::update_property() {
property_vbox->add_child(hbox);
Button *reorder_button = memnew(Button);
- reorder_button->set_icon(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons")));
+ reorder_button->set_icon(get_editor_theme_icon(SNAME("TripleBar")));
reorder_button->set_default_cursor_shape(Control::CURSOR_MOVE);
reorder_button->set_disabled(is_read_only());
reorder_button->connect("gui_input", callable_mp(this, &EditorPropertyArray::_reorder_button_gui_input));
@@ -397,13 +398,13 @@ void EditorPropertyArray::update_property() {
if (is_untyped_array) {
Button *edit_btn = memnew(Button);
- edit_btn->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ edit_btn->set_icon(get_editor_theme_icon(SNAME("Edit")));
hbox->add_child(edit_btn);
edit_btn->set_disabled(is_read_only());
edit_btn->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type).bind(edit_btn, i + offset));
} else {
Button *remove_btn = memnew(Button);
- remove_btn->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ remove_btn->set_icon(get_editor_theme_icon(SNAME("Remove")));
remove_btn->set_disabled(is_read_only());
remove_btn->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed).bind(i + offset));
hbox->add_child(remove_btn);
@@ -438,7 +439,7 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
void EditorPropertyArray::_button_draw() {
if (dropping) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
edit->draw_rect(Rect2(Point2(), edit->get_size()), color, false);
}
}
@@ -529,13 +530,13 @@ void EditorPropertyArray::_notification(int p_what) {
}
String type = Variant::get_type_name(Variant::Type(i));
- change_type->add_icon_item(get_theme_icon(type, SNAME("EditorIcons")), type, i);
+ change_type->add_icon_item(get_editor_theme_icon(type), type, i);
}
change_type->add_separator();
- change_type->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Remove Item"), Variant::VARIANT_MAX);
+ change_type->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Remove Item"), Variant::VARIANT_MAX);
if (button_add_item) {
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
}
} break;
@@ -1117,7 +1118,7 @@ void EditorPropertyDictionary::update_property() {
if (i == amount) {
PanelContainer *pc = memnew(PanelContainer);
property_vbox->add_child(pc);
- pc->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("DictionaryAddItem"), SNAME("EditorStyles")));
+ pc->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("DictionaryAddItem"), EditorStringName(EditorStyles)));
add_vbox = memnew(VBoxContainer);
pc->add_child(add_vbox);
@@ -1151,7 +1152,7 @@ void EditorPropertyDictionary::update_property() {
hbox->add_child(prop);
prop->set_h_size_flags(SIZE_EXPAND_FILL);
Button *edit_btn = memnew(Button);
- edit_btn->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ edit_btn->set_icon(get_editor_theme_icon(SNAME("Edit")));
edit_btn->set_disabled(is_read_only());
hbox->add_child(edit_btn);
edit_btn->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type).bind(edit_btn, change_index));
@@ -1160,7 +1161,7 @@ void EditorPropertyDictionary::update_property() {
if (i == amount + 1) {
button_add_item = EditorInspector::create_inspector_action_button(TTR("Add Key/Value Pair"));
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
button_add_item->set_disabled(is_read_only());
button_add_item->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_add_key_value));
add_vbox->add_child(button_add_item);
@@ -1195,13 +1196,13 @@ void EditorPropertyDictionary::_notification(int p_what) {
}
String type = Variant::get_type_name(Variant::Type(i));
- change_type->add_icon_item(get_theme_icon(type, SNAME("EditorIcons")), type, i);
+ change_type->add_icon_item(get_editor_theme_icon(type), type, i);
}
change_type->add_separator();
- change_type->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Remove Item"), Variant::VARIANT_MAX);
+ change_type->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Remove Item"), Variant::VARIANT_MAX);
if (button_add_item) {
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
}
} break;
}
@@ -1380,7 +1381,7 @@ void EditorPropertyLocalizableString::update_property() {
hbox->add_child(prop);
prop->set_h_size_flags(SIZE_EXPAND_FILL);
Button *edit_btn = memnew(Button);
- edit_btn->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ edit_btn->set_icon(get_editor_theme_icon(SNAME("Remove")));
hbox->add_child(edit_btn);
edit_btn->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item).bind(edit_btn, remove_index));
@@ -1389,7 +1390,7 @@ void EditorPropertyLocalizableString::update_property() {
if (page_index == max_page) {
button_add_item = EditorInspector::create_inspector_action_button(TTR("Add Translation"));
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
button_add_item->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_add_locale_popup));
property_vbox->add_child(button_add_item);
}
@@ -1415,7 +1416,7 @@ void EditorPropertyLocalizableString::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
if (button_add_item) {
- button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->set_icon(get_editor_theme_icon(SNAME("Add")));
}
} break;
}
diff --git a/editor/editor_properties_vector.cpp b/editor/editor_properties_vector.cpp
index 66ed95b97e..9e9848f142 100644
--- a/editor/editor_properties_vector.cpp
+++ b/editor/editor_properties_vector.cpp
@@ -136,8 +136,8 @@ void EditorPropertyVectorN::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- linked->set_texture_normal(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons")));
- linked->set_texture_pressed(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
+ linked->set_texture_normal(get_editor_theme_icon(SNAME("Unlinked")));
+ linked->set_texture_pressed(get_editor_theme_icon(SNAME("Instance")));
const Color *colors = _get_property_colors();
for (int i = 0; i < component_count; i++) {
diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp
index a6cd07dd8b..b9144375bc 100644
--- a/editor/editor_property_name_processor.cpp
+++ b/editor/editor_property_name_processor.cpp
@@ -276,7 +276,6 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["uv"] = "UV";
capitalize_string_remaps["uv1"] = "UV1";
capitalize_string_remaps["uv2"] = "UV2";
- capitalize_string_remaps["uwp"] = "UWP";
capitalize_string_remaps["vector2"] = "Vector2";
capitalize_string_remaps["vpn"] = "VPN";
capitalize_string_remaps["vram"] = "VRAM";
diff --git a/editor/editor_quick_open.cpp b/editor/editor_quick_open.cpp
index f75ab875e4..82313c12e2 100644
--- a/editor/editor_quick_open.cpp
+++ b/editor/editor_quick_open.cpp
@@ -257,7 +257,7 @@ void EditorQuickOpen::_notification(int p_what) {
}
void EditorQuickOpen::_theme_changed() {
- search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
}
void EditorQuickOpen::_bind_methods() {
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index ea7e1549f5..e284c1e440 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/plugins/editor_resource_conversion_plugin.h"
@@ -193,10 +194,10 @@ void EditorResourcePicker::_update_menu_items() {
set_create_options(edit_menu);
// Add an option to load a resource from a file using the QuickOpen dialog.
- edit_menu->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Quick Load"), OBJ_MENU_QUICKLOAD);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Quick Load"), OBJ_MENU_QUICKLOAD);
// Add an option to load a resource from a file using the regular file dialog.
- edit_menu->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Load"), OBJ_MENU_LOAD);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Load"), OBJ_MENU_LOAD);
}
// Add options for changing existing value of the resource.
@@ -208,14 +209,14 @@ void EditorResourcePicker::_update_menu_items() {
// since will only be able to view its properties in read-only mode.
if (is_edited_resource_foreign_import) {
// The 'Search' icon is a magnifying glass, which seems appropriate, but maybe a bespoke icon is preferred here.
- edit_menu->add_icon_item(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")), TTR("Inspect"), OBJ_MENU_INSPECT);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Search")), TTR("Inspect"), OBJ_MENU_INSPECT);
} else {
- edit_menu->add_icon_item(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), TTR("Edit"), OBJ_MENU_INSPECT);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Edit")), TTR("Edit"), OBJ_MENU_INSPECT);
}
if (is_editable()) {
- edit_menu->add_icon_item(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), TTR("Clear"), OBJ_MENU_CLEAR);
- edit_menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Clear")), TTR("Clear"), OBJ_MENU_CLEAR);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
// Check whether the resource has subresources.
List<PropertyInfo> property_list;
@@ -228,10 +229,10 @@ void EditorResourcePicker::_update_menu_items() {
}
}
if (has_subresources) {
- edit_menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Make Unique (Recursive)"), OBJ_MENU_MAKE_UNIQUE_RECURSIVE);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Make Unique (Recursive)"), OBJ_MENU_MAKE_UNIQUE_RECURSIVE);
}
- edit_menu->add_icon_item(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")), TTR("Save"), OBJ_MENU_SAVE);
+ edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Save")), TTR("Save"), OBJ_MENU_SAVE);
}
if (edited_resource->get_path().is_resource_file()) {
@@ -282,8 +283,8 @@ void EditorResourcePicker::_update_menu_items() {
for (int i = 0; i < conversions.size(); i++) {
String what = conversions[i]->converts_to();
Ref<Texture2D> icon;
- if (has_theme_icon(what, SNAME("EditorIcons"))) {
- icon = get_theme_icon(what, SNAME("EditorIcons"));
+ if (has_theme_icon(what, EditorStringName(EditorIcons))) {
+ icon = get_editor_theme_icon(what);
} else {
icon = get_theme_icon(what, SNAME("Resource"));
}
@@ -516,7 +517,7 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) {
inheritors_array.push_back(t);
if (!icon.is_valid()) {
- icon = get_theme_icon(has_theme_icon(t, SNAME("EditorIcons")) ? t : String("Object"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(has_theme_icon(t, EditorStringName(EditorIcons)) ? t : String("Object"));
}
int id = TYPE_BASE_ID + idx;
@@ -539,7 +540,7 @@ bool EditorResourcePicker::handle_menu_selected(int p_which) {
void EditorResourcePicker::_button_draw() {
if (dropping) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
assign_button->draw_rect(Rect2(Point2(), assign_button->get_size()), color, false);
}
}
@@ -806,7 +807,7 @@ void EditorResourcePicker::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- assign_button->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), SNAME("Editor")));
+ assign_button->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
edit_button->set_icon(get_theme_icon(SNAME("select_arrow"), SNAME("Tree")));
} break;
@@ -1072,11 +1073,11 @@ void EditorScriptPicker::set_create_options(Object *p_menu_node) {
return;
}
- menu_node->add_icon_item(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")), TTR("New Script"), OBJ_MENU_NEW_SCRIPT);
+ menu_node->add_icon_item(get_editor_theme_icon(SNAME("ScriptCreate")), TTR("New Script"), OBJ_MENU_NEW_SCRIPT);
if (script_owner) {
Ref<Script> scr = script_owner->get_script();
if (scr.is_valid()) {
- menu_node->add_icon_item(get_theme_icon(SNAME("ScriptExtend"), SNAME("EditorIcons")), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT);
+ menu_node->add_icon_item(get_editor_theme_icon(SNAME("ScriptExtend")), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT);
}
}
menu_node->add_separator();
@@ -1128,7 +1129,7 @@ void EditorShaderPicker::set_create_options(Object *p_menu_node) {
return;
}
- menu_node->add_icon_item(get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")), TTR("New Shader"), OBJ_MENU_NEW_SHADER);
+ menu_node->add_icon_item(get_editor_theme_icon(SNAME("Shader")), TTR("New Shader"), OBJ_MENU_NEW_SHADER);
menu_node->add_separator();
}
@@ -1277,12 +1278,12 @@ void EditorAudioStreamPicker::_preview_draw() {
points.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
}
- Vector<Color> colors = { get_theme_color(SNAME("contrast_color_2"), SNAME("Editor")) };
+ Vector<Color> colors = { get_theme_color(SNAME("contrast_color_2"), EditorStringName(Editor)) };
RS::get_singleton()->canvas_item_add_multiline(stream_preview_rect->get_canvas_item(), points, colors);
if (tagged_frame_offset_count) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
for (uint32_t i = 0; i < tagged_frame_offset_count; i++) {
int x = CLAMP(tagged_frame_offsets[i] * size.width / preview_len, 0, size.width);
@@ -1299,9 +1300,9 @@ void EditorAudioStreamPicker::_preview_draw() {
Color icon_modulate(1, 1, 1, 1);
if (tagged_frame_offset_count > 0) {
- icon = get_theme_icon(SNAME("Play"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("Play"));
if ((OS::get_singleton()->get_ticks_msec() % 500) > 250) {
- icon_modulate = Color(1, 0.5, 0.5, 1); // get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ icon_modulate = Color(1, 0.5, 0.5, 1); // get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
}
} else {
icon = EditorNode::get_singleton()->get_object_icon(audio_stream.operator->(), "Object");
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index c6747c4481..ac098a354d 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/image_texture.h"
bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
@@ -341,7 +342,8 @@ void EditorResourcePreview::_thread() {
void EditorResourcePreview::_update_thumbnail_sizes() {
if (small_thumbnail_size == -1) {
- small_thumbnail_size = EditorNode::get_singleton()->get_theme_base()->get_theme_icon(SNAME("Object"), SNAME("EditorIcons"))->get_width(); // Kind of a workaround to retrieve the default icon size
+ // Kind of a workaround to retrieve the default icon size.
+ small_thumbnail_size = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Object"), EditorStringName(EditorIcons))->get_width();
}
}
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index cf6a8f1368..6744e79931 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -40,7 +40,7 @@
void EditorRunNative::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- remote_debug->set_icon(get_theme_icon(SNAME("PlayRemote"), SNAME("EditorIcons")));
+ remote_debug->set_icon(get_editor_theme_icon(SNAME("PlayRemote")));
} break;
case NOTIFICATION_PROCESS: {
diff --git a/editor/editor_script.cpp b/editor/editor_script.cpp
index 4e8c5ad8b5..e675b9621e 100644
--- a/editor/editor_script.cpp
+++ b/editor/editor_script.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
+#include "scene/main/node.h"
void EditorScript::add_root_node(Node *p_node) {
if (!EditorNode::get_singleton()) {
diff --git a/editor/editor_script.h b/editor/editor_script.h
index d7c813261d..72e7641df7 100644
--- a/editor/editor_script.h
+++ b/editor/editor_script.h
@@ -33,10 +33,10 @@
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
class EditorInterface;
class EditorNode;
+class Node;
class EditorScript : public RefCounted {
GDCLASS(EditorScript, RefCounted);
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index 92aa74dd9d..7bf88ba94f 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
if (p_property_path.findn(p_filter) != -1) {
@@ -264,8 +265,8 @@ void SectionedInspector::update_category_list() {
for (int i = 0; i < sc; i++) {
TreeItem *parent = section_map[metasection];
- //parent->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
- parent->set_custom_font(0, get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ //parent->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
+ parent->set_custom_font(0, get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
if (i > 0) {
metasection += "/" + sectionarr[i];
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 548492e488..85b59663c3 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/event_listener_line_edit.h"
#include "editor/input_event_configuration_dialog.h"
@@ -197,15 +198,15 @@ void EditorSettingsDialog::shortcut_input(const Ref<InputEvent> &p_event) {
}
void EditorSettingsDialog::_update_icons() {
- search_box->set_right_icon(shortcuts->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(shortcuts->get_editor_theme_icon(SNAME("Search")));
search_box->set_clear_button_enabled(true);
- shortcut_search_box->set_right_icon(shortcuts->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ shortcut_search_box->set_right_icon(shortcuts->get_editor_theme_icon(SNAME("Search")));
shortcut_search_box->set_clear_button_enabled(true);
- restart_close_button->set_icon(shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ restart_close_button->set_icon(shortcuts->get_editor_theme_icon(SNAME("Close")));
restart_container->add_theme_style_override("panel", shortcuts->get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- restart_icon->set_texture(shortcuts->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- restart_label->add_theme_color_override("font_color", shortcuts->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ restart_icon->set_texture(shortcuts->get_editor_theme_icon(SNAME("StatusWarning")));
+ restart_label->add_theme_color_override("font_color", shortcuts->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
}
void EditorSettingsDialog::_event_config_confirmed() {
@@ -303,11 +304,11 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S
}
if (p_allow_revert) {
- shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), SHORTCUT_REVERT);
+ shortcut_item->add_button(1, shortcuts->get_editor_theme_icon(SNAME("Reload")), SHORTCUT_REVERT);
}
- shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), SHORTCUT_ADD);
- shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE);
+ shortcut_item->add_button(1, shortcuts->get_editor_theme_icon(SNAME("Add")), SHORTCUT_ADD);
+ shortcut_item->add_button(1, shortcuts->get_editor_theme_icon(SNAME("Close")), SHORTCUT_ERASE);
shortcut_item->set_meta("is_action", p_is_action);
shortcut_item->set_meta("type", "shortcut");
@@ -326,11 +327,11 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S
event_item->set_text(0, shortcut_item->get_child_count() == 1 ? "Primary" : "");
event_item->set_text(1, ie->as_text());
- event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), SHORTCUT_EDIT);
- event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE);
+ event_item->add_button(1, shortcuts->get_editor_theme_icon(SNAME("Edit")), SHORTCUT_EDIT);
+ event_item->add_button(1, shortcuts->get_editor_theme_icon(SNAME("Close")), SHORTCUT_ERASE);
- event_item->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor")));
- event_item->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor")));
+ event_item->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor)));
+ event_item->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor)));
event_item->set_meta("is_action", p_is_action);
event_item->set_meta("type", "event");
@@ -399,8 +400,8 @@ void EditorSettingsDialog::_update_shortcuts() {
if (collapsed.has("Common")) {
common_section->set_collapsed(collapsed["Common"]);
}
- common_section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
- common_section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ common_section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
+ common_section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
// Get the action map for the editor, and add each item to the "Common" section.
for (const KeyValue<StringName, InputMap::Action> &E : InputMap::get_singleton()->get_action_map()) {
@@ -452,8 +453,8 @@ void EditorSettingsDialog::_update_shortcuts() {
section->set_tooltip_text(0, tooltip);
section->set_selectable(0, false);
section->set_selectable(1, false);
- section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
- section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
+ section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
if (collapsed.has(item_name)) {
section->set_collapsed(collapsed[item_name]);
diff --git a/modules/freetype/uwpdef.h b/editor/editor_string_names.cpp
index 52b839c9b4..bd31d32b2d 100644
--- a/modules/freetype/uwpdef.h
+++ b/editor/editor_string_names.cpp
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* uwpdef.h */
+/* editor_string_names.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef UWPDEF_H
-#define UWPDEF_H
+#include "editor_string_names.h"
-// "generic" is a reserved keyword in C++/CX code
-// this avoids the errors in the variable name from Freetype code
-#define generic freetype_generic
+EditorStringNames *EditorStringNames::singleton = nullptr;
-#endif // UWPDEF_H
+EditorStringNames::EditorStringNames() {
+ Editor = StaticCString::create("Editor");
+ EditorFonts = StaticCString::create("EditorFonts");
+ EditorIcons = StaticCString::create("EditorIcons");
+ EditorStyles = StaticCString::create("EditorStyles");
+}
diff --git a/platform/uwp/export/export.h b/editor/editor_string_names.h
index d2053e02b1..55d8a9c1ec 100644
--- a/platform/uwp/export/export.h
+++ b/editor/editor_string_names.h
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* export.h */
+/* editor_string_names.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef UWP_EXPORT_H
-#define UWP_EXPORT_H
+#ifndef EDITOR_STRING_NAMES_H
+#define EDITOR_STRING_NAMES_H
-void register_uwp_exporter_types();
-void register_uwp_exporter();
+#include "core/string/string_name.h"
-#endif // UWP_EXPORT_H
+class EditorStringNames {
+ static EditorStringNames *singleton;
+
+ EditorStringNames();
+
+public:
+ static void create() { singleton = memnew(EditorStringNames); }
+ static void free() {
+ memdelete(singleton);
+ singleton = nullptr;
+ }
+
+ _FORCE_INLINE_ static EditorStringNames *get_singleton() { return singleton; }
+
+ StringName Editor;
+ StringName EditorFonts;
+ StringName EditorIcons;
+ StringName EditorStyles;
+};
+
+#define EditorStringName(m_name) EditorStringNames::get_singleton()->m_name
+
+#endif // EDITOR_STRING_NAMES_H
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 9712297ec8..311e532e63 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_icons.gen.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/image_texture.h"
#include "scene/resources/style_box_flat.h"
#include "scene/resources/style_box_line.h"
@@ -313,9 +314,9 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
}
}
// These colors should be converted even if we are using a dark theme.
- const Color error_color = p_theme->get_color(SNAME("error_color"), SNAME("Editor"));
- const Color success_color = p_theme->get_color(SNAME("success_color"), SNAME("Editor"));
- const Color warning_color = p_theme->get_color(SNAME("warning_color"), SNAME("Editor"));
+ const Color error_color = p_theme->get_color(SNAME("error_color"), EditorStringName(Editor));
+ const Color success_color = p_theme->get_color(SNAME("success_color"), EditorStringName(Editor));
+ const Color warning_color = p_theme->get_color(SNAME("warning_color"), EditorStringName(Editor));
color_conversion_map[Color::html("#ff5f5f")] = error_color;
color_conversion_map[Color::html("#5fff97")] = success_color;
color_conversion_map[Color::html("#ffdd65")] = warning_color;
@@ -335,7 +336,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
HashMap<Color, Color> accent_color_map;
HashSet<StringName> accent_color_icons;
- const Color accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor"));
+ const Color accent_color = p_theme->get_color(SNAME("accent_color"), EditorStringName(Editor));
accent_color_map[Color::html("699ce8")] = accent_color;
if (accent_color.get_luminance() > 0.75) {
accent_color_map[Color::html("ffffff")] = Color(0.2, 0.2, 0.2);
@@ -369,7 +370,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
}
}
- p_theme->set_icon(editor_icon_name, SNAME("EditorIcons"), icon);
+ p_theme->set_icon(editor_icon_name, EditorStringName(EditorIcons), icon);
}
}
@@ -396,7 +397,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
}
}
- p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon);
+ p_theme->set_icon(editor_icons_names[index], EditorStringName(EditorIcons), icon);
}
} else {
const float scale = (float)p_thumb_size / 32.0 * EDSCALE;
@@ -419,7 +420,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
}
}
- p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon);
+ p_theme->set_icon(editor_icons_names[index], EditorStringName(EditorIcons), icon);
}
}
OS::get_singleton()->benchmark_end_measure("editor_register_and_generate_icons_" + String((p_only_thumbs ? "with_only_thumbs" : "all")));
@@ -572,38 +573,38 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color disabled_highlight_color = highlight_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5);
// Can't save single float in theme, so using Color.
- theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation));
- theme->set_color("accent_color", "Editor", accent_color);
- theme->set_color("highlight_color", "Editor", highlight_color);
- theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color);
- theme->set_color("base_color", "Editor", base_color);
- theme->set_color("dark_color_1", "Editor", dark_color_1);
- theme->set_color("dark_color_2", "Editor", dark_color_2);
- theme->set_color("dark_color_3", "Editor", dark_color_3);
- theme->set_color("contrast_color_1", "Editor", contrast_color_1);
- theme->set_color("contrast_color_2", "Editor", contrast_color_2);
- theme->set_color("box_selection_fill_color", "Editor", accent_color * Color(1, 1, 1, 0.3));
- theme->set_color("box_selection_stroke_color", "Editor", accent_color * Color(1, 1, 1, 0.8));
-
- theme->set_color("axis_x_color", "Editor", Color(0.96, 0.20, 0.32));
- theme->set_color("axis_y_color", "Editor", Color(0.53, 0.84, 0.01));
- theme->set_color("axis_z_color", "Editor", Color(0.16, 0.55, 0.96));
- theme->set_color("axis_w_color", "Editor", Color(0.55, 0.55, 0.55));
+ theme->set_color("icon_saturation", EditorStringName(Editor), Color(icon_saturation, icon_saturation, icon_saturation));
+ theme->set_color("accent_color", EditorStringName(Editor), accent_color);
+ theme->set_color("highlight_color", EditorStringName(Editor), highlight_color);
+ theme->set_color("disabled_highlight_color", EditorStringName(Editor), disabled_highlight_color);
+ theme->set_color("base_color", EditorStringName(Editor), base_color);
+ theme->set_color("dark_color_1", EditorStringName(Editor), dark_color_1);
+ theme->set_color("dark_color_2", EditorStringName(Editor), dark_color_2);
+ theme->set_color("dark_color_3", EditorStringName(Editor), dark_color_3);
+ theme->set_color("contrast_color_1", EditorStringName(Editor), contrast_color_1);
+ theme->set_color("contrast_color_2", EditorStringName(Editor), contrast_color_2);
+ theme->set_color("box_selection_fill_color", EditorStringName(Editor), accent_color * Color(1, 1, 1, 0.3));
+ theme->set_color("box_selection_stroke_color", EditorStringName(Editor), accent_color * Color(1, 1, 1, 0.8));
+
+ theme->set_color("axis_x_color", EditorStringName(Editor), Color(0.96, 0.20, 0.32));
+ theme->set_color("axis_y_color", EditorStringName(Editor), Color(0.53, 0.84, 0.01));
+ theme->set_color("axis_z_color", EditorStringName(Editor), Color(0.16, 0.55, 0.96));
+ theme->set_color("axis_w_color", EditorStringName(Editor), Color(0.55, 0.55, 0.55));
const float prop_color_saturation = accent_color.get_s() * 0.75;
const float prop_color_value = accent_color.get_v();
- theme->set_color("property_color_x", "Editor", Color().from_hsv(0.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
- theme->set_color("property_color_y", "Editor", Color().from_hsv(1.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
- theme->set_color("property_color_z", "Editor", Color().from_hsv(2.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
- theme->set_color("property_color_w", "Editor", Color().from_hsv(1.5 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
+ theme->set_color("property_color_x", EditorStringName(Editor), Color().from_hsv(0.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
+ theme->set_color("property_color_y", EditorStringName(Editor), Color().from_hsv(1.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
+ theme->set_color("property_color_z", EditorStringName(Editor), Color().from_hsv(2.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
+ theme->set_color("property_color_w", EditorStringName(Editor), Color().from_hsv(1.5 / 3.0 + 0.05, prop_color_saturation, prop_color_value));
- theme->set_color("font_color", "Editor", font_color);
- theme->set_color("highlighted_font_color", "Editor", font_hover_color);
- theme->set_color("disabled_font_color", "Editor", font_disabled_color);
- theme->set_color("readonly_font_color", "Editor", font_readonly_color);
+ theme->set_color("font_color", EditorStringName(Editor), font_color);
+ theme->set_color("highlighted_font_color", EditorStringName(Editor), font_hover_color);
+ theme->set_color("disabled_font_color", EditorStringName(Editor), font_disabled_color);
+ theme->set_color("readonly_font_color", EditorStringName(Editor), font_readonly_color);
- theme->set_color("mono_color", "Editor", mono_color);
+ theme->set_color("mono_color", EditorStringName(Editor), mono_color);
Color success_color = Color(0.45, 0.95, 0.5);
Color warning_color = Color(1, 0.87, 0.4);
@@ -619,27 +620,27 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
error_color = error_color.lerp(mono_color, 0.25);
}
- theme->set_color("success_color", "Editor", success_color);
- theme->set_color("warning_color", "Editor", warning_color);
- theme->set_color("error_color", "Editor", error_color);
- theme->set_color("property_color", "Editor", property_color);
- theme->set_color("readonly_color", "Editor", readonly_color);
+ theme->set_color("success_color", EditorStringName(Editor), success_color);
+ theme->set_color("warning_color", EditorStringName(Editor), warning_color);
+ theme->set_color("error_color", EditorStringName(Editor), error_color);
+ theme->set_color("property_color", EditorStringName(Editor), property_color);
+ theme->set_color("readonly_color", EditorStringName(Editor), readonly_color);
if (!dark_theme) {
- theme->set_color("highend_color", "Editor", Color::hex(0xad1128ff));
+ theme->set_color("highend_color", EditorStringName(Editor), Color::hex(0xad1128ff));
} else {
- theme->set_color("highend_color", "Editor", Color(1.0, 0.0, 0.0));
+ theme->set_color("highend_color", EditorStringName(Editor), Color(1.0, 0.0, 0.0));
}
const int thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size");
- theme->set_constant("scale", "Editor", EDSCALE);
- theme->set_constant("thumb_size", "Editor", thumb_size);
- theme->set_constant("class_icon_size", "Editor", 16 * EDSCALE);
- theme->set_constant("dark_theme", "Editor", dark_theme);
- theme->set_constant("color_picker_button_height", "Editor", 28 * EDSCALE);
- theme->set_constant("gizmo_handle_scale", "Editor", gizmo_handle_scale);
- theme->set_constant("window_border_margin", "Editor", 8);
- theme->set_constant("top_bar_separation", "Editor", 8 * EDSCALE);
+ theme->set_constant("scale", EditorStringName(Editor), EDSCALE);
+ theme->set_constant("thumb_size", EditorStringName(Editor), thumb_size);
+ theme->set_constant("class_icon_size", EditorStringName(Editor), 16 * EDSCALE);
+ theme->set_constant("dark_theme", EditorStringName(Editor), dark_theme);
+ theme->set_constant("color_picker_button_height", EditorStringName(Editor), 28 * EDSCALE);
+ theme->set_constant("gizmo_handle_scale", EditorStringName(Editor), gizmo_handle_scale);
+ theme->set_constant("window_border_margin", EditorStringName(Editor), 8);
+ theme->set_constant("top_bar_separation", EditorStringName(Editor), 8 * EDSCALE);
// Register editor icons.
// If the settings are comparable to the old theme, then just copy them over.
@@ -651,11 +652,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// That doesn't really work as expected, since theme constants are integers, and scales are floats.
// So this check will never work when changing between 100-199% values.
- const float prev_scale = (float)p_theme->get_constant(SNAME("scale"), SNAME("Editor"));
- const bool prev_dark_theme = (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor"));
- const Color prev_accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor"));
- const float prev_icon_saturation = p_theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r;
- const float prev_gizmo_handle_scale = (float)p_theme->get_constant(SNAME("gizmo_handle_scale"), SNAME("Editor"));
+ const float prev_scale = (float)p_theme->get_constant(SNAME("scale"), EditorStringName(Editor));
+ const bool prev_dark_theme = (bool)p_theme->get_constant(SNAME("dark_theme"), EditorStringName(Editor));
+ const Color prev_accent_color = p_theme->get_color(SNAME("accent_color"), EditorStringName(Editor));
+ const float prev_icon_saturation = p_theme->get_color(SNAME("icon_saturation"), EditorStringName(Editor)).r;
+ const float prev_gizmo_handle_scale = (float)p_theme->get_constant(SNAME("gizmo_handle_scale"), EditorStringName(Editor));
keep_old_icons = (Math::is_equal_approx(prev_scale, EDSCALE) &&
Math::is_equal_approx(prev_gizmo_handle_scale, gizmo_handle_scale) &&
@@ -663,7 +664,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
prev_accent_color == accent_color &&
prev_icon_saturation == icon_saturation);
- const double prev_thumb_size = (double)p_theme->get_constant(SNAME("thumb_size"), SNAME("Editor"));
+ const double prev_thumb_size = (double)p_theme->get_constant(SNAME("thumb_size"), EditorStringName(Editor));
regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size);
}
@@ -674,7 +675,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
if (keep_old_icons) {
for (int i = 0; i < editor_icons_count; i++) {
- theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons")));
+ theme->set_icon(editor_icons_names[i], EditorStringName(EditorIcons), p_theme->get_icon(editor_icons_names[i], EditorStringName(EditorIcons)));
}
} else {
editor_register_and_generate_icons(theme, dark_theme, icon_saturation, thumb_size, false);
@@ -815,27 +816,27 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Editor background
Color background_color_opaque = background_color;
background_color_opaque.a = 1.0;
- theme->set_color("background", "Editor", background_color_opaque);
- theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color_opaque, default_margin_size, default_margin_size, default_margin_size, default_margin_size));
+ theme->set_color("background", EditorStringName(Editor), background_color_opaque);
+ theme->set_stylebox("Background", EditorStringName(EditorStyles), make_flat_stylebox(background_color_opaque, default_margin_size, default_margin_size, default_margin_size, default_margin_size));
// Focus
- theme->set_stylebox("Focus", "EditorStyles", style_widget_focus);
+ theme->set_stylebox("Focus", EditorStringName(EditorStyles), style_widget_focus);
// Use a less opaque color to be less distracting for the 2D and 3D editor viewports.
Ref<StyleBoxFlat> style_widget_focus_viewport = style_widget_focus->duplicate();
style_widget_focus_viewport->set_border_color(accent_color * Color(1, 1, 1, 0.5));
- theme->set_stylebox("FocusViewport", "EditorStyles", style_widget_focus_viewport);
+ theme->set_stylebox("FocusViewport", EditorStringName(EditorStyles), style_widget_focus_viewport);
// Menu
Ref<StyleBoxFlat> style_menu = style_widget->duplicate();
style_menu->set_draw_center(false);
style_menu->set_border_width_all(0);
theme->set_stylebox("panel", "PanelContainer", style_menu);
- theme->set_stylebox("MenuPanel", "EditorStyles", style_menu);
+ theme->set_stylebox("MenuPanel", EditorStringName(EditorStyles), style_menu);
// CanvasItem Editor
Ref<StyleBoxFlat> style_canvas_editor_info = make_flat_stylebox(Color(0.0, 0.0, 0.0, 0.2));
style_canvas_editor_info->set_expand_margin_all(4 * EDSCALE);
- theme->set_stylebox("CanvasItemInfoOverlay", "EditorStyles", style_canvas_editor_info);
+ theme->set_stylebox("CanvasItemInfoOverlay", EditorStringName(EditorStyles), style_canvas_editor_info);
// 2D and 3D contextual toolbar.
// Use a custom stylebox to make contextual menu items stand out from the rest.
@@ -850,25 +851,25 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
toolbar_stylebox->set_border_color(accent_color);
toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
toolbar_stylebox->set_content_margin(SIDE_BOTTOM, 0);
- theme->set_stylebox("ContextualToolbar", "EditorStyles", toolbar_stylebox);
+ theme->set_stylebox("ContextualToolbar", EditorStringName(EditorStyles), toolbar_stylebox);
// Script Editor
- theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size));
- theme->set_stylebox("ScriptEditorPanelFloating", "EditorStyles", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_stylebox("ScriptEditorPanel", EditorStringName(EditorStyles), make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size));
+ theme->set_stylebox("ScriptEditorPanelFloating", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0));
- theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_stylebox("ScriptEditor", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0));
// Launch Pad and Play buttons
Ref<StyleBoxFlat> style_launch_pad = make_flat_stylebox(dark_color_1, 2 * EDSCALE, 0, 2 * EDSCALE, 0, corner_width);
style_launch_pad->set_corner_radius_all(corner_radius * EDSCALE);
- theme->set_stylebox("LaunchPadNormal", "EditorStyles", style_launch_pad);
+ theme->set_stylebox("LaunchPadNormal", EditorStringName(EditorStyles), style_launch_pad);
Ref<StyleBoxFlat> style_launch_pad_movie = style_launch_pad->duplicate();
style_launch_pad_movie->set_bg_color(accent_color * Color(1, 1, 1, 0.1));
style_launch_pad_movie->set_border_color(accent_color);
style_launch_pad_movie->set_border_width_all(Math::round(2 * EDSCALE));
- theme->set_stylebox("LaunchPadMovieMode", "EditorStyles", style_launch_pad_movie);
+ theme->set_stylebox("LaunchPadMovieMode", EditorStringName(EditorStyles), style_launch_pad_movie);
- theme->set_stylebox("MovieWriterButtonNormal", "EditorStyles", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_stylebox("MovieWriterButtonNormal", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0));
Ref<StyleBoxFlat> style_write_movie_button = style_widget_pressed->duplicate();
style_write_movie_button->set_bg_color(accent_color);
style_write_movie_button->set_corner_radius_all(corner_radius * EDSCALE);
@@ -877,7 +878,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_write_movie_button->set_content_margin(SIDE_LEFT, 0);
style_write_movie_button->set_content_margin(SIDE_RIGHT, 0);
style_write_movie_button->set_expand_margin(SIDE_RIGHT, 2 * EDSCALE);
- theme->set_stylebox("MovieWriterButtonPressed", "EditorStyles", style_write_movie_button);
+ theme->set_stylebox("MovieWriterButtonPressed", EditorStringName(EditorStyles), style_write_movie_button);
// MenuButton
theme->set_stylebox("normal", "MenuButton", style_menu);
@@ -894,7 +895,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("outline_size", "MenuButton", 0);
- theme->set_stylebox("MenuHover", "EditorStyles", style_widget_hover);
+ theme->set_stylebox("MenuHover", EditorStringName(EditorStyles), style_widget_hover);
// Buttons
theme->set_stylebox("normal", "Button", style_widget);
@@ -1061,7 +1062,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("icon_pressed_color", "OptionButton", icon_pressed_color);
theme->set_color("icon_disabled_color", "OptionButton", icon_disabled_color);
- theme->set_icon("arrow", "OptionButton", theme->get_icon(SNAME("GuiOptionArrow"), SNAME("EditorIcons")));
+ theme->set_icon("arrow", "OptionButton", theme->get_icon(SNAME("GuiOptionArrow"), EditorStringName(EditorIcons)));
theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE);
theme->set_constant("modulate_arrow", "OptionButton", true);
theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE);
@@ -1074,15 +1075,15 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("hover", "CheckButton", style_menu);
theme->set_stylebox("hover_pressed", "CheckButton", style_menu);
- theme->set_icon("checked", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons")));
- theme->set_icon("checked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons")));
- theme->set_icon("unchecked", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), SNAME("EditorIcons")));
- theme->set_icon("unchecked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), SNAME("EditorIcons")));
+ theme->set_icon("checked", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), EditorStringName(EditorIcons)));
+ theme->set_icon("checked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), EditorStringName(EditorIcons)));
- theme->set_icon("checked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), SNAME("EditorIcons")));
- theme->set_icon("checked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), SNAME("EditorIcons")));
- theme->set_icon("unchecked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), SNAME("EditorIcons")));
- theme->set_icon("unchecked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), SNAME("EditorIcons")));
+ theme->set_icon("checked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), EditorStringName(EditorIcons)));
+ theme->set_icon("checked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), EditorStringName(EditorIcons)));
theme->set_color("font_color", "CheckButton", font_color);
theme->set_color("font_hover_color", "CheckButton", font_hover_color);
@@ -1111,14 +1112,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("disabled", "CheckBox", sb_checkbox);
theme->set_stylebox("hover", "CheckBox", sb_checkbox);
theme->set_stylebox("hover_pressed", "CheckBox", sb_checkbox);
- theme->set_icon("checked", "CheckBox", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons")));
- theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons")));
- theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons")));
- theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons")));
- theme->set_icon("checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("radio_checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("radio_unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons")));
+ theme->set_icon("checked", "CheckBox", theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons)));
theme->set_color("font_color", "CheckBox", font_color);
theme->set_color("font_hover_color", "CheckBox", font_hover_color);
@@ -1171,19 +1172,19 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color);
theme->set_color("font_separator_color", "PopupMenu", font_disabled_color);
theme->set_color("font_outline_color", "PopupMenu", font_outline_color);
- theme->set_icon("checked", "PopupMenu", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons")));
- theme->set_icon("unchecked", "PopupMenu", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons")));
- theme->set_icon("radio_checked", "PopupMenu", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons")));
- theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons")));
- theme->set_icon("checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("radio_checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("radio_unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons")));
- theme->set_icon("submenu", "PopupMenu", theme->get_icon(SNAME("ArrowRight"), SNAME("EditorIcons")));
- theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon(SNAME("ArrowLeft"), SNAME("EditorIcons")));
- theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")));
- theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")));
- theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityXray"), SNAME("EditorIcons")));
+ theme->set_icon("checked", "PopupMenu", theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked", "PopupMenu", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_checked", "PopupMenu", theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("radio_unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons)));
+ theme->set_icon("submenu", "PopupMenu", theme->get_icon(SNAME("ArrowRight"), EditorStringName(EditorIcons)));
+ theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon(SNAME("ArrowLeft"), EditorStringName(EditorIcons)));
+ theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityHidden"), EditorStringName(EditorIcons)));
+ theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(EditorIcons)));
+ theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityXray"), EditorStringName(EditorIcons)));
// Force the v_separation to be even so that the spacing on top and bottom is even.
// If the vsep is odd and cannot be split into 2 even groups (of pixels), then it will be lopsided.
@@ -1212,7 +1213,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
sub_inspector_bg->set_corner_radius(CORNER_TOP_LEFT, 0);
sub_inspector_bg->set_corner_radius(CORNER_TOP_RIGHT, 0);
- theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg);
+ theme->set_stylebox("sub_inspector_bg" + itos(i), EditorStringName(Editor), sub_inspector_bg);
// EditorProperty background while it has a sub-inspector open.
Ref<StyleBoxFlat> bg_color = make_flat_stylebox(si_base_color * Color(0.7, 0.7, 0.7, 0.8), 0, 0, 0, 0, corner_radius);
@@ -1220,10 +1221,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
bg_color->set_corner_radius(CORNER_BOTTOM_LEFT, 0);
bg_color->set_corner_radius(CORNER_BOTTOM_RIGHT, 0);
- theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color);
+ theme->set_stylebox("sub_inspector_property_bg" + itos(i), EditorStringName(Editor), bg_color);
}
- theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1));
+ theme->set_color("sub_inspector_property_color", EditorStringName(Editor), dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1));
// EditorSpinSlider.
theme->set_color("label_color", "EditorSpinSlider", font_color);
@@ -1269,7 +1270,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("indent_box", "EditorInspectorSection", inspector_indent_style);
theme->set_constant("indent_size", "EditorInspectorSection", 6.0 * EDSCALE);
- theme->set_constant("inspector_margin", "Editor", 12 * EDSCALE);
+ theme->set_constant("inspector_margin", EditorStringName(Editor), 12 * EDSCALE);
// Tree & ItemList background
Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate();
@@ -1286,14 +1287,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("panel", "EditorValidationPanel", style_tree_bg);
// Tree
- theme->set_icon("checked", "Tree", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons")));
- theme->set_icon("indeterminate", "Tree", theme->get_icon(SNAME("GuiIndeterminate"), SNAME("EditorIcons")));
- theme->set_icon("unchecked", "Tree", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons")));
- theme->set_icon("arrow", "Tree", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")));
- theme->set_icon("arrow_collapsed", "Tree", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")));
- theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon(SNAME("GuiTreeArrowLeft"), SNAME("EditorIcons")));
- theme->set_icon("updown", "Tree", theme->get_icon(SNAME("GuiTreeUpdown"), SNAME("EditorIcons")));
- theme->set_icon("select_arrow", "Tree", theme->get_icon(SNAME("GuiDropdown"), SNAME("EditorIcons")));
+ theme->set_icon("checked", "Tree", theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("indeterminate", "Tree", theme->get_icon(SNAME("GuiIndeterminate"), EditorStringName(EditorIcons)));
+ theme->set_icon("unchecked", "Tree", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons)));
+ theme->set_icon("arrow", "Tree", theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
+ theme->set_icon("arrow_collapsed", "Tree", theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
+ theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons)));
+ theme->set_icon("updown", "Tree", theme->get_icon(SNAME("GuiTreeUpdown"), EditorStringName(EditorIcons)));
+ theme->set_icon("select_arrow", "Tree", theme->get_icon(SNAME("GuiDropdown"), EditorStringName(EditorIcons)));
theme->set_stylebox("focus", "Tree", style_widget_focus);
theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
@@ -1376,9 +1377,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color prop_category_color = dark_color_1.lerp(mono_color, 0.12);
Color prop_section_color = dark_color_1.lerp(mono_color, 0.09);
Color prop_subsection_color = dark_color_1.lerp(mono_color, 0.06);
- theme->set_color("prop_category", "Editor", prop_category_color);
- theme->set_color("prop_section", "Editor", prop_section_color);
- theme->set_color("prop_subsection", "Editor", prop_subsection_color);
+ theme->set_color("prop_category", EditorStringName(Editor), prop_category_color);
+ theme->set_color("prop_section", EditorStringName(Editor), prop_section_color);
+ theme->set_color("prop_subsection", EditorStringName(Editor), prop_subsection_color);
theme->set_color("drop_position_color", "Tree", accent_color);
// EditorInspectorCategory
@@ -1452,19 +1453,19 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_outline_color", "TabBar", font_outline_color);
theme->set_color("drop_mark_color", "TabContainer", tab_highlight);
theme->set_color("drop_mark_color", "TabBar", tab_highlight);
- theme->set_icon("menu", "TabContainer", theme->get_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons")));
- theme->set_icon("menu_highlight", "TabContainer", theme->get_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- theme->set_icon("close", "TabBar", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons")));
- theme->set_icon("increment", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons")));
- theme->set_icon("decrement", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons")));
- theme->set_icon("increment", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons")));
- theme->set_icon("decrement", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons")));
- theme->set_icon("increment_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons")));
- theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons")));
- theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons")));
- theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons")));
- theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons")));
- theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons")));
+ theme->set_icon("menu", "TabContainer", theme->get_icon(SNAME("GuiTabMenu"), EditorStringName(EditorIcons)));
+ theme->set_icon("menu_highlight", "TabContainer", theme->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("close", "TabBar", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons)));
+ theme->set_icon("increment", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons)));
+ theme->set_icon("decrement", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons)));
+ theme->set_icon("increment", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons)));
+ theme->set_icon("decrement", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons)));
+ theme->set_icon("increment_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons)));
+ theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons)));
theme->set_constant("side_margin", "TabContainer", 0);
theme->set_constant("outline_size", "TabContainer", 0);
theme->set_constant("h_separation", "TabBar", 4 * EDSCALE);
@@ -1484,7 +1485,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Bottom panel.
Ref<StyleBoxFlat> style_bottom_panel = style_content_panel->duplicate();
style_bottom_panel->set_corner_radius_all(corner_radius * EDSCALE);
- theme->set_stylebox("BottomPanel", "EditorStyles", style_bottom_panel);
+ theme->set_stylebox("BottomPanel", EditorStringName(EditorStyles), style_bottom_panel);
// TabContainerOdd can be used on tabs against the base color background (e.g. nested tabs).
theme->set_type_variation("TabContainerOdd", "TabContainer");
@@ -1500,20 +1501,20 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// This stylebox is used in 3d and 2d viewports (no borders).
Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate();
style_content_panel_vp->set_content_margin_individual(border_width * 2, default_margin_size * EDSCALE, border_width * 2, border_width * 2);
- theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
+ theme->set_stylebox("Content", EditorStringName(EditorStyles), style_content_panel_vp);
// This stylebox is used by preview tabs in the Theme Editor.
Ref<StyleBoxFlat> style_theme_preview_tab = style_tab_selected_odd->duplicate();
style_theme_preview_tab->set_expand_margin(SIDE_BOTTOM, 5 * EDSCALE);
- theme->set_stylebox("ThemeEditorPreviewFG", "EditorStyles", style_theme_preview_tab);
+ theme->set_stylebox("ThemeEditorPreviewFG", EditorStringName(EditorStyles), style_theme_preview_tab);
Ref<StyleBoxFlat> style_theme_preview_bg_tab = style_tab_unselected->duplicate();
style_theme_preview_bg_tab->set_expand_margin(SIDE_BOTTOM, 2 * EDSCALE);
- theme->set_stylebox("ThemeEditorPreviewBG", "EditorStyles", style_theme_preview_bg_tab);
+ theme->set_stylebox("ThemeEditorPreviewBG", EditorStringName(EditorStyles), style_theme_preview_bg_tab);
Ref<StyleBoxFlat> style_texture_region_bg = style_tree_bg->duplicate();
style_texture_region_bg->set_content_margin_all(0);
- theme->set_stylebox("TextureRegionPreviewBG", "EditorStyles", style_texture_region_bg);
- theme->set_stylebox("TextureRegionPreviewFG", "EditorStyles", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_stylebox("TextureRegionPreviewBG", EditorStringName(EditorStyles), style_texture_region_bg);
+ theme->set_stylebox("TextureRegionPreviewFG", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0));
// Separators
theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width)));
@@ -1523,13 +1524,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<StyleBoxFlat> style_panel_debugger = style_content_panel->duplicate();
style_panel_debugger->set_border_width(SIDE_BOTTOM, 0);
- theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger);
+ theme->set_stylebox("DebuggerPanel", EditorStringName(EditorStyles), style_panel_debugger);
Ref<StyleBoxFlat> style_panel_invisible_top = style_content_panel->duplicate();
int stylebox_offset = theme->get_font(SNAME("tab_selected"), SNAME("TabContainer"))->get_height(theme->get_font_size(SNAME("tab_selected"), SNAME("TabContainer"))) + theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainer"))->get_minimum_size().height + theme->get_stylebox(SNAME("panel"), SNAME("TabContainer"))->get_content_margin(SIDE_TOP);
style_panel_invisible_top->set_expand_margin(SIDE_TOP, -stylebox_offset);
style_panel_invisible_top->set_content_margin(SIDE_TOP, 0);
- theme->set_stylebox("BottomPanelDebuggerOverride", "EditorStyles", style_panel_invisible_top);
+ theme->set_stylebox("BottomPanelDebuggerOverride", EditorStringName(EditorStyles), style_panel_invisible_top);
// LineEdit
@@ -1559,7 +1560,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("normal", "LineEdit", style_line_edit);
theme->set_stylebox("focus", "LineEdit", style_widget_focus);
theme->set_stylebox("read_only", "LineEdit", style_line_edit_disabled);
- theme->set_icon("clear", "LineEdit", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons")));
+ theme->set_icon("clear", "LineEdit", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons)));
theme->set_color("font_color", "LineEdit", font_color);
theme->set_color("font_selected_color", "LineEdit", mono_color);
theme->set_color("font_uneditable_color", "LineEdit", font_readonly_color);
@@ -1578,8 +1579,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("normal", "TextEdit", style_line_edit);
theme->set_stylebox("focus", "TextEdit", style_widget_focus);
theme->set_stylebox("read_only", "TextEdit", style_line_edit_disabled);
- theme->set_icon("tab", "TextEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons")));
- theme->set_icon("space", "TextEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons")));
+ theme->set_icon("tab", "TextEdit", theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons)));
+ theme->set_icon("space", "TextEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons)));
theme->set_color("font_color", "TextEdit", font_color);
theme->set_color("font_readonly_color", "TextEdit", font_readonly_color);
theme->set_color("font_placeholder_color", "TextEdit", font_placeholder_color);
@@ -1592,10 +1593,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("outline_size", "TextEdit", 0);
theme->set_constant("caret_width", "TextEdit", 1);
- theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons")));
- theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons")));
- theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons")));
- theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons")));
+ theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons)));
+ theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons)));
+ theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons)));
+ theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons)));
theme->set_constant("separation", "SplitContainer", default_margin_size * 2 * EDSCALE);
theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE);
@@ -1646,14 +1647,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("embedded_unfocused_border", "Window", style_window);
theme->set_color("title_color", "Window", font_color);
- theme->set_icon("close", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons")));
- theme->set_icon("close_pressed", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons")));
+ theme->set_icon("close", "Window", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons)));
+ theme->set_icon("close_pressed", "Window", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons)));
theme->set_constant("close_h_offset", "Window", 22 * EDSCALE);
theme->set_constant("close_v_offset", "Window", 20 * EDSCALE);
theme->set_constant("title_height", "Window", 24 * EDSCALE);
theme->set_constant("resize_margin", "Window", 4 * EDSCALE);
- theme->set_font("title_font", "Window", theme->get_font(SNAME("title"), SNAME("EditorFonts")));
- theme->set_font_size("title_font_size", "Window", theme->get_font_size(SNAME("title_size"), SNAME("EditorFonts")));
+ theme->set_font("title_font", "Window", theme->get_font(SNAME("title"), EditorStringName(EditorFonts)));
+ theme->set_font_size("title_font_size", "Window", theme->get_font_size(SNAME("title_size"), EditorStringName(EditorFonts)));
// Complex window (currently only Editor Settings and Project Settings)
Ref<StyleBoxFlat> style_complex_window = style_window->duplicate();
@@ -1673,12 +1674,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
if (increase_scrollbar_touch_area) {
theme->set_stylebox("scroll", "HScrollBar", make_line_stylebox(separator_color, 50));
} else {
- theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
}
- theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
- theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 1, 1, 1, 1));
- theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
- theme->set_stylebox("grabber_pressed", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 1, 1, 1, 1));
+ theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1));
+ theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("grabber_pressed", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1));
theme->set_icon("increment", "HScrollBar", empty_icon);
theme->set_icon("increment_highlight", "HScrollBar", empty_icon);
@@ -1691,12 +1692,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
if (increase_scrollbar_touch_area) {
theme->set_stylebox("scroll", "VScrollBar", make_line_stylebox(separator_color, 50, 1, 1, true));
} else {
- theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
}
- theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
- theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 1, 1, 1, 1));
- theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 1, 1, 1, 1));
- theme->set_stylebox("grabber_pressed", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 1, 1, 1, 1));
+ theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1));
+ theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1));
+ theme->set_stylebox("grabber_pressed", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1));
theme->set_icon("increment", "VScrollBar", empty_icon);
theme->set_icon("increment_highlight", "VScrollBar", empty_icon);
@@ -1706,8 +1707,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("decrement_pressed", "VScrollBar", empty_icon);
// HSlider
- theme->set_icon("grabber_highlight", "HSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons")));
- theme->set_icon("grabber", "HSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons")));
+ theme->set_icon("grabber_highlight", "HSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons)));
+ theme->set_icon("grabber", "HSlider", theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons)));
theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width));
theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width));
theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2));
@@ -1715,8 +1716,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("grabber_offset", "HSlider", 0);
// VSlider
- theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons")));
- theme->set_icon("grabber_highlight", "VSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons")));
+ theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons)));
+ theme->set_icon("grabber_highlight", "VSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons)));
theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width));
theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width));
theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0));
@@ -1764,7 +1765,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Panel
theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width));
- theme->set_stylebox("PanelForeground", "EditorStyles", style_default);
+ theme->set_stylebox("PanelForeground", EditorStringName(EditorStyles), style_default);
// Label
theme->set_stylebox("normal", "Label", style_empty);
@@ -1816,12 +1817,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_type_variation("ControlEditorPopupPanel", "PopupPanel");
// SpinBox
- theme->set_icon("updown", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdown"), SNAME("EditorIcons")));
- theme->set_icon("updown_disabled", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), SNAME("EditorIcons")));
+ theme->set_icon("updown", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdown"), EditorStringName(EditorIcons)));
+ theme->set_icon("updown_disabled", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), EditorStringName(EditorIcons)));
// ProgressBar
- theme->set_stylebox("background", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0));
- theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1));
+ theme->set_stylebox("background", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), EditorStringName(EditorIcons)), 4, 4, 4, 4, 0, 0, 0, 0));
+ theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 2, 1, 2, 1));
theme->set_color("font_color", "ProgressBar", font_color);
theme->set_color("font_outline_color", "ProgressBar", font_outline_color);
theme->set_constant("outline_size", "ProgressBar", 0);
@@ -1829,23 +1830,23 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// GraphEdit
theme->set_stylebox("panel", "GraphEdit", style_tree_bg);
if (dark_theme) {
- theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.15));
- theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.07));
+ theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.1));
+ theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.05));
} else {
theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15));
theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07));
}
- theme->set_color("selection_fill", "GraphEdit", theme->get_color(SNAME("box_selection_fill_color"), SNAME("Editor")));
- theme->set_color("selection_stroke", "GraphEdit", theme->get_color(SNAME("box_selection_stroke_color"), SNAME("Editor")));
+ theme->set_color("selection_fill", "GraphEdit", theme->get_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
+ theme->set_color("selection_stroke", "GraphEdit", theme->get_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)));
theme->set_color("activity", "GraphEdit", accent_color);
- theme->set_icon("zoom_out", "GraphEdit", theme->get_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- theme->set_icon("zoom_in", "GraphEdit", theme->get_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
- theme->set_icon("zoom_reset", "GraphEdit", theme->get_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
- theme->set_icon("grid_toggle", "GraphEdit", theme->get_icon(SNAME("GridToggle"), SNAME("EditorIcons")));
- theme->set_icon("minimap_toggle", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), SNAME("EditorIcons")));
- theme->set_icon("snapping_toggle", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), SNAME("EditorIcons")));
+ theme->set_icon("zoom_out", "GraphEdit", theme->get_icon(SNAME("ZoomLess"), EditorStringName(EditorIcons)));
+ theme->set_icon("zoom_in", "GraphEdit", theme->get_icon(SNAME("ZoomMore"), EditorStringName(EditorIcons)));
+ theme->set_icon("zoom_reset", "GraphEdit", theme->get_icon(SNAME("ZoomReset"), EditorStringName(EditorIcons)));
+ theme->set_icon("grid_toggle", "GraphEdit", theme->get_icon(SNAME("GridToggle"), EditorStringName(EditorIcons)));
+ theme->set_icon("minimap_toggle", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), EditorStringName(EditorIcons)));
+ theme->set_icon("snapping_toggle", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), EditorStringName(EditorIcons)));
+ theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), EditorStringName(EditorIcons)));
// GraphEditMinimap
Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
@@ -1865,6 +1866,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_minimap_node = make_flat_stylebox(Color(0, 0, 0), 0, 0, 0, 0);
}
style_minimap_camera->set_border_width_all(1);
+ style_minimap_node->set_anti_aliased(false);
theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera);
theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node);
@@ -1874,42 +1876,47 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
} else {
minimap_resizer_color = Color(0, 0, 0, 0.65);
}
- theme->set_icon("resizer", "GraphEditMinimap", theme->get_icon(SNAME("GuiResizerTopLeft"), SNAME("EditorIcons")));
+ theme->set_icon("resizer", "GraphEditMinimap", theme->get_icon(SNAME("GuiResizerTopLeft"), EditorStringName(EditorIcons)));
theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color);
// GraphNode
+
+ const int gn_margin_top = 2;
const int gn_margin_side = 2;
const int gn_margin_bottom = 2;
- // StateMachine
- const int sm_margin_side = 10;
-
Color graphnode_bg = dark_color_3;
if (!dark_theme) {
graphnode_bg = prop_section_color;
}
+ const Color graph_node_selected_border_color = graphnode_bg.lerp(accent_color, 0.275);
+
+ const Color graphnode_frame_bg = graphnode_bg.lerp(style_tree_bg->get_bg_color(), 0.3);
+
+ Ref<StyleBoxFlat> graphn_sb_panel = make_flat_stylebox(graphnode_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, corner_width);
+ graphn_sb_panel->set_border_width_all(border_width);
+ graphn_sb_panel->set_border_color(graphnode_bg);
+ graphn_sb_panel->set_corner_radius_individual(0, 0, corner_radius * EDSCALE, corner_radius * EDSCALE);
+ graphn_sb_panel->set_expand_margin(SIDE_TOP, 17 * EDSCALE);
- Ref<StyleBoxFlat> graphsb = make_flat_stylebox(graphnode_bg.lerp(style_tree_bg->get_bg_color(), 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
- graphsb->set_border_width_all(border_width);
- graphsb->set_border_color(graphnode_bg);
- Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 1), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
- graphsbselected->set_border_width_all(2 * EDSCALE + border_width);
- graphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.6));
- Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
- graphsbcomment->set_border_width_all(border_width);
- graphsbcomment->set_border_color(graphnode_bg);
- Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.4), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width);
- graphsbcommentselected->set_border_width_all(border_width);
- graphsbcommentselected->set_border_color(graphnode_bg);
- Ref<StyleBoxFlat> graphsbbreakpoint = graphsbselected->duplicate();
- graphsbbreakpoint->set_draw_center(false);
- graphsbbreakpoint->set_border_color(warning_color);
- graphsbbreakpoint->set_shadow_color(warning_color * Color(1.0, 1.0, 1.0, 0.1));
- Ref<StyleBoxFlat> graphsbposition = graphsbselected->duplicate();
- graphsbposition->set_draw_center(false);
- graphsbposition->set_border_color(error_color);
- graphsbposition->set_shadow_color(error_color * Color(1.0, 1.0, 1.0, 0.2));
- Ref<StyleBoxEmpty> graphsbslot = make_empty_stylebox(12, 0, 12, 0);
+ Ref<StyleBoxFlat> graphn_sb_panel_selected = make_flat_stylebox(graphnode_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, corner_width);
+ graphn_sb_panel_selected->set_border_width_all(2 * EDSCALE + border_width);
+ graphn_sb_panel_selected->set_border_color(graph_node_selected_border_color);
+ graphn_sb_panel_selected->set_corner_radius_individual(0, 0, corner_radius * EDSCALE, corner_radius * EDSCALE);
+ graphn_sb_panel_selected->set_expand_margin(SIDE_TOP, 17 * EDSCALE);
+
+ const int gn_titlebar_margin_side = 12;
+ Ref<StyleBoxFlat> graphn_sb_titlebar = make_flat_stylebox(graphnode_bg, gn_titlebar_margin_side, gn_margin_top, gn_titlebar_margin_side, 0, corner_width);
+ graphn_sb_titlebar->set_expand_margin(SIDE_TOP, 2 * EDSCALE);
+ graphn_sb_titlebar->set_corner_radius_individual(corner_radius * EDSCALE, corner_radius * EDSCALE, 0, 0);
+
+ Ref<StyleBoxFlat> graphn_sb_titlebar_selected = make_flat_stylebox(graph_node_selected_border_color, gn_titlebar_margin_side, gn_margin_top, gn_titlebar_margin_side, 0, corner_width);
+ graphn_sb_titlebar_selected->set_corner_radius_individual(corner_radius * EDSCALE, corner_radius * EDSCALE, 0, 0);
+ graphn_sb_titlebar_selected->set_expand_margin(SIDE_TOP, 2 * EDSCALE);
+ Ref<StyleBoxEmpty> graphn_sb_slot = make_empty_stylebox(12, 0, 12, 0);
+
+ // StateMachine.
+ const int sm_margin_side = 10;
Ref<StyleBoxFlat> smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), sm_margin_side, 24, sm_margin_side, gn_margin_bottom, corner_width);
smgraphsb->set_border_width_all(border_width);
smgraphsb->set_border_color(graphnode_bg);
@@ -1919,56 +1926,53 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
smgraphsbselected->set_shadow_size(8 * EDSCALE);
smgraphsbselected->set_shadow_color(shadow_color);
- graphsb->set_border_width(SIDE_TOP, 24 * EDSCALE);
- graphsbselected->set_border_width(SIDE_TOP, 24 * EDSCALE);
- graphsbcomment->set_border_width(SIDE_TOP, 24 * EDSCALE);
- graphsbcommentselected->set_border_width(SIDE_TOP, 24 * EDSCALE);
-
- graphsb->set_corner_detail(corner_radius * EDSCALE);
- graphsbselected->set_corner_detail(corner_radius * EDSCALE);
- graphsbcomment->set_corner_detail(corner_radius * EDSCALE);
- graphsbcommentselected->set_corner_detail(corner_radius * EDSCALE);
-
- theme->set_stylebox("frame", "GraphNode", graphsb);
- theme->set_stylebox("selected_frame", "GraphNode", graphsbselected);
- theme->set_stylebox("breakpoint", "GraphNode", graphsbbreakpoint);
- theme->set_stylebox("position", "GraphNode", graphsbposition);
- theme->set_stylebox("slot", "GraphNode", graphsbslot);
- theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb);
- theme->set_stylebox("state_machine_selected_frame", "GraphNode", smgraphsbselected);
+ theme->set_stylebox("panel", "GraphElement", graphn_sb_panel);
+ theme->set_stylebox("panel_selected", "GraphElement", graphn_sb_panel_selected);
+ theme->set_stylebox("titlebar", "GraphElement", graphn_sb_titlebar);
+ theme->set_stylebox("titlebar_selected", "GraphElement", graphn_sb_titlebar_selected);
+
+ // GraphNode's title Label.
+ theme->set_type_variation("GraphNodeTitleLabel", "Label");
+
+ theme->set_stylebox("normal", "GraphNodeTitleLabel", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_color("font_color", "GraphNodeTitleLabel", font_color);
+ theme->set_constant("line_spacing", "GraphNodeTitleLabel", 3 * EDSCALE);
+
+ Color graphnode_decoration_color = dark_color_1.inverted();
+
+ theme->set_color("resizer_color", "GraphElement", graphnode_decoration_color);
+ theme->set_icon("resizer", "GraphElement", theme->get_icon(SNAME("GuiResizer"), EditorStringName(EditorIcons)));
- Color node_decoration_color = dark_color_1.inverted();
- theme->set_color("title_color", "GraphNode", node_decoration_color);
- node_decoration_color.a = 0.7;
- theme->set_color("close_color", "GraphNode", node_decoration_color);
- theme->set_color("resizer_color", "GraphNode", node_decoration_color);
-
- theme->set_constant("port_offset", "GraphNode", 0);
- theme->set_constant("title_h_offset", "GraphNode", 12 * EDSCALE);
- theme->set_constant("title_offset", "GraphNode", 21 * EDSCALE);
- theme->set_constant("close_h_offset", "GraphNode", -2 * EDSCALE);
- theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE);
+ // GraphNode.
+ theme->set_stylebox("panel", "GraphNode", graphn_sb_panel);
+ theme->set_stylebox("panel_selected", "GraphNode", graphn_sb_panel_selected);
+ theme->set_stylebox("titlebar", "GraphNode", graphn_sb_titlebar);
+ theme->set_stylebox("titlebar_selected", "GraphNode", graphn_sb_titlebar_selected);
+ theme->set_stylebox("slot", "GraphNode", graphn_sb_slot);
+
+ theme->set_color("resizer_color", "GraphNode", graphnode_decoration_color);
+
+ theme->set_constant("port_h_offset", "GraphNode", 0);
theme->set_constant("separation", "GraphNode", 1 * EDSCALE);
- theme->set_icon("close", "GraphNode", theme->get_icon(SNAME("GuiCloseCustomizable"), SNAME("EditorIcons")));
- theme->set_icon("resizer", "GraphNode", theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons")));
- Ref<ImageTexture> port_icon = theme->get_icon(SNAME("GuiGraphNodePort"), SNAME("EditorIcons"));
+ Ref<ImageTexture> port_icon = theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons));
// The true size is 24x24 This is necessary for sharp port icons at high zoom levels in GraphEdit (up to ~200%).
port_icon->set_size_override(Size2(12, 12));
theme->set_icon("port", "GraphNode", port_icon);
- theme->set_font("title_font", "GraphNode", theme->get_font(SNAME("main_bold_msdf"), SNAME("EditorFonts")));
+ theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb);
+ theme->set_stylebox("state_machine_selected_frame", "GraphNode", smgraphsbselected);
// GridContainer
theme->set_constant("v_separation", "GridContainer", Math::round(widget_default_margin.y - 2 * EDSCALE));
// FileDialog
- theme->set_icon("folder", "FileDialog", theme->get_icon(SNAME("Folder"), SNAME("EditorIcons")));
- theme->set_icon("parent_folder", "FileDialog", theme->get_icon(SNAME("ArrowUp"), SNAME("EditorIcons")));
- theme->set_icon("back_folder", "FileDialog", theme->get_icon(SNAME("Back"), SNAME("EditorIcons")));
- theme->set_icon("forward_folder", "FileDialog", theme->get_icon(SNAME("Forward"), SNAME("EditorIcons")));
- theme->set_icon("reload", "FileDialog", theme->get_icon(SNAME("Reload"), SNAME("EditorIcons")));
- theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")));
+ theme->set_icon("folder", "FileDialog", theme->get_icon(SNAME("Folder"), EditorStringName(EditorIcons)));
+ theme->set_icon("parent_folder", "FileDialog", theme->get_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons)));
+ theme->set_icon("back_folder", "FileDialog", theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons)));
+ theme->set_icon("forward_folder", "FileDialog", theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons)));
+ theme->set_icon("reload", "FileDialog", theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons)));
+ theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(EditorIcons)));
// Use a different color for folder icons to make them easier to distinguish from files.
// On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color.
theme->set_color("folder_icon_color", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7));
@@ -1981,36 +1985,36 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE);
theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE);
theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
- theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
- theme->set_icon("shape_circle", "ColorPicker", theme->get_icon(SNAME("PickerShapeCircle"), SNAME("EditorIcons")));
- theme->set_icon("shape_rect", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangle"), SNAME("EditorIcons")));
- theme->set_icon("shape_rect_wheel", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangleWheel"), SNAME("EditorIcons")));
- theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), SNAME("EditorIcons")));
- theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")));
- theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons")));
- theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon(SNAME("ColorPickerBarArrow"), SNAME("EditorIcons")));
- theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon(SNAME("PickerCursor"), SNAME("EditorIcons")));
+ theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons)));
+ theme->set_icon("shape_circle", "ColorPicker", theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons)));
+ theme->set_icon("shape_rect", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangle"), EditorStringName(EditorIcons)));
+ theme->set_icon("shape_rect_wheel", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangleWheel"), EditorStringName(EditorIcons)));
+ theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), EditorStringName(EditorIcons)));
+ theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
+ theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons)));
+ theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons)));
+ theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons)));
// ColorPickerButton
- theme->set_icon("bg", "ColorPickerButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")));
+ theme->set_icon("bg", "ColorPickerButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
// ColorPresetButton
Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2);
theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb);
- theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")));
- theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons")));
+ theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
+ theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons)));
// Information on 3D viewport
Ref<StyleBoxFlat> style_info_3d_viewport = style_default->duplicate();
style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5));
style_info_3d_viewport->set_border_width_all(0);
- theme->set_stylebox("Information3dViewport", "EditorStyles", style_info_3d_viewport);
+ theme->set_stylebox("Information3dViewport", EditorStringName(EditorStyles), style_info_3d_viewport);
// Asset Library.
theme->set_stylebox("bg", "AssetLib", style_empty);
theme->set_stylebox("panel", "AssetLib", style_content_panel);
theme->set_color("status_color", "AssetLib", Color(0.5, 0.5, 0.5));
- theme->set_icon("dismiss", "AssetLib", theme->get_icon(SNAME("Close"), SNAME("EditorIcons")));
+ theme->set_icon("dismiss", "AssetLib", theme->get_icon(SNAME("Close"), EditorStringName(EditorIcons)));
// Theme editor.
theme->set_color("preview_picker_overlay_color", "ThemeEditor", Color(0.1, 0.1, 0.1, 0.25));
@@ -2030,7 +2034,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<StyleBoxFlat> style_dictionary_add_item = make_flat_stylebox(prop_subsection_color, 0, 4, 0, 4, corner_radius);
style_dictionary_add_item->set_expand_margin(SIDE_LEFT, 4 * EDSCALE);
style_dictionary_add_item->set_expand_margin(SIDE_RIGHT, 4 * EDSCALE);
- theme->set_stylebox("DictionaryAddItem", "EditorStyles", style_dictionary_add_item);
+ theme->set_stylebox("DictionaryAddItem", EditorStringName(EditorStyles), style_dictionary_add_item);
Ref<StyleBoxEmpty> vshader_label_style = make_empty_stylebox(2, 1, 2, 1);
theme->set_stylebox("label_style", "VShaderEditor", vshader_label_style);
@@ -2131,20 +2135,20 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
}
// Now theme is loaded, apply it to CodeEdit.
- theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts")));
- theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts")));
+ theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), EditorStringName(EditorFonts)));
+ theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), EditorStringName(EditorFonts)));
Ref<StyleBoxFlat> code_edit_stylebox = make_flat_stylebox(EDITOR_GET("text_editor/theme/highlighting/background_color"), widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y, corner_radius);
theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox);
theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox);
theme->set_stylebox("focus", "CodeEdit", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
- theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons")));
- theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons")));
- theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), SNAME("EditorIcons")));
- theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), SNAME("EditorIcons")));
- theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), SNAME("EditorIcons")));
- theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons")));
+ theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons)));
+ theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons)));
+ theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), EditorStringName(EditorIcons)));
+ theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), EditorStringName(EditorIcons)));
+ theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), EditorStringName(EditorIcons)));
+ theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), EditorStringName(EditorIcons)));
theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing"));
diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h
index 2291bd8a70..78dc726c52 100644
--- a/editor/editor_translation_parser.h
+++ b/editor/editor_translation_parser.h
@@ -34,7 +34,6 @@
#include "core/error/error_list.h"
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
#include "core/variant/typed_array.h"
class EditorTranslationParserPlugin : public RefCounted {
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index 814baeb37c..84f2cf9281 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -33,9 +33,9 @@
#include "core/object/class_db.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language_extension.h"
#include "core/string/ustring.h"
#include "core/variant/type_info.h"
+#include "core/variant/typed_array.h"
class EditorVCSInterface : public Object {
GDCLASS(EditorVCSInterface, Object)
diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp
index b9e182d780..e51808c78c 100644
--- a/editor/event_listener_line_edit.cpp
+++ b/editor/event_listener_line_edit.cpp
@@ -215,7 +215,7 @@ void EventListenerLineEdit::_notification(int p_what) {
connect("text_changed", callable_mp(this, &EventListenerLineEdit::_on_text_changed));
connect("focus_entered", callable_mp(this, &EventListenerLineEdit::_on_focus));
connect("focus_exited", callable_mp(this, &EventListenerLineEdit::_on_unfocus));
- set_right_icon(get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")));
+ set_right_icon(get_editor_theme_icon(SNAME("Keyboard")));
set_clear_button_enabled(true);
} break;
}
diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp
index 208451acce..d65f10c441 100644
--- a/editor/export/editor_export_platform.cpp
+++ b/editor/export/editor_export_platform.cpp
@@ -42,6 +42,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor_export_plugin.h"
@@ -72,12 +73,12 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
p_log->add_text(" - ");
if (p_err == OK) {
if (get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed with warnings."));
has_messages = true;
} else {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusSuccess")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed successfully."));
if (msg_count > 0) {
@@ -85,7 +86,7 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
}
}
} else {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusError")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Failed."));
has_messages = true;
@@ -103,15 +104,15 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
switch (msg.msg_type) {
case EditorExportPlatform::EXPORT_MESSAGE_INFO: {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.6);
+ color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6);
} break;
case EditorExportPlatform::EXPORT_MESSAGE_WARNING: {
- icon = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"));
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
+ icon = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Warning"));
+ color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
} break;
case EditorExportPlatform::EXPORT_MESSAGE_ERROR: {
- icon = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Error"), SNAME("EditorIcons"));
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ icon = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Error"));
+ color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
} break;
default:
break;
@@ -293,9 +294,9 @@ Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
ERR_FAIL_COND_V(theme.is_null(), Ref<ImageTexture>());
if (EditorNode::get_singleton()->get_main_screen_control()->is_layout_rtl()) {
- return theme->get_icon(SNAME("PlayBackwards"), SNAME("EditorIcons"));
+ return theme->get_icon(SNAME("PlayBackwards"), EditorStringName(EditorIcons));
} else {
- return theme->get_icon(SNAME("Play"), SNAME("EditorIcons"));
+ return theme->get_icon(SNAME("Play"), EditorStringName(EditorIcons));
}
}
@@ -1971,5 +1972,9 @@ Error EditorExportPlatform::ssh_push_to_remote(const String &p_host, const Strin
return OK;
}
+void EditorExportPlatform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_os_name"), &EditorExportPlatform::get_os_name);
+}
+
EditorExportPlatform::EditorExportPlatform() {
}
diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h
index 5f5702026c..0b922cc6c8 100644
--- a/editor/export/editor_export_platform.h
+++ b/editor/export/editor_export_platform.h
@@ -49,6 +49,9 @@ const String ENV_SCRIPT_ENCRYPTION_KEY = "GODOT_SCRIPT_ENCRYPTION_KEY";
class EditorExportPlatform : public RefCounted {
GDCLASS(EditorExportPlatform, RefCounted);
+protected:
+ static void _bind_methods();
+
public:
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so);
diff --git a/editor/export/export_template_manager.cpp b/editor/export/export_template_manager.cpp
index 42e4b6f6f6..3a034c8dcc 100644
--- a/editor/export/export_template_manager.cpp
+++ b/editor/export/export_template_manager.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/progress_dialog.h"
#include "scene/gui/file_dialog.h"
#include "scene/gui/menu_button.h"
@@ -109,8 +110,8 @@ void ExportTemplateManager::_update_template_status() {
TreeItem *ti = installed_table->create_item(installed_root);
ti->set_text(0, version_string);
- ti->add_button(0, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), OPEN_TEMPLATE_FOLDER, false, TTR("Open the folder containing these templates."));
- ti->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), UNINSTALL_TEMPLATE, false, TTR("Uninstall these templates."));
+ ti->add_button(0, get_editor_theme_icon(SNAME("Folder")), OPEN_TEMPLATE_FOLDER, false, TTR("Open the folder containing these templates."));
+ ti->add_button(0, get_editor_theme_icon(SNAME("Remove")), UNINSTALL_TEMPLATE, false, TTR("Uninstall these templates."));
}
}
@@ -360,7 +361,7 @@ void ExportTemplateManager::_set_current_progress_status(const String &p_status,
download_progress_label->set_text(p_status);
if (p_error) {
- download_progress_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ download_progress_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} else {
download_progress_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Label")));
}
@@ -755,11 +756,11 @@ void ExportTemplateManager::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- current_value->add_theme_font_override("font", get_theme_font(SNAME("main"), SNAME("EditorFonts")));
- current_missing_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- current_installed_label->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ current_value->add_theme_font_override("font", get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
+ current_missing_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ current_installed_label->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
- mirror_options_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ mirror_options_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index f723a20368..24a9e2ae36 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/import/resource_importer_texture_settings.h"
@@ -66,7 +67,7 @@ void ProjectExportTextureFormatError::_bind_methods() {
void ProjectExportTextureFormatError::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- texture_format_error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ texture_format_error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
}
}
@@ -90,8 +91,8 @@ ProjectExportTextureFormatError::ProjectExportTextureFormatError() {
}
void ProjectExportDialog::_theme_changed() {
- duplicate_preset->set_icon(presets->get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")));
- delete_preset->set_icon(presets->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
+ delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
}
void ProjectExportDialog::_notification(int p_what) {
@@ -103,8 +104,8 @@ void ProjectExportDialog::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
- duplicate_preset->set_icon(presets->get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")));
- delete_preset->set_icon(presets->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
+ delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
connect("confirmed", callable_mp(this, &ProjectExportDialog::_export_pck_zip));
_update_export_all();
} break;
@@ -812,7 +813,7 @@ void ProjectExportDialog::_setup_item_for_file_mode(TreeItem *p_item, EditorExpo
p_item->set_cell_mode(1, TreeItem::CELL_MODE_STRING);
p_item->set_editable(1, false);
p_item->set_selectable(1, false);
- p_item->set_custom_color(1, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ p_item->set_custom_color(1, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
} else {
p_item->set_checked(0, true);
p_item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
@@ -1327,7 +1328,7 @@ ProjectExportDialog::ProjectExportDialog() {
script_key->connect("text_changed", callable_mp(this, &ProjectExportDialog::_script_encryption_key_changed));
script_key_error = memnew(Label);
script_key_error->set_text(String::utf8("• ") + TTR("Invalid Encryption Key (must be 64 hexadecimal characters long)"));
- script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
sec_vb->add_margin_child(TTR("Encryption Key (256-bits as hexadecimal):"), script_key);
sec_vb->add_child(script_key_error);
sections->add_child(sec_vb);
@@ -1412,12 +1413,12 @@ ProjectExportDialog::ProjectExportDialog() {
export_error = memnew(Label);
main_vb->add_child(export_error);
export_error->hide();
- export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
export_warning = memnew(Label);
main_vb->add_child(export_warning);
export_warning->hide();
- export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
export_templates_error = memnew(HBoxContainer);
main_vb->add_child(export_templates_error);
@@ -1425,7 +1426,7 @@ ProjectExportDialog::ProjectExportDialog() {
Label *export_error2 = memnew(Label);
export_templates_error->add_child(export_error2);
- export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
export_error2->set_text(String::utf8("• ") + TTR("Export templates for this platform are missing:") + " ");
result_dialog = memnew(AcceptDialog);
diff --git a/editor/fbx_importer_manager.cpp b/editor/fbx_importer_manager.cpp
index 87f2d596e8..5922cbf312 100644
--- a/editor/fbx_importer_manager.cpp
+++ b/editor/fbx_importer_manager.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/link_button.h"
void FBXImporterManager::_notification(int p_what) {
@@ -88,11 +89,11 @@ void FBXImporterManager::_validate_path(const String &p_path) {
if (success) {
path_status->set_text(TTR("FBX2glTF executable is valid."));
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
get_ok_button()->set_disabled(false);
} else {
path_status->set_text(error);
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
get_ok_button()->set_disabled(true);
}
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 3c010112ad..606137cb76 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -44,6 +44,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_dir_dialog.h"
#include "editor/gui/editor_scene_tabs.h"
#include "editor/import/resource_importer_scene.h"
@@ -170,9 +171,9 @@ FileSystemDock *FileSystemDock::singleton = nullptr;
Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) {
Ref<Texture2D> file_icon;
if (!p_is_valid) {
- file_icon = get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ file_icon = get_editor_theme_icon(SNAME("ImportFail"));
} else {
- file_icon = (has_theme_icon(p_file_type, SNAME("EditorIcons"))) ? get_theme_icon(p_file_type, SNAME("EditorIcons")) : get_theme_icon(SNAME("File"), SNAME("EditorIcons"));
+ file_icon = (has_theme_icon(p_file_type, EditorStringName(EditorIcons))) ? get_editor_theme_icon(p_file_type) : get_editor_theme_icon(SNAME("File"));
}
return file_icon;
}
@@ -212,7 +213,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
subdirectory_item->set_text(0, dname);
subdirectory_item->set_structured_text_bidi_override(0, TextServer::STRUCTURED_TEXT_FILE);
- subdirectory_item->set_icon(0, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ subdirectory_item->set_icon(0, get_editor_theme_icon(SNAME("Folder")));
subdirectory_item->set_selectable(0, true);
subdirectory_item->set_metadata(0, lpath);
if (!p_select_in_favorites && (current_path == lpath || ((display_mode == DISPLAY_MODE_SPLIT) && current_path.get_base_dir() == lpath))) {
@@ -294,7 +295,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
file_item->set_as_cursor(0);
}
if (main_scene == file_metadata) {
- file_item->set_custom_color(0, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ file_item->set_custom_color(0, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
}
Array udata;
udata.push_back(tree_update_id);
@@ -362,7 +363,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
// Handles the favorites.
TreeItem *favorites_item = tree->create_item(root);
- favorites_item->set_icon(0, get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+ favorites_item->set_icon(0, get_editor_theme_icon(SNAME("Favorites")));
favorites_item->set_text(0, TTR("Favorites:"));
favorites_item->set_metadata(0, "Favorites");
favorites_item->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0);
@@ -382,7 +383,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
EditorSettings::get_singleton()->set_favorites(favorite_paths);
}
- Ref<Texture2D> folder_icon = get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"));
+ Ref<Texture2D> folder_icon = get_editor_theme_icon(SNAME("Folder"));
const Color default_folder_color = get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog"));
for (int i = 0; i < favorite_paths.size(); i++) {
@@ -409,7 +410,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
if (dir) {
icon = _get_tree_item_icon(dir->get_file_import_is_valid(index), dir->get_file_type(index));
} else {
- icon = get_theme_icon(SNAME("File"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("File"));
}
color = Color(1, 1, 1);
}
@@ -498,28 +499,28 @@ void FileSystemDock::_notification(int p_what) {
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &FileSystemDock::_fs_changed));
EditorResourcePreview::get_singleton()->connect("preview_invalidated", callable_mp(this, &FileSystemDock::_preview_invalidated));
- button_reload->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
- button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons")));
+ button_reload->set_icon(get_editor_theme_icon(SNAME("Reload")));
+ button_toggle_display_mode->set_icon(get_editor_theme_icon(SNAME("Panels2")));
button_file_list_display_mode->connect("pressed", callable_mp(this, &FileSystemDock::_toggle_file_display));
files->connect("item_activated", callable_mp(this, &FileSystemDock::_file_list_activate_file));
button_hist_next->connect("pressed", callable_mp(this, &FileSystemDock::_fw_history));
button_hist_prev->connect("pressed", callable_mp(this, &FileSystemDock::_bw_history));
- tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ tree_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
tree_search_box->set_clear_button_enabled(true);
- tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
+ tree_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
- file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ file_list_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
file_list_search_box->set_clear_button_enabled(true);
- file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
+ file_list_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
if (is_layout_rtl()) {
- button_hist_next->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Back")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Forward")));
} else {
- button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Back")));
}
file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option));
tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option));
@@ -585,28 +586,28 @@ void FileSystemDock::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
// Update icons.
- button_reload->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
- button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons")));
+ button_reload->set_icon(get_editor_theme_icon(SNAME("Reload")));
+ button_toggle_display_mode->set_icon(get_editor_theme_icon(SNAME("Panels2")));
if (is_layout_rtl()) {
- button_hist_next->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Back")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Forward")));
} else {
- button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Back")));
}
if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) {
- button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons")));
+ button_file_list_display_mode->set_icon(get_editor_theme_icon(SNAME("FileThumbnail")));
} else {
- button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileList"), SNAME("EditorIcons")));
+ button_file_list_display_mode->set_icon(get_editor_theme_icon(SNAME("FileList")));
}
- tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ tree_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
tree_search_box->set_clear_button_enabled(true);
- tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
+ tree_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
- file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ file_list_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
file_list_search_box->set_clear_button_enabled(true);
- file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
+ file_list_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
// Update editor dark theme & always show folders states from editor settings, redraw if needed.
bool do_redraw = false;
@@ -775,11 +776,11 @@ void FileSystemDock::_toggle_file_display() {
void FileSystemDock::_set_file_display(bool p_active) {
if (p_active) {
file_list_display_mode = FILE_LIST_DISPLAY_LIST;
- button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons")));
+ button_file_list_display_mode->set_icon(get_editor_theme_icon(SNAME("FileThumbnail")));
button_file_list_display_mode->set_tooltip_text(TTR("View items as a grid of thumbnails."));
} else {
file_list_display_mode = FILE_LIST_DISPLAY_THUMBNAILS;
- button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileList"), SNAME("EditorIcons")));
+ button_file_list_display_mode->set_icon(get_editor_theme_icon(SNAME("FileList")));
button_file_list_display_mode->set_tooltip_text(TTR("View items as a list."));
}
@@ -922,13 +923,13 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
if (thumbnail_size < 64) {
- folder_thumbnail = get_theme_icon(SNAME("FolderMediumThumb"), SNAME("EditorIcons"));
- file_thumbnail = get_theme_icon(SNAME("FileMediumThumb"), SNAME("EditorIcons"));
- file_thumbnail_broken = get_theme_icon(SNAME("FileDeadMediumThumb"), SNAME("EditorIcons"));
+ folder_thumbnail = get_editor_theme_icon(SNAME("FolderMediumThumb"));
+ file_thumbnail = get_editor_theme_icon(SNAME("FileMediumThumb"));
+ file_thumbnail_broken = get_editor_theme_icon(SNAME("FileDeadMediumThumb"));
} else {
- folder_thumbnail = get_theme_icon(SNAME("FolderBigThumb"), SNAME("EditorIcons"));
- file_thumbnail = get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons"));
- file_thumbnail_broken = get_theme_icon(SNAME("FileDeadBigThumb"), SNAME("EditorIcons"));
+ folder_thumbnail = get_editor_theme_icon(SNAME("FolderBigThumb"));
+ file_thumbnail = get_editor_theme_icon(SNAME("FileBigThumb"));
+ file_thumbnail_broken = get_editor_theme_icon(SNAME("FileDeadBigThumb"));
}
} else {
// No thumbnails.
@@ -1087,10 +1088,10 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
// Select the icons.
if (!finfo->import_broken) {
- type_icon = (has_theme_icon(ftype, SNAME("EditorIcons"))) ? get_theme_icon(ftype, SNAME("EditorIcons")) : get_theme_icon(SNAME("Object"), SNAME("EditorIcons"));
+ type_icon = (has_theme_icon(ftype, EditorStringName(EditorIcons))) ? get_editor_theme_icon(ftype) : get_editor_theme_icon(SNAME("Object"));
big_icon = file_thumbnail;
} else {
- type_icon = get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ type_icon = get_editor_theme_icon(SNAME("ImportFail"));
big_icon = file_thumbnail_broken;
tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually.");
}
@@ -1110,7 +1111,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
if (fpath == main_scene) {
- files->set_item_custom_fg_color(item_index, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ files->set_item_custom_fg_color(item_index, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
}
// Generate the preview.
@@ -1746,7 +1747,7 @@ void FileSystemDock::_rename_operation_confirm() {
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
rename_error = true;
- } else if (new_name.begins_with(".")) {
+ } else if (new_name[0] == '.') {
EditorNode::get_singleton()->show_warning(TTR("This filename begins with a dot rendering the file invisible to the editor.\nIf you want to rename it anyway, use your operating system's file manager."));
rename_error = true;
} else if (to_rename.is_file && to_rename.path.get_extension() != new_name.get_extension()) {
@@ -1776,7 +1777,7 @@ void FileSystemDock::_rename_operation_confirm() {
// Present a more user friendly warning for name conflict.
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
+#if defined(WINDOWS_ENABLED)
// Workaround case insensitivity on Windows.
if ((da->file_exists(new_path) || da->dir_exists(new_path)) && new_path.to_lower() != old_path.to_lower()) {
#else
@@ -1818,6 +1819,9 @@ void FileSystemDock::_duplicate_operation_confirm() {
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
return;
+ } else if (new_name[0] == '.') {
+ EditorNode::get_singleton()->show_warning(TTR("Name begins with a dot."));
+ return;
}
String base_dir = to_duplicate.path.get_base_dir();
@@ -1930,7 +1934,6 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop
if (!to_move[i].is_file) {
new_path = new_path.path_join(old_path.trim_suffix("/").get_file());
- print_line(new_path);
}
if (old_path != new_path) {
@@ -2794,6 +2797,12 @@ void FileSystemDock::_folder_color_index_pressed(int p_index, PopupMenu *p_menu)
}
}
+ if (!ProjectSettings::get_singleton()->has_setting("file_customization/folder_colors")) {
+ ProjectSettings::get_singleton()->set_setting("file_customization/folder_colors", assigned_folder_colors);
+ } else if (assigned_folder_colors.is_empty()) {
+ ProjectSettings::get_singleton()->set_setting("file_customization/folder_colors", Variant());
+ }
+
ProjectSettings::get_singleton()->save();
_update_tree(get_uncollapsed_paths());
@@ -2844,18 +2853,18 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
if (all_files) {
if (all_files_scenes) {
if (filenames.size() == 1) {
- p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scene"), FILE_OPEN);
- p_popup->add_icon_item(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), TTR("New Inherited Scene"), FILE_INHERIT);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open Scene"), FILE_OPEN);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("CreateNewSceneFrom")), TTR("New Inherited Scene"), FILE_INHERIT);
if (GLOBAL_GET("application/run/main_scene") != filenames[0]) {
- p_popup->add_icon_item(get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons")), TTR("Set As Main Scene"), FILE_MAIN_SCENE);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("PlayScene")), TTR("Set As Main Scene"), FILE_MAIN_SCENE);
}
} else {
- p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scenes"), FILE_OPEN);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open Scenes"), FILE_OPEN);
}
- p_popup->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate"), FILE_INSTANTIATE);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Instance")), TTR("Instantiate"), FILE_INSTANTIATE);
p_popup->add_separator();
} else if (filenames.size() == 1) {
- p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open"), FILE_OPEN);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open"), FILE_OPEN);
p_popup->add_separator();
}
@@ -2873,22 +2882,22 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
p_popup->add_child(new_menu);
p_popup->add_submenu_item(TTR("Create New"), "New", FILE_NEW);
- p_popup->set_item_icon(p_popup->get_item_index(FILE_NEW), get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ p_popup->set_item_icon(p_popup->get_item_index(FILE_NEW), get_editor_theme_icon(SNAME("Add")));
- new_menu->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("Folder..."), FILE_NEW_FOLDER);
- new_menu->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("Scene..."), FILE_NEW_SCENE);
- new_menu->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("Script..."), FILE_NEW_SCRIPT);
- new_menu->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("Resource..."), FILE_NEW_RESOURCE);
- new_menu->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("TextFile..."), FILE_NEW_TEXTFILE);
+ new_menu->add_icon_item(get_editor_theme_icon(SNAME("Folder")), TTR("Folder..."), FILE_NEW_FOLDER);
+ new_menu->add_icon_item(get_editor_theme_icon(SNAME("PackedScene")), TTR("Scene..."), FILE_NEW_SCENE);
+ new_menu->add_icon_item(get_editor_theme_icon(SNAME("Script")), TTR("Script..."), FILE_NEW_SCRIPT);
+ new_menu->add_icon_item(get_editor_theme_icon(SNAME("Object")), TTR("Resource..."), FILE_NEW_RESOURCE);
+ new_menu->add_icon_item(get_editor_theme_icon(SNAME("TextFile")), TTR("TextFile..."), FILE_NEW_TEXTFILE);
p_popup->add_separator();
}
if (all_folders && foldernames.size() > 0) {
- p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Expand Folder"), FILE_OPEN);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Expand Folder"), FILE_OPEN);
if (foldernames.size() == 1) {
- p_popup->add_icon_item(get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")), TTR("Expand Hierarchy"), FOLDER_EXPAND_ALL);
- p_popup->add_icon_item(get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")), TTR("Collapse Hierarchy"), FOLDER_COLLAPSE_ALL);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("GuiTreeArrowDown")), TTR("Expand Hierarchy"), FOLDER_EXPAND_ALL);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("GuiTreeArrowRight")), TTR("Collapse Hierarchy"), FOLDER_COLLAPSE_ALL);
}
p_popup->add_separator();
@@ -2900,14 +2909,14 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
p_popup->add_child(folder_colors_menu);
p_popup->add_submenu_item(TTR("Set Folder Color..."), "FolderColor");
- p_popup->set_item_icon(-1, get_theme_icon(SNAME("CanvasItem"), SNAME("EditorIcons")));
+ p_popup->set_item_icon(-1, get_editor_theme_icon(SNAME("CanvasItem")));
- folder_colors_menu->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("Default (Reset)"));
+ folder_colors_menu->add_icon_item(get_editor_theme_icon(SNAME("Folder")), TTR("Default (Reset)"));
folder_colors_menu->set_item_icon_modulate(0, get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog")));
folder_colors_menu->add_separator();
for (const KeyValue<String, Color> &E : folder_colors) {
- folder_colors_menu->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR(E.key.capitalize()));
+ folder_colors_menu->add_icon_item(get_editor_theme_icon(SNAME("Folder")), TTR(E.key.capitalize()));
folder_colors_menu->set_item_icon_modulate(-1, editor_is_dark_theme ? E.value : E.value * 2);
folder_colors_menu->set_item_metadata(-1, E.key);
@@ -2916,29 +2925,29 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
}
if (p_paths.size() == 1) {
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionCopy")), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH);
if (ResourceLoader::get_resource_uid(p_paths[0]) != ResourceUID::INVALID_ID) {
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/copy_uid"), FILE_COPY_UID);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Instance")), ED_GET_SHORTCUT("filesystem_dock/copy_uid"), FILE_COPY_UID);
}
if (p_paths[0] != "res://") {
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME);
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Rename")), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Duplicate")), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE);
}
}
if (p_paths.size() > 1 || p_paths[0] != "res://") {
- p_popup->add_icon_item(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")), TTR("Move/Duplicate To..."), FILE_MOVE);
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/delete"), FILE_REMOVE);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("MoveUp")), TTR("Move/Duplicate To..."), FILE_MOVE);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Remove")), ED_GET_SHORTCUT("filesystem_dock/delete"), FILE_REMOVE);
}
p_popup->add_separator();
if (p_paths.size() >= 1) {
if (!all_favorites) {
- p_popup->add_icon_item(get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")), TTR("Add to Favorites"), FILE_ADD_FAVORITE);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Favorites")), TTR("Add to Favorites"), FILE_ADD_FAVORITE);
}
if (!all_not_favorites) {
- p_popup->add_icon_item(get_theme_icon(SNAME("NonFavorite"), SNAME("EditorIcons")), TTR("Remove from Favorites"), FILE_REMOVE_FAVORITE);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("NonFavorite")), TTR("Remove from Favorites"), FILE_REMOVE_FAVORITE);
}
{
@@ -2968,7 +2977,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
}
if (resource_valid) {
- p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Reimport"), FILE_REIMPORT);
+ p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Reimport"), FILE_REIMPORT);
}
}
}
@@ -2982,10 +2991,10 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
// Opening the system file manager is not supported on the Android and web editors.
const bool is_directory = fpath.ends_with("/");
const String item_text = is_directory ? TTR("Open in File Manager") : TTR("Show in File Manager");
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Filesystem")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
p_popup->set_item_text(p_popup->get_item_index(FILE_SHOW_IN_EXPLORER), item_text);
if (!is_directory) {
- p_popup->add_icon_shortcut(get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/open_in_external_program"), FILE_OPEN_EXTERNAL);
+ p_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("ExternalLink")), ED_GET_SHORTCUT("filesystem_dock/open_in_external_program"), FILE_OPEN_EXTERNAL);
}
#endif
@@ -3022,15 +3031,15 @@ void FileSystemDock::_tree_empty_click(const Vector2 &p_pos, MouseButton p_butto
current_path = "res://";
tree_popup->clear();
tree_popup->reset_size();
- tree_popup->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("New Folder..."), FILE_NEW_FOLDER);
- tree_popup->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("New Scene..."), FILE_NEW_SCENE);
- tree_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT);
- tree_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE);
- tree_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
+ tree_popup->add_icon_item(get_editor_theme_icon(SNAME("Folder")), TTR("New Folder..."), FILE_NEW_FOLDER);
+ tree_popup->add_icon_item(get_editor_theme_icon(SNAME("PackedScene")), TTR("New Scene..."), FILE_NEW_SCENE);
+ tree_popup->add_icon_item(get_editor_theme_icon(SNAME("Script")), TTR("New Script..."), FILE_NEW_SCRIPT);
+ tree_popup->add_icon_item(get_editor_theme_icon(SNAME("Object")), TTR("New Resource..."), FILE_NEW_RESOURCE);
+ tree_popup->add_icon_item(get_editor_theme_icon(SNAME("TextFile")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
// Opening the system file manager is not supported on the Android and web editors.
tree_popup->add_separator();
- tree_popup->add_icon_shortcut(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
+ tree_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Filesystem")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
#endif
tree_popup->set_position(tree->get_screen_position() + p_pos);
@@ -3086,13 +3095,13 @@ void FileSystemDock::_file_list_empty_clicked(const Vector2 &p_pos, MouseButton
file_list_popup->clear();
file_list_popup->reset_size();
- file_list_popup->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("New Folder..."), FILE_NEW_FOLDER);
- file_list_popup->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("New Scene..."), FILE_NEW_SCENE);
- file_list_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT);
- file_list_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE);
- file_list_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
+ file_list_popup->add_icon_item(get_editor_theme_icon(SNAME("Folder")), TTR("New Folder..."), FILE_NEW_FOLDER);
+ file_list_popup->add_icon_item(get_editor_theme_icon(SNAME("PackedScene")), TTR("New Scene..."), FILE_NEW_SCENE);
+ file_list_popup->add_icon_item(get_editor_theme_icon(SNAME("Script")), TTR("New Script..."), FILE_NEW_SCRIPT);
+ file_list_popup->add_icon_item(get_editor_theme_icon(SNAME("Object")), TTR("New Resource..."), FILE_NEW_RESOURCE);
+ file_list_popup->add_icon_item(get_editor_theme_icon(SNAME("TextFile")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
file_list_popup->add_separator();
- file_list_popup->add_icon_shortcut(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
+ file_list_popup->add_icon_shortcut(get_editor_theme_icon(SNAME("Filesystem")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER);
file_list_popup->set_position(files->get_screen_position() + p_pos);
file_list_popup->reset_size();
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 4c341a6d52..3e580e5f08 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -35,6 +35,7 @@
#include "core/os/os.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/check_box.h"
@@ -685,10 +686,10 @@ void FindInFilesPanel::stop_search() {
void FindInFilesPanel::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- _search_text_label->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts")));
- _search_text_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts")));
- _results_display->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts")));
- _results_display->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts")));
+ _search_text_label->add_theme_font_override("font", get_theme_font(SNAME("source"), EditorStringName(EditorFonts)));
+ _search_text_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("source_size"), EditorStringName(EditorFonts)));
+ _results_display->add_theme_font_override("font", get_theme_font(SNAME("source"), EditorStringName(EditorFonts)));
+ _results_display->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("source_size"), EditorStringName(EditorFonts)));
// Rebuild search tree.
if (!_finder->get_search_text().is_empty()) {
@@ -776,8 +777,8 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
match_rect.position.y += 1 * EDSCALE;
match_rect.size.y -= 2 * EDSCALE;
- _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.33), false, 2.0);
- _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.17), true);
+ _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.33), false, 2.0);
+ _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.17), true);
// Text is drawn by Tree already.
}
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 37b4654113..09e5fe790d 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/scene_tree_dock.h"
@@ -116,7 +117,7 @@ void GroupDialog::_load_nodes(Node *p_current) {
if (!can_edit(p_current, selected_group)) {
node->set_selectable(0, false);
- node->set_custom_color(0, groups->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ node->set_custom_color(0, groups->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
}
}
@@ -210,8 +211,8 @@ void GroupDialog::_add_group(String p_name) {
TreeItem *new_group = groups->create_item(groups_root);
new_group->set_text(0, name);
- new_group->add_button(0, groups->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP);
- new_group->add_button(0, groups->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP);
+ new_group->add_button(0, groups->get_editor_theme_icon(SNAME("Remove")), DELETE_GROUP);
+ new_group->add_button(0, groups->get_editor_theme_icon(SNAME("ActionCopy")), COPY_GROUP);
new_group->set_editable(0, true);
new_group->select(0);
groups->ensure_cursor_is_visible();
@@ -393,16 +394,16 @@ void GroupDialog::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
if (is_layout_rtl()) {
- add_button->set_icon(groups->get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- remove_button->set_icon(groups->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
+ add_button->set_icon(groups->get_editor_theme_icon(SNAME("Back")));
+ remove_button->set_icon(groups->get_editor_theme_icon(SNAME("Forward")));
} else {
- add_button->set_icon(groups->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- remove_button->set_icon(groups->get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
+ add_button->set_icon(groups->get_editor_theme_icon(SNAME("Forward")));
+ remove_button->set_icon(groups->get_editor_theme_icon(SNAME("Back")));
}
- add_filter->set_right_icon(groups->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ add_filter->set_right_icon(groups->get_editor_theme_icon(SNAME("Search")));
add_filter->set_clear_button_enabled(true);
- remove_filter->set_right_icon(groups->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ remove_filter->set_right_icon(groups->get_editor_theme_icon(SNAME("Search")));
remove_filter->set_clear_button_enabled(true);
} break;
}
@@ -761,8 +762,8 @@ void GroupsEditor::update_tree() {
item->set_text(0, gi.name);
item->set_editable(0, true);
if (can_be_deleted) {
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP);
- item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP);
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), DELETE_GROUP);
+ item->add_button(0, get_editor_theme_icon(SNAME("ActionCopy")), COPY_GROUP);
} else {
item->set_selectable(0, false);
}
diff --git a/editor/gui/editor_dir_dialog.cpp b/editor/gui/editor_dir_dialog.cpp
index 9da592d639..fada434a03 100644
--- a/editor/gui/editor_dir_dialog.cpp
+++ b/editor/gui/editor_dir_dialog.cpp
@@ -46,7 +46,7 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p
String path = p_dir->get_path();
p_item->set_metadata(0, p_dir->get_path());
- p_item->set_icon(0, tree->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ p_item->set_icon(0, tree->get_editor_theme_icon(SNAME("Folder")));
p_item->set_icon_modulate(0, tree->get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog")));
if (!p_item->get_parent()) {
diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp
index cf701f1e63..fd1e63b904 100644
--- a/editor/gui/editor_file_dialog.cpp
+++ b/editor/gui/editor_file_dialog.cpp
@@ -75,37 +75,37 @@ VBoxContainer *EditorFileDialog::get_vbox() {
void EditorFileDialog::_update_theme_item_cache() {
ConfirmationDialog::_update_theme_item_cache();
- theme_cache.parent_folder = get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"));
- theme_cache.forward_folder = get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"));
- theme_cache.back_folder = get_theme_icon(SNAME("Back"), SNAME("EditorIcons"));
- theme_cache.reload = get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"));
- theme_cache.toggle_hidden = get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"));
- theme_cache.favorite = get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"));
- theme_cache.mode_thumbnails = get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"));
- theme_cache.mode_list = get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"));
- theme_cache.favorites_up = get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"));
- theme_cache.favorites_down = get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"));
-
- theme_cache.folder = get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"));
+ theme_cache.parent_folder = get_editor_theme_icon(SNAME("ArrowUp"));
+ theme_cache.forward_folder = get_editor_theme_icon(SNAME("Forward"));
+ theme_cache.back_folder = get_editor_theme_icon(SNAME("Back"));
+ theme_cache.reload = get_editor_theme_icon(SNAME("Reload"));
+ theme_cache.toggle_hidden = get_editor_theme_icon(SNAME("GuiVisibilityVisible"));
+ theme_cache.favorite = get_editor_theme_icon(SNAME("Favorites"));
+ theme_cache.mode_thumbnails = get_editor_theme_icon(SNAME("FileThumbnail"));
+ theme_cache.mode_list = get_editor_theme_icon(SNAME("FileList"));
+ theme_cache.favorites_up = get_editor_theme_icon(SNAME("MoveUp"));
+ theme_cache.favorites_down = get_editor_theme_icon(SNAME("MoveDown"));
+
+ theme_cache.folder = get_editor_theme_icon(SNAME("Folder"));
theme_cache.folder_icon_color = get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog"));
- theme_cache.action_copy = get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons"));
- theme_cache.action_delete = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"));
- theme_cache.filesystem = get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons"));
+ theme_cache.action_copy = get_editor_theme_icon(SNAME("ActionCopy"));
+ theme_cache.action_delete = get_editor_theme_icon(SNAME("Remove"));
+ theme_cache.filesystem = get_editor_theme_icon(SNAME("Filesystem"));
- theme_cache.folder_medium_thumbnail = get_theme_icon(SNAME("FolderMediumThumb"), SNAME("EditorIcons"));
- theme_cache.file_medium_thumbnail = get_theme_icon(SNAME("FileMediumThumb"), SNAME("EditorIcons"));
- theme_cache.folder_big_thumbnail = get_theme_icon(SNAME("FolderBigThumb"), SNAME("EditorIcons"));
- theme_cache.file_big_thumbnail = get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons"));
+ theme_cache.folder_medium_thumbnail = get_editor_theme_icon(SNAME("FolderMediumThumb"));
+ theme_cache.file_medium_thumbnail = get_editor_theme_icon(SNAME("FileMediumThumb"));
+ theme_cache.folder_big_thumbnail = get_editor_theme_icon(SNAME("FolderBigThumb"));
+ theme_cache.file_big_thumbnail = get_editor_theme_icon(SNAME("FileBigThumb"));
- theme_cache.progress[0] = get_theme_icon("Progress1", SNAME("EditorIcons"));
- theme_cache.progress[1] = get_theme_icon("Progress2", SNAME("EditorIcons"));
- theme_cache.progress[2] = get_theme_icon("Progress3", SNAME("EditorIcons"));
- theme_cache.progress[3] = get_theme_icon("Progress4", SNAME("EditorIcons"));
- theme_cache.progress[4] = get_theme_icon("Progress5", SNAME("EditorIcons"));
- theme_cache.progress[5] = get_theme_icon("Progress6", SNAME("EditorIcons"));
- theme_cache.progress[6] = get_theme_icon("Progress7", SNAME("EditorIcons"));
- theme_cache.progress[7] = get_theme_icon("Progress8", SNAME("EditorIcons"));
+ theme_cache.progress[0] = get_editor_theme_icon("Progress1");
+ theme_cache.progress[1] = get_editor_theme_icon("Progress2");
+ theme_cache.progress[2] = get_editor_theme_icon("Progress3");
+ theme_cache.progress[3] = get_editor_theme_icon("Progress4");
+ theme_cache.progress[4] = get_editor_theme_icon("Progress5");
+ theme_cache.progress[5] = get_editor_theme_icon("Progress6");
+ theme_cache.progress[6] = get_editor_theme_icon("Progress7");
+ theme_cache.progress[7] = get_editor_theme_icon("Progress8");
}
void EditorFileDialog::_notification(int p_what) {
@@ -264,17 +264,17 @@ void EditorFileDialog::update_dir() {
}
dir->set_text(dir_access->get_current_dir(false));
- file->set_text("");
-
// Disable "Open" button only when selecting file(s) mode.
get_ok_button()->set_disabled(_is_open_should_be_disabled());
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
+ file->set_text("");
set_ok_button_text(TTR("Open"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_OPEN_DIR:
+ file->set_text("");
set_ok_button_text(TTR("Select Current Folder"));
break;
case FILE_MODE_SAVE_FILE:
@@ -1535,7 +1535,7 @@ void EditorFileDialog::_recent_selected(int p_idx) {
}
void EditorFileDialog::_go_up() {
- dir_access->change_dir(get_current_dir().get_base_dir());
+ dir_access->change_dir(get_current_dir().trim_suffix("/").get_base_dir());
update_file_list();
update_dir();
_push_history();
diff --git a/editor/gui/editor_object_selector.cpp b/editor/gui/editor_object_selector.cpp
index 7cc830416c..9acd38bcf4 100644
--- a/editor/gui/editor_object_selector.cpp
+++ b/editor/gui/editor_object_selector.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_data.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/multi_node_edit.h"
Size2 EditorObjectSelector::get_minimum_size() const {
@@ -200,10 +201,10 @@ void EditorObjectSelector::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
update_path();
- int icon_size = get_theme_constant(SNAME("class_icon_size"), SNAME("Editor"));
+ int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
current_object_icon->set_custom_minimum_size(Size2(icon_size, icon_size));
- current_object_label->add_theme_font_override("font", get_theme_font(SNAME("main"), SNAME("EditorFonts")));
+ current_object_label->add_theme_font_override("font", get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
sub_objects_icon->set_texture(get_theme_icon(SNAME("arrow"), SNAME("OptionButton")));
sub_objects_menu->add_theme_constant_override("icon_max_width", icon_size);
} break;
diff --git a/editor/gui/editor_run_bar.cpp b/editor/gui/editor_run_bar.cpp
index e144d1d10d..4dfe40f0ad 100644
--- a/editor/gui/editor_run_bar.cpp
+++ b/editor/gui/editor_run_bar.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_quick_open.h"
#include "editor/editor_run_native.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/panel_container.h"
@@ -51,18 +52,18 @@ void EditorRunBar::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
_update_play_buttons();
- pause_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
- stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ pause_button->set_icon(get_editor_theme_icon(SNAME("Pause")));
+ stop_button->set_icon(get_editor_theme_icon(SNAME("Stop")));
if (is_movie_maker_enabled()) {
- main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles")));
- write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles")));
+ main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), EditorStringName(EditorStyles)));
+ write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), EditorStringName(EditorStyles)));
} else {
- main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles")));
- write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles")));
+ main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), EditorStringName(EditorStyles)));
+ write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), EditorStringName(EditorStyles)));
}
- write_movie_button->set_icon(get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons")));
+ write_movie_button->set_icon(get_editor_theme_icon(SNAME("MainMovieWrite")));
// This button behaves differently, so color it as such.
write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.7));
write_movie_button->add_theme_color_override("icon_pressed_color", Color(0, 0, 0, 0.84));
@@ -73,15 +74,15 @@ void EditorRunBar::_notification(int p_what) {
void EditorRunBar::_reset_play_buttons() {
play_button->set_pressed(false);
- play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
play_button->set_tooltip_text(TTR("Play the project."));
play_scene_button->set_pressed(false);
- play_scene_button->set_icon(get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons")));
+ play_scene_button->set_icon(get_editor_theme_icon(SNAME("PlayScene")));
play_scene_button->set_tooltip_text(TTR("Play the edited scene."));
play_custom_scene_button->set_pressed(false);
- play_custom_scene_button->set_icon(get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons")));
+ play_custom_scene_button->set_icon(get_editor_theme_icon(SNAME("PlayCustom")));
play_custom_scene_button->set_tooltip_text(TTR("Play a custom scene."));
}
@@ -102,18 +103,18 @@ void EditorRunBar::_update_play_buttons() {
if (active_button) {
active_button->set_pressed(true);
- active_button->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ active_button->set_icon(get_editor_theme_icon(SNAME("Reload")));
active_button->set_tooltip_text(TTR("Reload the played scene."));
}
}
void EditorRunBar::_write_movie_toggled(bool p_enabled) {
if (p_enabled) {
- add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles")));
- write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles")));
+ add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), EditorStringName(EditorStyles)));
+ write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), EditorStringName(EditorStyles)));
} else {
- add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles")));
- write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles")));
+ add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), EditorStringName(EditorStyles)));
+ write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), EditorStringName(EditorStyles)));
}
}
diff --git a/editor/gui/editor_scene_tabs.cpp b/editor/gui/editor_scene_tabs.cpp
index 553c45bd7f..a11d3e7b6a 100644
--- a/editor/gui/editor_scene_tabs.cpp
+++ b/editor/gui/editor_scene_tabs.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/inspector_dock.h"
#include "scene/gui/box_container.h"
@@ -50,9 +51,9 @@ void EditorSceneTabs::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
tabbar_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("tabbar_background"), SNAME("TabContainer")));
- scene_tabs->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), SNAME("Editor")));
+ scene_tabs->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
- scene_tab_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ scene_tab_add->set_icon(get_editor_theme_icon(SNAME("Add")));
scene_tab_add->add_theme_color_override("icon_normal_color", Color(0.6f, 0.6f, 0.6f, 0.8f));
scene_tab_add_ph->set_custom_minimum_size(scene_tab_add->get_minimum_size());
@@ -213,7 +214,7 @@ void EditorSceneTabs::update_scene_tabs() {
scene_tabs->disconnect("tab_changed", callable_mp(this, &EditorSceneTabs::_scene_tab_changed));
scene_tabs->clear_tabs();
- Ref<Texture2D> script_icon = get_theme_icon(SNAME("Script"), SNAME("EditorIcons"));
+ Ref<Texture2D> script_icon = get_editor_theme_icon(SNAME("Script"));
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
Node *type_node = EditorNode::get_editor_data().get_edited_scene_root(i);
Ref<Texture2D> icon;
diff --git a/editor/gui/editor_toaster.cpp b/editor/gui/editor_toaster.cpp
index f928a0fd30..6a415c18da 100644
--- a/editor/gui/editor_toaster.cpp
+++ b/editor/gui/editor_toaster.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
#include "scene/gui/panel_container.h"
@@ -110,29 +111,29 @@ void EditorToaster::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
if (vbox_container->is_visible()) {
- main_button->set_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons")));
+ main_button->set_icon(get_editor_theme_icon(SNAME("Notification")));
} else {
- main_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));
+ main_button->set_icon(get_editor_theme_icon(SNAME("NotificationDisabled")));
}
- disable_notifications_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));
+ disable_notifications_button->set_icon(get_editor_theme_icon(SNAME("NotificationDisabled")));
// Styleboxes background.
- info_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")));
+ info_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)));
- warning_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")));
- warning_panel_style_background->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warning_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)));
+ warning_panel_style_background->set_border_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
- error_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")));
- error_panel_style_background->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)));
+ error_panel_style_background->set_border_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
// Styleboxes progress.
- info_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03));
+ info_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)).lightened(0.03));
- warning_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03));
- warning_panel_style_progress->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warning_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)).lightened(0.03));
+ warning_panel_style_progress->set_border_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
- error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03));
- error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)).lightened(0.03));
+ error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
main_button->queue_redraw();
disable_notifications_button->queue_redraw();
@@ -270,13 +271,13 @@ void EditorToaster::_draw_button() {
real_t button_radius = main_button->get_size().x / 8;
switch (highest_severity) {
case SEVERITY_INFO:
- color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
break;
case SEVERITY_WARNING:
- color = get_theme_color(SNAME("warning_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
break;
case SEVERITY_ERROR:
- color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
break;
default:
break;
@@ -310,9 +311,9 @@ void EditorToaster::_draw_progress(Control *panel) {
void EditorToaster::_set_notifications_enabled(bool p_enabled) {
vbox_container->set_visible(p_enabled);
if (p_enabled) {
- main_button->set_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons")));
+ main_button->set_icon(get_editor_theme_icon(SNAME("Notification")));
} else {
- main_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));
+ main_button->set_icon(get_editor_theme_icon(SNAME("NotificationDisabled")));
}
_update_disable_notifications_button();
}
@@ -374,7 +375,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_
if (p_time > 0.0) {
Button *close_button = memnew(Button);
close_button->set_flat(true);
- close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ close_button->set_icon(get_editor_theme_icon(SNAME("Close")));
close_button->connect("pressed", callable_mp(this, &EditorToaster::close).bind(panel));
close_button->connect("theme_changed", callable_mp(this, &EditorToaster::_close_button_theme_changed).bind(close_button));
hbox_container->add_child(close_button);
@@ -490,7 +491,7 @@ void EditorToaster::close(Control *p_control) {
void EditorToaster::_close_button_theme_changed(Control *p_close_button) {
Button *close_button = Object::cast_to<Button>(p_close_button);
if (close_button) {
- close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ close_button->set_icon(get_editor_theme_icon(SNAME("Close")));
}
}
diff --git a/editor/gui/editor_validation_panel.cpp b/editor/gui/editor_validation_panel.cpp
index af15010b78..14fe05e906 100644
--- a/editor/gui/editor_validation_panel.cpp
+++ b/editor/gui/editor_validation_panel.cpp
@@ -31,6 +31,7 @@
#include "editor_validation_panel.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
@@ -52,9 +53,9 @@ void EditorValidationPanel::_update() {
void EditorValidationPanel::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- theme_cache.valid_color = get_theme_color(SNAME("success_color"), SNAME("Editor"));
- theme_cache.warning_color = get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- theme_cache.error_color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ theme_cache.valid_color = get_theme_color(SNAME("success_color"), EditorStringName(Editor));
+ theme_cache.warning_color = get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+ theme_cache.error_color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
} break;
}
}
diff --git a/editor/gui/editor_zoom_widget.cpp b/editor/gui/editor_zoom_widget.cpp
index 3998b33a53..e292dc99ac 100644
--- a/editor/gui/editor_zoom_widget.cpp
+++ b/editor/gui/editor_zoom_widget.cpp
@@ -145,8 +145,8 @@ void EditorZoomWidget::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- zoom_minus->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- zoom_plus->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
+ zoom_minus->set_icon(get_editor_theme_icon(SNAME("ZoomLess")));
+ zoom_plus->set_icon(get_editor_theme_icon(SNAME("ZoomMore")));
} break;
}
}
diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp
index 0862af37b6..8e08528f19 100644
--- a/editor/gui/scene_tree_editor.cpp
+++ b/editor/gui/scene_tree_editor.cpp
@@ -32,10 +32,12 @@
#include "core/config/project_settings.h"
#include "core/object/message_queue.h"
+#include "core/object/script_language.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/node_dock.h"
#include "editor/plugins/animation_player_editor_plugin.h"
@@ -226,19 +228,19 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_metadata(0, p_node->get_path());
if (connect_to_script_mode) {
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
Ref<Script> scr = p_node->get_script();
if (!scr.is_null() && EditorNode::get_singleton()->get_object_custom_type_base(p_node) != scr) {
//has script
- item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT);
+ item->add_button(0, get_editor_theme_icon(SNAME("Script")), BUTTON_SCRIPT);
} else {
//has no script (or script is a custom type)
- _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
item->set_selectable(0, false);
if (!scr.is_null()) { // make sure to mark the script if a custom type
- item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT);
+ item->add_button(0, get_editor_theme_icon(SNAME("Script")), BUTTON_SCRIPT);
item->set_button_disabled(0, item->get_button_count(0) - 1, true);
}
@@ -255,7 +257,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
} else if (part_of_subscene) {
if (valid_types.size() == 0) {
- _set_item_custom_color(item, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
}
} else if (marked.has(p_node)) {
String node_name = p_node->get_name();
@@ -264,15 +266,15 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
item->set_text(0, node_name);
item->set_selectable(0, marked_selectable);
- _set_item_custom_color(item, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
} else if (!p_node->can_process()) {
- _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
} else if (!marked_selectable && !marked_children_selectable) {
Node *node = p_node;
while (node) {
if (marked.has(node)) {
item->set_selectable(0, false);
- _set_item_custom_color(item, get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
break;
}
node = node->get_parent();
@@ -305,11 +307,11 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
String newline = (num_warnings == 1 ? "\n" : "\n\n");
- item->add_button(0, get_theme_icon(warning_icon, SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + newline + conf_warning);
+ item->add_button(0, get_editor_theme_icon(warning_icon), BUTTON_WARNING, false, TTR("Node configuration warning:") + newline + conf_warning);
}
if (p_node->is_unique_name_in_owner()) {
- item->add_button(0, get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), BUTTON_UNIQUE, false, vformat(TTR("This node can be accessed from within anywhere in the scene by preceding it with the '%s' prefix in a node path.\nClick to disable this."), UNIQUE_NODE_PREFIX));
+ item->add_button(0, get_editor_theme_icon(SNAME("SceneUniqueName")), BUTTON_UNIQUE, false, vformat(TTR("This node can be accessed from within anywhere in the scene by preceding it with the '%s' prefix in a node path.\nClick to disable this."), UNIQUE_NODE_PREFIX));
}
int num_connections = p_node->get_persistent_signal_connection_count();
@@ -345,11 +347,11 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
Ref<Texture2D> icon_temp;
SceneTreeEditorButton signal_temp = BUTTON_SIGNALS;
if (num_connections >= 1 && num_groups >= 1) {
- icon_temp = get_theme_icon(SNAME("SignalsAndGroups"), SNAME("EditorIcons"));
+ icon_temp = get_editor_theme_icon(SNAME("SignalsAndGroups"));
} else if (num_connections >= 1) {
- icon_temp = get_theme_icon(SNAME("Signals"), SNAME("EditorIcons"));
+ icon_temp = get_editor_theme_icon(SNAME("Signals"));
} else if (num_groups >= 1) {
- icon_temp = get_theme_icon(SNAME("Groups"), SNAME("EditorIcons"));
+ icon_temp = get_editor_theme_icon(SNAME("Groups"));
signal_temp = BUTTON_GROUPS;
}
@@ -364,10 +366,10 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
String tooltip = String(p_node->get_name());
if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
- item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
+ item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
tooltip += String("\n" + TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path());
} else if (p_node != get_scene_node() && !p_node->get_scene_file_path().is_empty() && can_open_instance) {
- item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
+ item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
tooltip += String("\n" + TTR("Instance:") + " " + p_node->get_scene_file_path());
}
@@ -400,30 +402,30 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
// Can't set tooltip after adding button, need to do it before.
if (scr->is_tool()) {
additional_notes += "\n" + TTR("This script is currently running in the editor.");
- button_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ button_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
}
if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == scr) {
additional_notes += "\n" + TTR("This script is a custom type.");
button_color.a = 0.5;
}
- item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + scr->get_path() + additional_notes);
+ item->add_button(0, get_editor_theme_icon(SNAME("Script")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + scr->get_path() + additional_notes);
item->set_button_color(0, item->get_button_count(0) - 1, button_color);
}
if (p_node->is_class("CanvasItem")) {
if (p_node->has_meta("_edit_lock_")) {
- item->add_button(0, get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
+ item->add_button(0, get_editor_theme_icon(SNAME("Lock")), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
}
if (p_node->has_meta("_edit_group_")) {
- item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
+ item->add_button(0, get_editor_theme_icon(SNAME("Group")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
}
bool v = p_node->call("is_visible");
if (v) {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityVisible")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
} else {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityHidden")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
@@ -434,9 +436,9 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
} else if (p_node->is_class("CanvasLayer") || p_node->is_class("Window")) {
bool v = p_node->call("is_visible");
if (v) {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityVisible")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
} else {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityHidden")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
@@ -444,18 +446,18 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
} else if (p_node->is_class("Node3D")) {
if (p_node->has_meta("_edit_lock_")) {
- item->add_button(0, get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
+ item->add_button(0, get_editor_theme_icon(SNAME("Lock")), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
}
if (p_node->has_meta("_edit_group_")) {
- item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
+ item->add_button(0, get_editor_theme_icon(SNAME("Group")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
}
bool v = p_node->call("is_visible");
if (v) {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityVisible")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
} else {
- item->add_button(0, get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ item->add_button(0, get_editor_theme_icon(SNAME("GuiVisibilityHidden")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
@@ -467,7 +469,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
bool is_pinned = AnimationPlayerEditor::get_singleton()->get_player() == p_node && AnimationPlayerEditor::get_singleton()->is_pinned();
if (is_pinned) {
- item->add_button(0, get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), BUTTON_PIN, false, TTR("AnimationPlayer is pinned.\nClick to unpin."));
+ item->add_button(0, get_editor_theme_icon(SNAME("Pin")), BUTTON_PIN, false, TTR("AnimationPlayer is pinned.\nClick to unpin."));
}
}
}
@@ -500,7 +502,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (!valid) {
- _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
item->set_selectable(0, false);
}
}
@@ -530,9 +532,9 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
}
if (node_visible) {
- item->set_button(0, idx, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")));
+ item->set_button(0, idx, get_editor_theme_icon(SNAME("GuiVisibilityVisible")));
} else {
- item->set_button(0, idx, get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")));
+ item->set_button(0, idx, get_editor_theme_icon(SNAME("GuiVisibilityHidden")));
}
_update_visibility_color(p_node, item);
@@ -674,7 +676,7 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select
}
p_parent->set_selectable(0, true);
} else if (keep_for_children) {
- p_parent->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ p_parent->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
p_parent->set_selectable(0, false);
p_parent->deselect(0);
}
@@ -905,7 +907,7 @@ void SceneTreeEditor::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- tree->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), SNAME("Editor")));
+ tree->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
_update_tree();
} break;
@@ -1238,7 +1240,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
if (i < list_max) {
HBoxContainer *hb = memnew(HBoxContainer);
TextureRect *tf = memnew(TextureRect);
- int icon_size = get_theme_constant(SNAME("class_icon_size"), SNAME("Editor"));
+ int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
tf->set_custom_minimum_size(Size2(icon_size, icon_size));
tf->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
tf->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
@@ -1563,9 +1565,9 @@ void SceneTreeDialog::set_valid_types(const Vector<StringName> &p_valid) {
}
void SceneTreeDialog::_update_theme() {
- filter->set_right_icon(tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ filter->set_right_icon(tree->get_editor_theme_icon(SNAME("Search")));
for (TextureRect *trect : valid_type_icons) {
- trect->set_custom_minimum_size(Vector2(get_theme_constant(SNAME("class_icon_size"), SNAME("Editor")), 0));
+ trect->set_custom_minimum_size(Vector2(get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)), 0));
trect->set_texture(EditorNode::get_singleton()->get_class_icon(trect->get_meta("type")));
}
}
diff --git a/editor/history_dock.cpp b/editor/history_dock.cpp
index 41ca519400..0ec840b8f1 100644
--- a/editor/history_dock.cpp
+++ b/editor/history_dock.cpp
@@ -31,6 +31,7 @@
#include "history_dock.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/check_box.h"
#include "scene/gui/item_list.h"
@@ -100,7 +101,7 @@ void HistoryDock::refresh_history() {
for (const EditorUndoRedoManager::Action &E : full_history) {
action_list->add_item(E.action_name);
if (E.history_id == EditorUndoRedoManager::GLOBAL_HISTORY) {
- action_list->set_item_custom_fg_color(-1, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ action_list->set_item_custom_fg_color(-1, get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
}
}
diff --git a/editor/icons/GraphEdit.svg b/editor/icons/GraphEdit.svg
index b5b21a084e..fd633a4662 100644
--- a/editor/icons/GraphEdit.svg
+++ b/editor/icons/GraphEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-1 3.73v6.541a2 2 0 1 0 2 0V5.414l4.793 4.793 1.414-1.414L5.414 4h5.857a2 2 0 1 0 0-2H4.729A2 2 0 0 0 3 1zm10.656 6.93-.707.707 1.414 1.414.707-.707zm-1.414 1.414-3.889 3.889L8 15l1.767-.353 3.889-3.89-1.414-1.413z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M11 1c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1h3c.554 0 1-.446 1-1V2c0-.554-.446-1-1-1h-3zM9 3.883L6.732 5.016c.17.292.268.628.268.984v1.117l2.268-1.133A1.964 1.964 0 019 5V3.883zM2 5c-.554 0-1 .446-1 1v4c0 .554.446 1 1 1h3c.554 0 1-.446 1-1V6c0-.554-.446-1-1-1H2zm5 3.883V10c0 .356-.099.692-.268.984L9 12.117V11c0-.356.099-.692.268-.984L7 8.883zM11 10c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1h3c.554 0 1-.446 1-1v-3c0-.554-.446-1-1-1h-3z" color="#000" fill="#8eef97"/><path d="M5 3h6" fill="none"/><rect width="3" height="1" x="-5" y="6.5" ry=".5" fill="#4a4a4a"/></svg>
diff --git a/editor/icons/GraphElement.svg b/editor/icons/GraphElement.svg
new file mode 100644
index 0000000000..5629993c25
--- /dev/null
+++ b/editor/icons/GraphElement.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a6 6 0 00-6 6 6 6 0 006 6 6 6 0 006-6 6 6 0 00-6-6zm0 2a4 4 0 014 4 4 4 0 01-4 4 4 4 0 01-4-4 4 4 0 014-4zm0 2a2 2 0 100 4 2 2 0 000-4z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GraphNode.svg b/editor/icons/GraphNode.svg
index 31316ea32c..9bef701ffd 100644
--- a/editor/icons/GraphNode.svg
+++ b/editor/icons/GraphNode.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-1 3.73v6.541a2 2 0 1 0 2 0V5.414L8.086 9.5 9.5 8.086 5.414 4h5.857a2 2 0 1 0 0-2H4.729A2 2 0 0 0 3 1zm9.5 9a2.5 2.5 0 0 0 0 5 2.5 2.5 0 0 0 0-5z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.846 2A1.841 1.841 0 003 3.846V4h10v-.154A1.841 1.841 0 0011.154 2H4.846zM3 5v1a3 3 0 013 3 3 3 0 01-3 3v.154C3 13.177 3.823 14 4.846 14h6.308A1.841 1.841 0 0013 12.154V12a3 3 0 01-3-3 3 3 0 013-3V5H3zm0 2a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2zm10 0a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GuiCloseCustomizable.svg b/editor/icons/GuiCloseCustomizable.svg
deleted file mode 100644
index 81822a3aaf..0000000000
--- a/editor/icons/GuiCloseCustomizable.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3 10 10M3 13 13 3" fill="none" stroke="#fff" stroke-width="2" stroke-opacity=".898"/></svg>
diff --git a/editor/import/audio_stream_import_settings.cpp b/editor/import/audio_stream_import_settings.cpp
index 1f7fbd8c59..c77143c8ac 100644
--- a/editor/import/audio_stream_import_settings.cpp
+++ b/editor/import/audio_stream_import_settings.cpp
@@ -32,6 +32,7 @@
#include "editor/audio_stream_preview.h"
#include "editor/editor_file_system.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/check_box.h"
AudioStreamImportSettings *AudioStreamImportSettings::singleton = nullptr;
@@ -45,18 +46,18 @@ void AudioStreamImportSettings::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
- _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
- _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
- color_rect->set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor")));
- _current_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- _current_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
- _duration_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- _duration_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
-
- zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
- zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
+ _stop_button->set_icon(get_editor_theme_icon(SNAME("Stop")));
+ _preview->set_color(get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)));
+ color_rect->set_color(get_theme_color(SNAME("dark_color_1"), EditorStringName(Editor)));
+ _current_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ _current_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
+ _duration_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ _duration_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
+
+ zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore")));
+ zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess")));
+ zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset")));
_indicator->queue_redraw();
_preview->queue_redraw();
@@ -84,11 +85,11 @@ void AudioStreamImportSettings::_draw_preview() {
float preview_offset = zoom_bar->get_value();
float preview_len = zoom_bar->get_page();
- Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts"));
- int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"));
+ Ref<Font> beat_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts));
+ int main_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts));
Vector<Vector2> points;
points.resize(width * 2);
- Color color_active = get_theme_color(SNAME("contrast_color_2"), SNAME("Editor"));
+ Color color_active = get_theme_color(SNAME("contrast_color_2"), EditorStringName(Editor));
Color color_inactive = color_active;
color_inactive.a *= 0.5;
Vector<Color> colors;
@@ -226,25 +227,25 @@ void AudioStreamImportSettings::_play() {
// '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'.
_pausing = true;
_player->stop();
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
set_process(false);
} else {
_player->play(_current);
- _play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("Pause")));
set_process(true);
}
}
void AudioStreamImportSettings::_stop() {
_player->stop();
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
_current = 0;
_indicator->queue_redraw();
set_process(false);
}
void AudioStreamImportSettings::_on_finished() {
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
if (!_pausing) {
_current = 0;
_indicator->queue_redraw();
@@ -261,8 +262,8 @@ void AudioStreamImportSettings::_draw_indicator() {
Rect2 rect = _preview->get_rect();
- Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts"));
- int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"));
+ Ref<Font> beat_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts));
+ int main_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts));
if (stream->get_bpm() > 0) {
int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE;
@@ -275,11 +276,11 @@ void AudioStreamImportSettings::_draw_indicator() {
return;
}
- const Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ const Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
_indicator->draw_line(Point2(ofs_x, rect.position.y), Point2(ofs_x, rect.position.y + rect.size.height), color, Math::round(2 * EDSCALE));
_indicator->draw_texture(
- get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons")),
- Point2(ofs_x - get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons"))->get_width() * 0.5, rect.position.y),
+ get_editor_theme_icon(SNAME("TimelineIndicator")),
+ Point2(ofs_x - get_editor_theme_icon(SNAME("TimelineIndicator"))->get_width() * 0.5, rect.position.y),
color);
if (stream->get_bpm() > 0 && _hovering_beat != -1) {
@@ -316,8 +317,8 @@ void AudioStreamImportSettings::_on_input_indicator(Ref<InputEvent> p_event) {
const Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
if (stream->get_bpm() > 0) {
- int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"));
- Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts"));
+ int main_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts));
+ Ref<Font> beat_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts));
int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE;
if ((!_dragging && mb->get_position().y < y_ofs) || _beat_len_dragging) {
if (mb->is_pressed()) {
@@ -345,8 +346,8 @@ void AudioStreamImportSettings::_on_input_indicator(Ref<InputEvent> p_event) {
_set_beat_len_to(mm->get_position().x);
}
if (stream->get_bpm() > 0) {
- int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"));
- Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts"));
+ int main_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts));
+ Ref<Font> beat_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts));
int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE;
if (mm->get_position().y < y_ofs) {
int new_hovering_beat = _get_beat_at_pos(mm->get_position().x);
diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp
index 1ee795f7d8..8a385aaf82 100644
--- a/editor/import/dynamic_font_import_settings.cpp
+++ b/editor/import/dynamic_font_import_settings.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
/*************************************************************************/
@@ -499,7 +500,7 @@ void DynamicFontImportSettings::_variation_add() {
vars_item->set_text(0, TTR("New Configuration"));
vars_item->set_editable(0, true);
- vars_item->add_button(1, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation"));
+ vars_item->add_button(1, get_editor_theme_icon(SNAME("Remove")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation"));
vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75));
Ref<DynamicFontImportSettingsData> import_variation_data;
@@ -726,8 +727,8 @@ void DynamicFontImportSettings::_glyph_selected() {
TreeItem *item = glyph_table->get_selected();
ERR_FAIL_NULL(item);
- Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor"));
- Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor"));
+ Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor));
+ Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), EditorStringName(Editor));
scol.a = 1.f;
int32_t c = item->get_metadata(glyph_table->get_selected_column());
@@ -798,8 +799,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
TreeItem *root = glyph_table->create_item();
ERR_FAIL_NULL(root);
- Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor"));
- Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor"));
+ Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor));
+ Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), EditorStringName(Editor));
scol.a = 1.f;
TreeItem *item = nullptr;
@@ -814,7 +815,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item->set_text(0, _pad_zeros(String::num_int64(c, 16)));
item->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
item->set_selectable(0, false);
- item->set_custom_bg_color(0, glyph_table->get_theme_color(SNAME("dark_color_3"), SNAME("Editor")));
+ item->set_custom_bg_color(0, glyph_table->get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor)));
}
if (font_main->has_char(c)) {
item->set_text(col + 1, String::chr(c));
@@ -827,7 +828,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item->clear_custom_bg_color(col + 1);
}
} else {
- item->set_custom_bg_color(col + 1, glyph_table->get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
+ item->set_custom_bg_color(col + 1, glyph_table->get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)));
}
item->set_metadata(col + 1, c);
item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER);
@@ -925,8 +926,8 @@ void DynamicFontImportSettings::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- add_var->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- label_warn->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ add_var->set_icon(get_editor_theme_icon(SNAME("Add")));
+ label_warn->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} break;
}
}
@@ -1082,7 +1083,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
}
font_preview_label->set_text(sample);
- Ref<Font> bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
+ Ref<Font> bold_font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
if (bold_font.is_valid()) {
font_name_label->add_theme_font_override("bold_font", bold_font);
}
@@ -1159,7 +1160,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
vars_item->set_text(0, cfg_name);
vars_item->set_editable(0, true);
- vars_item->add_button(1, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation"));
+ vars_item->add_button(1, get_editor_theme_icon(SNAME("Remove")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation"));
vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75));
Ref<DynamicFontImportSettingsData> import_variation_data_custom;
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 2e422d8c27..c70918e55e 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -32,6 +32,7 @@
#include "core/error/error_macros.h"
#include "core/io/resource_saver.h"
+#include "core/object/script_language.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/import/scene_import_settings.h"
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 2142ee3c10..6b42417296 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/animation/animation_player.h"
@@ -170,7 +171,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
MaterialData &material_data = material_map[import_id];
ERR_FAIL_COND(p_material != material_data.material);
- Ref<Texture2D> icon = get_theme_icon(SNAME("StandardMaterial3D"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("StandardMaterial3D"));
TreeItem *item = p_tree->create_item(p_parent);
if (p_material->get_name().is_empty()) {
@@ -224,7 +225,7 @@ void SceneImportSettings::_fill_mesh(Tree *p_tree, const Ref<Mesh> &p_mesh, Tree
MeshData &mesh_data = mesh_map[import_id];
- Ref<Texture2D> icon = get_theme_icon(SNAME("Mesh"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Mesh"));
TreeItem *item = p_tree->create_item(p_parent);
item->set_text(0, p_mesh->get_name());
@@ -274,7 +275,7 @@ void SceneImportSettings::_fill_animation(Tree *p_tree, const Ref<Animation> &p_
AnimationData &animation_data = animation_map[p_name];
- Ref<Texture2D> icon = get_theme_icon(SNAME("Animation"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Animation"));
TreeItem *item = p_tree->create_item(p_parent);
item->set_text(0, p_name);
@@ -318,17 +319,17 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
String type = p_node->get_class();
- if (!has_theme_icon(type, SNAME("EditorIcons"))) {
+ if (!has_theme_icon(type, EditorStringName(EditorIcons))) {
type = "Node3D";
}
- Ref<Texture2D> icon = get_theme_icon(type, SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(type);
TreeItem *item = scene_tree->create_item(p_parent_item);
item->set_text(0, p_node->get_name());
if (p_node == scene) {
- icon = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("PackedScene"));
item->set_text(0, TTR("Scene"));
}
@@ -886,11 +887,11 @@ void SceneImportSettings::_play_animation() {
if (animation_player->has_animation(id)) {
if (animation_player->is_playing()) {
animation_player->pause();
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
set_process(false);
} else {
animation_player->play(id);
- animation_play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("Pause")));
set_process(true);
}
}
@@ -899,7 +900,7 @@ void SceneImportSettings::_play_animation() {
void SceneImportSettings::_stop_current_animation() {
animation_pingpong = false;
animation_player->stop();
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
animation_slider->set_value_no_signal(0.0);
set_process(false);
}
@@ -911,7 +912,7 @@ void SceneImportSettings::_reset_animation(const String &p_animation_name) {
if (animation_player != nullptr && animation_player->is_playing()) {
animation_player->stop();
}
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
_reset_bone_transforms();
set_process(false);
@@ -933,7 +934,7 @@ void SceneImportSettings::_reset_animation(const String &p_animation_name) {
animation_player->play(p_animation_name);
} else {
animation_player->stop(true);
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
animation_player->set_assigned_animation(p_animation_name);
animation_player->seek(0.0, true);
animation_slider->set_value_no_signal(0.0);
@@ -948,7 +949,7 @@ void SceneImportSettings::_animation_slider_value_changed(double p_value) {
}
if (animation_player->is_playing()) {
animation_player->stop();
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
set_process(false);
}
animation_player->seek(p_value * animation_map[selected_id].animation->get_length(), true);
@@ -959,7 +960,7 @@ void SceneImportSettings::_animation_finished(const StringName &p_name) {
switch (loop_mode) {
case Animation::LOOP_NONE: {
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
animation_slider->set_value_no_signal(1.0);
set_process(false);
} break;
@@ -1145,11 +1146,11 @@ void SceneImportSettings::_notification(int p_what) {
action_menu->add_theme_style_override("pressed", get_theme_stylebox("pressed", "Button"));
if (animation_player != nullptr && animation_player->is_playing()) {
- animation_play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("Pause")));
} else {
- animation_play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ animation_play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
}
- animation_stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ animation_stop_button->set_icon(get_editor_theme_icon(SNAME("Stop")));
} break;
case NOTIFICATION_PROCESS: {
@@ -1193,11 +1194,11 @@ void SceneImportSettings::_save_path_changed(const String &p_path) {
if (FileAccess::exists(p_path)) {
save_path_item->set_text(2, TTR("Warning: File exists"));
save_path_item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced."));
- save_path_item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ save_path_item->set_icon(2, get_editor_theme_icon(SNAME("StatusWarning")));
} else {
save_path_item->set_text(2, TTR("Will create new file"));
- save_path_item->set_icon(2, get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")));
+ save_path_item->set_icon(2, get_editor_theme_icon(SNAME("StatusSuccess")));
}
}
@@ -1231,7 +1232,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
String name = md.material_node->get_text(0);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- item->set_icon(0, get_theme_icon(SNAME("StandardMaterial3D"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("StandardMaterial3D")));
item->set_text(0, name);
if (md.has_import_id) {
@@ -1253,20 +1254,20 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
if (FileAccess::exists(path)) {
item->set_text(2, TTR("Warning: File exists"));
item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced."));
- item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusWarning")));
} else {
item->set_text(2, TTR("Will create new file"));
- item->set_icon(2, get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusSuccess")));
}
- item->add_button(1, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ item->add_button(1, get_editor_theme_icon(SNAME("Folder")));
}
} else {
item->set_text(2, TTR("No import ID"));
item->set_tooltip_text(2, TTR("Material has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID."));
- item->set_icon(2, get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusError")));
}
save_path_items.push_back(item);
@@ -1284,7 +1285,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
String name = md.mesh_node->get_text(0);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- item->set_icon(0, get_theme_icon(SNAME("Mesh"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Mesh")));
item->set_text(0, name);
if (md.has_import_id) {
@@ -1306,20 +1307,20 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
if (FileAccess::exists(path)) {
item->set_text(2, TTR("Warning: File exists"));
item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced on import."));
- item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusWarning")));
} else {
item->set_text(2, TTR("Will save to new file"));
- item->set_icon(2, get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusSuccess")));
}
- item->add_button(1, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ item->add_button(1, get_editor_theme_icon(SNAME("Folder")));
}
} else {
item->set_text(2, TTR("No import ID"));
item->set_tooltip_text(2, TTR("Mesh has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID."));
- item->set_icon(2, get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusError")));
}
save_path_items.push_back(item);
@@ -1337,7 +1338,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
String name = ad.scene_node->get_text(0);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- item->set_icon(0, get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Animation")));
item->set_text(0, name);
if (ad.settings.has("save_to_file/enabled") && bool(ad.settings["save_to_file/enabled"])) {
@@ -1358,14 +1359,14 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
if (FileAccess::exists(path)) {
item->set_text(2, TTR("Warning: File exists"));
item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced on import."));
- item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusWarning")));
} else {
item->set_text(2, TTR("Will save to new file"));
- item->set_icon(2, get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")));
+ item->set_icon(2, get_editor_theme_icon(SNAME("StatusSuccess")));
}
- item->add_button(1, get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ item->add_button(1, get_editor_theme_icon(SNAME("Folder")));
}
save_path_items.push_back(item);
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 018231cda5..614047296a 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
class ImportDockParameters : public Object {
@@ -657,7 +658,7 @@ void ImportDock::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
import_opts->edit(params);
- label_warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ label_warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} break;
}
}
@@ -670,7 +671,7 @@ void ImportDock::_set_dirty(bool p_dirty) {
if (p_dirty) {
// Add a dirty marker to notify the user that they should reimport the selected resource to see changes.
import->set_text(TTR("Reimport") + " (*)");
- import->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ import->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
import->set_tooltip_text(TTR("You have pending changes that haven't been applied yet. Click Reimport to apply changes made to the import options.\nSelecting another resource in the FileSystem dock without clicking Reimport first will discard changes made in the Import dock."));
} else {
// Remove the dirty marker on the Reimport button.
diff --git a/editor/input_event_configuration_dialog.cpp b/editor/input_event_configuration_dialog.cpp
index 430e81466e..724ad9370b 100644
--- a/editor/input_event_configuration_dialog.cpp
+++ b/editor/input_event_configuration_dialog.cpp
@@ -31,6 +31,7 @@
#include "editor/input_event_configuration_dialog.h"
#include "core/input/input_map.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/event_listener_line_edit.h"
#include "scene/gui/check_box.h"
#include "scene/gui/line_edit.h"
@@ -554,18 +555,18 @@ void InputEventConfigurationDialog::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- input_list_search->set_right_icon(input_list_search->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ input_list_search->set_right_icon(input_list_search->get_editor_theme_icon(SNAME("Search")));
- key_mode->set_item_icon(KEYMODE_KEYCODE, get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")));
- key_mode->set_item_icon(KEYMODE_PHY_KEYCODE, get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons")));
- key_mode->set_item_icon(KEYMODE_UNICODE, get_theme_icon(SNAME("KeyboardLabel"), SNAME("EditorIcons")));
+ key_mode->set_item_icon(KEYMODE_KEYCODE, get_editor_theme_icon(SNAME("Keyboard")));
+ key_mode->set_item_icon(KEYMODE_PHY_KEYCODE, get_editor_theme_icon(SNAME("KeyboardPhysical")));
+ key_mode->set_item_icon(KEYMODE_UNICODE, get_editor_theme_icon(SNAME("KeyboardLabel")));
- icon_cache.keyboard = get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons"));
- icon_cache.mouse = get_theme_icon(SNAME("Mouse"), SNAME("EditorIcons"));
- icon_cache.joypad_button = get_theme_icon(SNAME("JoyButton"), SNAME("EditorIcons"));
- icon_cache.joypad_axis = get_theme_icon(SNAME("JoyAxis"), SNAME("EditorIcons"));
+ icon_cache.keyboard = get_editor_theme_icon(SNAME("Keyboard"));
+ icon_cache.mouse = get_editor_theme_icon(SNAME("Mouse"));
+ icon_cache.joypad_button = get_editor_theme_icon(SNAME("JoyButton"));
+ icon_cache.joypad_axis = get_editor_theme_icon(SNAME("JoyAxis"));
- event_as_text->add_theme_font_override("font", get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ event_as_text->add_theme_font_override("font", get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
_update_input_list();
} break;
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 39ed7d869b..ac06841b30 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
@@ -424,33 +425,33 @@ void InspectorDock::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
- resource_new_button->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons")));
- resource_load_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
- resource_save_button->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")));
- resource_extra_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- open_docs_button->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")));
+ resource_new_button->set_icon(get_editor_theme_icon(SNAME("New")));
+ resource_load_button->set_icon(get_editor_theme_icon(SNAME("Load")));
+ resource_save_button->set_icon(get_editor_theme_icon(SNAME("Save")));
+ resource_extra_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ open_docs_button->set_icon(get_editor_theme_icon(SNAME("HelpSearch")));
PopupMenu *resource_extra_popup = resource_extra_button->get_popup();
- resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")));
- resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_COPY), get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
+ resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), get_editor_theme_icon(SNAME("ActionPaste")));
+ resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_COPY), get_editor_theme_icon(SNAME("ActionCopy")));
if (is_layout_rtl()) {
- backward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- forward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
+ backward_button->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ forward_button->set_icon(get_editor_theme_icon(SNAME("Back")));
} else {
- backward_button->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- forward_button->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
+ backward_button->set_icon(get_editor_theme_icon(SNAME("Back")));
+ forward_button->set_icon(get_editor_theme_icon(SNAME("Forward")));
}
- history_menu->set_icon(get_theme_icon(SNAME("History"), SNAME("EditorIcons")));
- object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
- search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ history_menu->set_icon(get_editor_theme_icon(SNAME("History")));
+ object_menu->set_icon(get_editor_theme_icon(SNAME("Tools")));
+ search->set_right_icon(get_editor_theme_icon(SNAME("Search")));
if (info_is_warning) {
- info->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- info->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ info->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ info->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} else {
- info->set_icon(get_theme_icon(SNAME("NodeInfo"), SNAME("EditorIcons")));
- info->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Editor")));
+ info->set_icon(get_editor_theme_icon(SNAME("NodeInfo")));
+ info->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), EditorStringName(Editor)));
}
} break;
}
@@ -485,11 +486,11 @@ void InspectorDock::set_info(const String &p_button_text, const String &p_messag
info_is_warning = p_is_warning;
if (info_is_warning) {
- info->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- info->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ info->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ info->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
} else {
- info->set_icon(get_theme_icon(SNAME("NodeInfo"), SNAME("EditorIcons")));
- info->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Editor")));
+ info->set_icon(get_editor_theme_icon(SNAME("NodeInfo")));
+ info->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), EditorStringName(Editor)));
}
if (!p_button_text.is_empty() && !p_message.is_empty()) {
@@ -540,8 +541,8 @@ void InspectorDock::update(Object *p_object) {
PopupMenu *p = object_menu->get_popup();
p->clear();
- p->add_icon_shortcut(get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")), ED_SHORTCUT("property_editor/expand_all", TTR("Expand All")), EXPAND_ALL);
- p->add_icon_shortcut(get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")), ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All")), COLLAPSE_ALL);
+ p->add_icon_shortcut(get_editor_theme_icon(SNAME("GuiTreeArrowDown")), ED_SHORTCUT("property_editor/expand_all", TTR("Expand All")), EXPAND_ALL);
+ p->add_icon_shortcut(get_editor_theme_icon(SNAME("GuiTreeArrowRight")), ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All")), COLLAPSE_ALL);
// Calling it 'revertable' internally, because that's what the implementation is based on, but labeling it as 'non-default' because that's more user friendly, even if not 100% accurate.
p->add_shortcut(ED_SHORTCUT("property_editor/expand_revertable", TTR("Expand Non-Default")), EXPAND_REVERTABLE);
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 351986a80b..d4154d371b 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -497,7 +497,7 @@ void LocalizationEditor::update_translations() {
t->set_text(0, translations[i].replace_first("res://", ""));
t->set_tooltip_text(0, translations[i]);
t->set_metadata(0, i);
- t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove"));
+ t->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0, false, TTR("Remove"));
}
}
@@ -531,7 +531,7 @@ void LocalizationEditor::update_translations() {
t->set_text(0, keys[i].replace_first("res://", ""));
t->set_tooltip_text(0, keys[i]);
t->set_metadata(0, keys[i]);
- t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove"));
+ t->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0, false, TTR("Remove"));
// Display that it has been removed if this is the case.
if (!FileAccess::exists(keys[i])) {
@@ -555,7 +555,7 @@ void LocalizationEditor::update_translations() {
t2->set_text(0, path.replace_first("res://", ""));
t2->set_tooltip_text(0, path);
t2->set_metadata(0, j);
- t2->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove"));
+ t2->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0, false, TTR("Remove"));
t2->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
t2->set_text(1, TranslationServer::get_singleton()->get_locale_name(locale));
t2->set_editable(1, true);
@@ -583,7 +583,7 @@ void LocalizationEditor::update_translations() {
t->set_text(0, pot_translations[i].replace_first("res://", ""));
t->set_tooltip_text(0, pot_translations[i]);
t->set_metadata(0, i);
- t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove"));
+ t->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0, false, TTR("Remove"));
}
// New translation parser plugin might extend possible file extensions in POT generation.
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index ebb35eedf9..6521730473 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -55,8 +55,8 @@ void NodeDock::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- connections_button->set_icon(get_theme_icon(SNAME("Signals"), SNAME("EditorIcons")));
- groups_button->set_icon(get_theme_icon(SNAME("Groups"), SNAME("EditorIcons")));
+ connections_button->set_icon(get_editor_theme_icon(SNAME("Signals")));
+ groups_button->set_icon(get_editor_theme_icon(SNAME("Groups")));
} break;
}
}
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index c5a667cd5f..196a2186a7 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -32,6 +32,7 @@
#include "core/io/config_file.h"
#include "core/io/dir_access.h"
+#include "core/object/script_language.h"
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_scale.h"
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 4375a33b4f..86653f8775 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
@@ -157,9 +158,9 @@ void AbstractPolygon2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- button_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
+ button_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate")));
+ button_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit")));
+ button_delete->set_icon(get_editor_theme_icon(SNAME("CurveDelete")));
} break;
case NOTIFICATION_READY: {
@@ -498,7 +499,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
// All polygon points are sharp, so use the sharp handle icon
- const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
const Vertex active_point = get_active_point();
const int n_polygons = _get_polygon_count();
@@ -571,12 +572,12 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, overlay_modulate);
if (vertex == hover_point) {
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
String num = String::num(vertex.vertex);
Size2 num_size = font->get_string_size(num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
const float outline_size = 4;
- Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color font_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
Color outline_color = font_color.inverted();
p_overlay->draw_string_outline(font, point - num_size * 0.5, num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
p_overlay->draw_string(font, point - num_size * 0.5, num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
@@ -585,7 +586,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
}
if (edge_point.valid()) {
- Ref<Texture2D> add_handle = get_theme_icon(SNAME("EditorHandleAdd"), SNAME("EditorIcons"));
+ Ref<Texture2D> add_handle = get_editor_theme_icon(SNAME("EditorHandleAdd"));
p_overlay->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5);
}
}
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index 15fa60f11b..373a927ef9 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "scene/animation/animation_blend_tree.h"
@@ -85,7 +86,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
ap->get_animation_list(&names);
for (const StringName &E : names) {
- animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E);
+ animations_menu->add_icon_item(get_editor_theme_icon(SNAME("Animation")), E);
animations_to_add.push_back(E);
}
}
@@ -224,13 +225,13 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- Ref<Texture2D> icon = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons"));
- Ref<Texture2D> icon_selected = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("KeyValue"));
+ Ref<Texture2D> icon_selected = get_editor_theme_icon(SNAME("KeySelected"));
Size2 s = blend_space_draw->get_size();
if (blend_space_draw->has_focus()) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
blend_space_draw->draw_rect(Rect2(Point2(), s), color, false);
}
@@ -303,7 +304,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
{
Color color;
if (tool_blend->is_pressed()) {
- color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
} else {
color = linecolor;
color.a *= 0.5;
@@ -575,18 +576,18 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ tool_blend->set_icon(get_editor_theme_icon(SNAME("EditPivot")));
+ tool_select->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ tool_create->set_icon(get_editor_theme_icon(SNAME("EditKey")));
+ tool_erase->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ snap->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
+ open_editor->set_icon(get_editor_theme_icon(SNAME("Edit")));
interpolation->clear();
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")), "", 0);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")), "", 1);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons")), "", 2);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackContinuous")), "", 0);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackDiscrete")), "", 1);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackCapture")), "", 2);
} break;
case NOTIFICATION_PROCESS: {
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 924b948525..cd69e90660 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "scene/animation/animation_blend_tree.h"
@@ -128,7 +129,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
List<StringName> names;
ap->get_animation_list(&names);
for (const StringName &E : names) {
- animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E);
+ animations_menu->add_icon_item(get_editor_theme_icon(SNAME("Animation")), E);
animations_to_add.push_back(E);
}
}
@@ -450,13 +451,13 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
linecolor_soft.a *= 0.5;
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- Ref<Texture2D> icon = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons"));
- Ref<Texture2D> icon_selected = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("KeyValue"));
+ Ref<Texture2D> icon_selected = get_editor_theme_icon(SNAME("KeySelected"));
Size2 s = blend_space_draw->get_size();
if (blend_space_draw->has_focus()) {
- Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
blend_space_draw->draw_rect(Rect2(Point2(), s), color, false);
}
blend_space_draw->draw_line(Point2(1, 0), Point2(1, s.height - 1), linecolor, Math::round(EDSCALE));
@@ -535,7 +536,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
Color color;
if (i == selected_triangle) {
- color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
color.a *= 0.5;
} else {
color = linecolor;
@@ -597,7 +598,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
{
Color color;
if (tool_blend->is_pressed()) {
- color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
} else {
color = linecolor;
color.a *= 0.5;
@@ -796,20 +797,20 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
- tool_triangle->set_icon(get_theme_icon(SNAME("ToolTriangle"), SNAME("EditorIcons")));
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- auto_triangles->set_icon(get_theme_icon(SNAME("AutoTriangle"), SNAME("EditorIcons")));
+ tool_blend->set_icon(get_editor_theme_icon(SNAME("EditPivot")));
+ tool_select->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ tool_create->set_icon(get_editor_theme_icon(SNAME("EditKey")));
+ tool_triangle->set_icon(get_editor_theme_icon(SNAME("ToolTriangle")));
+ tool_erase->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ snap->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
+ open_editor->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ auto_triangles->set_icon(get_editor_theme_icon(SNAME("AutoTriangle")));
interpolation->clear();
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")), "", 0);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")), "", 1);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons")), "", 2);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackContinuous")), "", 0);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackDiscrete")), "", 1);
+ interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackCapture")), "", 2);
} break;
case NOTIFICATION_PROCESS: {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 8f2839ddb0..ac3be4ba84 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "scene/animation/animation_player.h"
@@ -168,8 +169,8 @@ void AnimationNodeBlendTreeEditor::update_graph() {
name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(agnode), CONNECT_DEFERRED);
name->connect("text_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_rename_lineedit_changed), CONNECT_DEFERRED);
base = 1;
- node->set_show_close_button(true);
- node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request).bind(E), CONNECT_DEFERRED);
+ agnode->set_closable(true);
+ node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_close_request).bind(E), CONNECT_DEFERRED);
}
for (int i = 0; i < agnode->get_input_count(); i++) {
@@ -204,7 +205,7 @@ void AnimationNodeBlendTreeEditor::update_graph() {
node->add_child(memnew(HSeparator));
Button *open_in_editor = memnew(Button);
open_in_editor->set_text(TTR("Open Editor"));
- open_in_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ open_in_editor->set_icon(get_editor_theme_icon(SNAME("Edit")));
node->add_child(open_in_editor);
open_in_editor->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor).bind(E), CONNECT_DEFERRED);
open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER);
@@ -218,7 +219,7 @@ void AnimationNodeBlendTreeEditor::update_graph() {
} else {
inspect_filters->set_text(TTR("Edit Filters"));
}
- inspect_filters->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons")));
+ inspect_filters->set_icon(get_editor_theme_icon(SNAME("AnimationFilter")));
node->add_child(inspect_filters);
inspect_filters->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_inspect_filters).bind(E), CONNECT_DEFERRED);
inspect_filters->set_h_size_flags(SIZE_SHRINK_CENTER);
@@ -228,7 +229,7 @@ void AnimationNodeBlendTreeEditor::update_graph() {
if (anim.is_valid()) {
MenuButton *mb = memnew(MenuButton);
mb->set_text(anim->get_animation());
- mb->set_icon(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")));
+ mb->set_icon(get_editor_theme_icon(SNAME("Animation")));
mb->set_disabled(read_only);
Array options;
@@ -262,7 +263,7 @@ void AnimationNodeBlendTreeEditor::update_graph() {
mb->get_popup()->connect("index_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_anim_selected).bind(options, E), CONNECT_DEFERRED);
}
- Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("frame"), SNAME("GraphNode"));
+ Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("panel"), SNAME("GraphNode"));
Color c = sb->get_border_color();
Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0);
mono_color.a = 0.85;
@@ -497,7 +498,7 @@ void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options,
undo_redo->commit_action();
}
-void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) {
+void AnimationNodeBlendTreeEditor::_close_request(const String &p_which) {
if (read_only) {
return;
}
@@ -521,7 +522,7 @@ void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) {
undo_redo->commit_action();
}
-void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<StringName> &p_nodes) {
+void AnimationNodeBlendTreeEditor::_close_nodes_request(const TypedArray<StringName> &p_nodes) {
if (read_only) {
return;
}
@@ -531,15 +532,19 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<String
if (p_nodes.is_empty()) {
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- if (gn->is_selected() && gn->is_close_button_visible()) {
+ if (gn && gn->is_selected()) {
+ Ref<AnimationNode> anode = blend_tree->get_node(gn->get_name());
+ if (anode->is_closable()) {
to_erase.push_back(gn->get_name());
}
}
}
} else {
for (int i = 0; i < p_nodes.size(); i++) {
- to_erase.push_back(p_nodes[i]);
+ Ref<AnimationNode> anode = blend_tree->get_node(p_nodes[i]);
+ if (anode->is_closable()) {
+ to_erase.push_back(p_nodes[i]);
+ }
}
}
@@ -551,7 +556,7 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<String
undo_redo->create_action(TTR("Delete Node(s)"));
for (const StringName &F : to_erase) {
- _delete_request(F);
+ _close_request(F);
}
undo_redo->commit_action();
@@ -747,7 +752,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
ti->set_text(0, F->get());
ti->set_selectable(0, false);
ti->set_editable(0, false);
- ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons")));
+ ti->set_icon(0, get_editor_theme_icon(SNAME("BoneAttachment3D")));
} else {
ti = parenthood[accum];
}
@@ -758,7 +763,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
ti->set_text(0, concat);
ti->set_checked(0, anode->is_path_filtered(path));
- ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons")));
+ ti->set_icon(0, get_editor_theme_icon(SNAME("BoneAttachment3D")));
ti->set_metadata(0, path);
} else {
@@ -828,7 +833,7 @@ void AnimationNodeBlendTreeEditor::_update_editor_settings() {
void AnimationNodeBlendTreeEditor::_update_theme() {
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
}
void AnimationNodeBlendTreeEditor::_notification(int p_what) {
@@ -1082,7 +1087,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
graph->connect("disconnection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_disconnection_request), CONNECT_DEFERRED);
graph->connect("node_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_selected));
graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed));
- graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request));
+ graph->connect("close_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_close_nodes_request));
graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request));
graph->connect("connection_to_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_to_empty));
graph->connect("connection_from_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_from_empty));
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index afb3394238..49c8d951ef 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -31,6 +31,7 @@
#ifndef ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
#define ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
+#include "core/object/script_language.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/gui/button.h"
@@ -108,8 +109,8 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
void _node_selected(Object *p_node);
void _open_in_editor(const String &p_which);
void _anim_selected(int p_index, Array p_options, const String &p_node);
- void _delete_request(const String &p_which);
- void _delete_nodes_request(const TypedArray<StringName> &p_nodes);
+ void _close_request(const String &p_which);
+ void _close_nodes_request(const TypedArray<StringName> &p_nodes);
bool _update_filters(const Ref<AnimationNode> &anode);
void _inspect_filters(const String &p_which);
diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp
index 4db4f870ca..f658b2d5e6 100644
--- a/editor/plugins/animation_library_editor.cpp
+++ b/editor/plugins/animation_library_editor.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
@@ -73,7 +74,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) {
}
if (error != "") {
- add_library_validate->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ add_library_validate->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
add_library_validate->set_text(error);
add_library_dialog->get_ok_button()->set_disabled(true);
} else {
@@ -86,7 +87,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) {
add_library_validate->set_text(TTR("Library name is valid."));
}
}
- add_library_validate->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ add_library_validate->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
add_library_dialog->get_ok_button()->set_disabled(false);
}
}
@@ -622,7 +623,7 @@ void AnimationLibraryEditor::update_tree() {
tree->clear();
ERR_FAIL_COND(!player);
- Color ss_color = get_theme_color(SNAME("prop_subsection"), SNAME("Editor"));
+ Color ss_color = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor));
TreeItem *root = tree->create_item();
TypedArray<StringName> libs = player->call("get_animation_library_list");
@@ -669,14 +670,14 @@ void AnimationLibraryEditor::update_tree() {
libitem->set_editable(0, !animation_library_is_foreign);
libitem->set_metadata(0, K);
- libitem->set_icon(0, get_theme_icon("AnimationLibrary", "EditorIcons"));
+ libitem->set_icon(0, get_editor_theme_icon("AnimationLibrary"));
- libitem->add_button(0, get_theme_icon("Add", "EditorIcons"), LIB_BUTTON_ADD, animation_library_is_foreign, TTR("Add Animation to Library"));
- libitem->add_button(0, get_theme_icon("Load", "EditorIcons"), LIB_BUTTON_LOAD, animation_library_is_foreign, TTR("Load animation from file and add to library"));
- libitem->add_button(0, get_theme_icon("ActionPaste", "EditorIcons"), LIB_BUTTON_PASTE, animation_library_is_foreign, TTR("Paste Animation to Library from clipboard"));
+ libitem->add_button(0, get_editor_theme_icon("Add"), LIB_BUTTON_ADD, animation_library_is_foreign, TTR("Add Animation to Library"));
+ libitem->add_button(0, get_editor_theme_icon("Load"), LIB_BUTTON_LOAD, animation_library_is_foreign, TTR("Load animation from file and add to library"));
+ libitem->add_button(0, get_editor_theme_icon("ActionPaste"), LIB_BUTTON_PASTE, animation_library_is_foreign, TTR("Paste Animation to Library from clipboard"));
- libitem->add_button(1, get_theme_icon("Save", "EditorIcons"), LIB_BUTTON_FILE, false, TTR("Save animation library to resource on disk"));
- libitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), LIB_BUTTON_DELETE, false, TTR("Remove animation library"));
+ libitem->add_button(1, get_editor_theme_icon("Save"), LIB_BUTTON_FILE, false, TTR("Save animation library to resource on disk"));
+ libitem->add_button(1, get_editor_theme_icon("Remove"), LIB_BUTTON_DELETE, false, TTR("Remove animation library"));
libitem->set_custom_bg_color(0, ss_color);
@@ -687,8 +688,8 @@ void AnimationLibraryEditor::update_tree() {
anitem->set_text(0, L);
anitem->set_editable(0, !animation_library_is_foreign);
anitem->set_metadata(0, L);
- anitem->set_icon(0, get_theme_icon("Animation", "EditorIcons"));
- anitem->add_button(0, get_theme_icon("ActionCopy", "EditorIcons"), ANIM_BUTTON_COPY, animation_library_is_foreign, TTR("Copy animation to clipboard"));
+ anitem->set_icon(0, get_editor_theme_icon("Animation"));
+ anitem->add_button(0, get_editor_theme_icon("ActionCopy"), ANIM_BUTTON_COPY, animation_library_is_foreign, TTR("Copy animation to clipboard"));
Ref<Animation> anim = al->get_animation(L);
String anim_path = anim->get_path();
@@ -715,8 +716,8 @@ void AnimationLibraryEditor::update_tree() {
anitem->set_text(1, anim_path.get_file());
}
}
- anitem->add_button(1, get_theme_icon("Save", "EditorIcons"), ANIM_BUTTON_FILE, animation_library_is_foreign, TTR("Save animation to resource on disk"));
- anitem->add_button(1, get_theme_icon("Remove", "EditorIcons"), ANIM_BUTTON_DELETE, animation_library_is_foreign, TTR("Remove animation from Library"));
+ anitem->add_button(1, get_editor_theme_icon("Save"), ANIM_BUTTON_FILE, animation_library_is_foreign, TTR("Save animation to resource on disk"));
+ anitem->add_button(1, get_editor_theme_icon("Remove"), ANIM_BUTTON_DELETE, animation_library_is_foreign, TTR("Remove animation from Library"));
}
}
}
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 7f4e7460f8..59e114fe45 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -121,22 +121,22 @@ void AnimationPlayerEditor::_notification(int p_what) {
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED: {
- stop_icon = get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"));
- pause_icon = get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"));
+ stop_icon = get_editor_theme_icon(SNAME("Stop"));
+ pause_icon = get_editor_theme_icon(SNAME("Pause"));
if (player && player->is_playing()) {
stop->set_icon(pause_icon);
} else {
stop->set_icon(stop_icon);
}
- autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")));
- play->set_icon(get_theme_icon(SNAME("PlayStart"), SNAME("EditorIcons")));
- play_from->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
- play_bw->set_icon(get_theme_icon(SNAME("PlayStartBackwards"), SNAME("EditorIcons")));
- play_bw_from->set_icon(get_theme_icon(SNAME("PlayBackwards"), SNAME("EditorIcons")));
+ autoplay->set_icon(get_editor_theme_icon(SNAME("AutoPlay")));
+ play->set_icon(get_editor_theme_icon(SNAME("PlayStart")));
+ play_from->set_icon(get_editor_theme_icon(SNAME("Play")));
+ play_bw->set_icon(get_editor_theme_icon(SNAME("PlayStartBackwards")));
+ play_bw_from->set_icon(get_editor_theme_icon(SNAME("PlayBackwards")));
- autoplay_icon = get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons"));
- reset_icon = get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"));
+ autoplay_icon = get_editor_theme_icon(SNAME("AutoPlay"));
+ reset_icon = get_editor_theme_icon(SNAME("Reload"));
{
Ref<Image> autoplay_img = autoplay_icon->get_image();
Ref<Image> reset_img = reset_icon->get_image();
@@ -147,15 +147,15 @@ void AnimationPlayerEditor::_notification(int p_what) {
autoplay_reset_icon = ImageTexture::create_from_image(autoplay_reset_img);
}
- onion_toggle->set_icon(get_theme_icon(SNAME("Onion"), SNAME("EditorIcons")));
- onion_skinning->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ onion_toggle->set_icon(get_editor_theme_icon(SNAME("Onion")));
+ onion_skinning->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
- pin->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
+ pin->set_icon(get_editor_theme_icon(SNAME("Pin")));
tool_anim->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("Button")));
track_editor->get_edit_menu()->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("Button")));
-#define ITEM_ICON(m_item, m_icon) tool_anim->get_popup()->set_item_icon(tool_anim->get_popup()->get_item_index(m_item), get_theme_icon(SNAME(m_icon), SNAME("EditorIcons")))
+#define ITEM_ICON(m_item, m_icon) tool_anim->get_popup()->set_item_icon(tool_anim->get_popup()->get_item_index(m_item), get_editor_theme_icon(SNAME(m_icon)))
ITEM_ICON(TOOL_NEW_ANIM, "New");
ITEM_ICON(TOOL_ANIM_LIBRARY, "AnimationLibrary");
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 0b2af0172c..5e40a2f986 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "scene/animation/animation_blend_tree.h"
@@ -554,7 +555,7 @@ void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) {
List<StringName> names;
ap->get_animation_list(&names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- animations_menu->add_icon_item(get_theme_icon("Animation", "EditorIcons"), E->get());
+ animations_menu->add_icon_item(get_editor_theme_icon("Animation"), E->get());
animations_to_add.push_back(E->get());
}
}
@@ -824,7 +825,7 @@ void AnimationNodeStateMachineEditor::_add_transition(const bool p_nested_action
void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, float p_fade_ratio, bool p_auto_advance, bool p_is_across_group) {
Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label"));
Color icon_color(1, 1, 1);
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
if (!p_enabled) {
linecolor.a *= 0.2;
@@ -833,12 +834,12 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co
}
const Ref<Texture2D> icons[] = {
- get_theme_icon(SNAME("TransitionImmediateBig"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TransitionSyncBig"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TransitionEndBig"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TransitionImmediateAutoBig"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TransitionSyncAutoBig"), SNAME("EditorIcons")),
- get_theme_icon(SNAME("TransitionEndAutoBig"), SNAME("EditorIcons"))
+ get_editor_theme_icon(SNAME("TransitionImmediateBig")),
+ get_editor_theme_icon(SNAME("TransitionSyncBig")),
+ get_editor_theme_icon(SNAME("TransitionEndBig")),
+ get_editor_theme_icon(SNAME("TransitionImmediateAutoBig")),
+ get_editor_theme_icon(SNAME("TransitionSyncAutoBig")),
+ get_editor_theme_icon(SNAME("TransitionEndAutoBig"))
};
const int ICON_COUNT = sizeof(icons) / sizeof(*icons);
@@ -911,9 +912,9 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<Font> font = get_theme_font(SNAME("title_font"), SNAME("GraphNode"));
int font_size = get_theme_font_size(SNAME("title_font_size"), SNAME("GraphNode"));
Color font_color = get_theme_color(SNAME("title_color"), SNAME("GraphNode"));
- Ref<Texture2D> play = get_theme_icon(SNAME("Play"), SNAME("EditorIcons"));
- Ref<Texture2D> edit = get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"));
- Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Ref<Texture2D> play = get_editor_theme_icon(SNAME("Play"));
+ Ref<Texture2D> edit = get_editor_theme_icon(SNAME("Edit"));
+ Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label"));
linecolor.a *= 0.3;
Ref<StyleBox> playing_overlay = get_theme_stylebox(SNAME("position"), SNAME("GraphNode"));
@@ -1027,7 +1028,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
_connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(switch_mode->get_selected()), true, false, false, 0.0, false, false);
}
- Ref<Texture2D> tr_reference_icon = get_theme_icon(SNAME("TransitionImmediateBig"), SNAME("EditorIcons"));
+ Ref<Texture2D> tr_reference_icon = get_editor_theme_icon(SNAME("TransitionImmediateBig"));
float tr_bidi_offset = int(tr_reference_icon->get_height() * 0.8);
//draw transition lines
@@ -1302,25 +1303,25 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("ToolAddNode"), SNAME("EditorIcons")));
- tool_connect->set_icon(get_theme_icon(SNAME("ToolConnect"), SNAME("EditorIcons")));
+ tool_select->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ tool_create->set_icon(get_editor_theme_icon(SNAME("ToolAddNode")));
+ tool_connect->set_icon(get_editor_theme_icon(SNAME("ToolConnect")));
switch_mode->clear();
- switch_mode->add_icon_item(get_theme_icon(SNAME("TransitionImmediate"), SNAME("EditorIcons")), TTR("Immediate"));
- switch_mode->add_icon_item(get_theme_icon(SNAME("TransitionSync"), SNAME("EditorIcons")), TTR("Sync"));
- switch_mode->add_icon_item(get_theme_icon(SNAME("TransitionEnd"), SNAME("EditorIcons")), TTR("At End"));
+ switch_mode->add_icon_item(get_editor_theme_icon(SNAME("TransitionImmediate")), TTR("Immediate"));
+ switch_mode->add_icon_item(get_editor_theme_icon(SNAME("TransitionSync")), TTR("Sync"));
+ switch_mode->add_icon_item(get_editor_theme_icon(SNAME("TransitionEnd")), TTR("At End"));
- auto_advance->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")));
+ auto_advance->set_icon(get_editor_theme_icon(SNAME("AutoPlay")));
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ tool_erase->set_icon(get_editor_theme_icon(SNAME("Remove")));
play_mode->clear();
- play_mode->add_icon_item(get_theme_icon(SNAME("PlayTravel"), SNAME("EditorIcons")), TTR("Travel"));
- play_mode->add_icon_item(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")), TTR("Immediate"));
+ play_mode->add_icon_item(get_editor_theme_icon(SNAME("PlayTravel")), TTR("Travel"));
+ play_mode->add_icon_item(get_editor_theme_icon(SNAME("Play")), TTR("Immediate"));
} break;
case NOTIFICATION_PROCESS: {
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 5c26199af1..5611296019 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/project_settings_editor.h"
#include "scene/gui/menu_button.h"
@@ -73,7 +74,7 @@ void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Textur
void EditorAssetLibraryItem::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- icon->set_texture_normal(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons")));
+ icon->set_texture_normal(get_editor_theme_icon(SNAME("ProjectIconLoading")));
category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
price->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
@@ -157,7 +158,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
if (preview_images[i].is_video) {
- Ref<Image> overlay = previews->get_theme_icon(SNAME("PlayOverlay"), SNAME("EditorIcons"))->get_image();
+ Ref<Image> overlay = previews->get_editor_theme_icon(SNAME("PlayOverlay"))->get_image();
Ref<Image> thumbnail = p_image->get_image();
thumbnail = thumbnail->duplicate();
Point2i overlay_pos = Point2i((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2);
@@ -251,12 +252,12 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
new_preview.video_link = p_url;
new_preview.is_video = p_video;
new_preview.button = memnew(Button);
- new_preview.button->set_icon(previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons")));
+ new_preview.button->set_icon(previews->get_editor_theme_icon(SNAME("ThumbnailWait")));
new_preview.button->set_toggle_mode(true);
new_preview.button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click).bind(p_id));
preview_hb->add_child(new_preview.button);
if (!p_video) {
- new_preview.image = previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons"));
+ new_preview.image = previews->get_editor_theme_icon(SNAME("ThumbnailWait"));
}
preview_images.push_back(new_preview);
if (preview_images.size() == 1 && !p_video) {
@@ -392,7 +393,7 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse
icon->set_texture(p_preview);
asset_id = p_asset_id;
if (!p_preview.is_valid()) {
- icon->set_texture(get_theme_icon(SNAME("FileBrokenBigThumb"), SNAME("EditorIcons")));
+ icon->set_texture(get_editor_theme_icon(SNAME("FileBrokenBigThumb")));
}
host = p_download_url;
sha256 = p_sha256_hash;
@@ -582,11 +583,11 @@ void EditorAssetLibrary::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- error_tr->set_texture(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
- filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ error_tr->set_texture(get_editor_theme_icon(SNAME("Error")));
+ filter->set_right_icon(get_editor_theme_icon(SNAME("Search")));
library_scroll_bg->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
downloads_scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -808,7 +809,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB
}
if (!image_set && final) {
- obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_theme_icon(SNAME("FileBrokenBigThumb"), SNAME("EditorIcons")));
+ obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_editor_theme_icon(SNAME("FileBrokenBigThumb")));
}
}
}
@@ -845,7 +846,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
WARN_PRINT("Error getting image file from URL: " + image_queue[p_queue_id].image_url);
Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
if (obj) {
- obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_theme_icon(SNAME("FileBrokenBigThumb"), SNAME("EditorIcons")));
+ obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_editor_theme_icon(SNAME("FileBrokenBigThumb")));
}
}
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index 89579150c2..2be9528019 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "editor/audio_stream_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/resources/audio_stream_wav.h"
// AudioStreamEditor
@@ -44,16 +45,16 @@ void AudioStreamEditor::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
- Ref<Font> font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts));
_current_label->add_theme_font_override(SNAME("font"), font);
_duration_label->add_theme_font_override(SNAME("font"), font);
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
- _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
- _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
+ _stop_button->set_icon(get_editor_theme_icon(SNAME("Stop")));
+ _preview->set_color(get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)));
- set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor")));
+ set_color(get_theme_color(SNAME("dark_color_1"), EditorStringName(Editor)));
_indicator->queue_redraw();
_preview->queue_redraw();
@@ -98,7 +99,7 @@ void AudioStreamEditor::_draw_preview() {
points.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
}
- Vector<Color> colors = { get_theme_color(SNAME("contrast_color_2"), SNAME("Editor")) };
+ Vector<Color> colors = { get_theme_color(SNAME("contrast_color_2"), EditorStringName(Editor)) };
RS::get_singleton()->canvas_item_add_multiline(_preview->get_canvas_item(), points, colors);
}
@@ -120,26 +121,26 @@ void AudioStreamEditor::_play() {
if (_player->is_playing()) {
_pausing = true;
_player->stop();
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
set_process(false);
} else {
_pausing = false;
_player->play(_current);
- _play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("Pause")));
set_process(true);
}
}
void AudioStreamEditor::_stop() {
_player->stop();
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
_current = 0;
_indicator->queue_redraw();
set_process(false);
}
void AudioStreamEditor::_on_finished() {
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay")));
if (!_pausing) {
_current = 0;
_indicator->queue_redraw();
@@ -157,8 +158,8 @@ void AudioStreamEditor::_draw_indicator() {
Rect2 rect = _preview->get_rect();
float len = stream->get_length();
float ofs_x = _current / len * rect.size.width;
- const Color col = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
- Ref<Texture2D> icon = get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons"));
+ const Color col = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("TimelineIndicator"));
_indicator->draw_line(Point2(ofs_x, 0), Point2(ofs_x, rect.size.height), col, Math::round(2 * EDSCALE));
_indicator->draw_texture(
icon,
diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp
index 3d94dd13a7..2c9cff3eff 100644
--- a/editor/plugins/bone_map_editor_plugin.cpp
+++ b/editor/plugins/bone_map_editor_plugin.cpp
@@ -42,9 +42,9 @@
void BoneMapperButton::fetch_textures() {
if (selected) {
- set_texture_normal(get_theme_icon(SNAME("BoneMapperHandleSelected"), SNAME("EditorIcons")));
+ set_texture_normal(get_editor_theme_icon(SNAME("BoneMapperHandleSelected")));
} else {
- set_texture_normal(get_theme_icon(SNAME("BoneMapperHandle"), SNAME("EditorIcons")));
+ set_texture_normal(get_editor_theme_icon(SNAME("BoneMapperHandle")));
}
set_offset(SIDE_LEFT, 0);
set_offset(SIDE_RIGHT, 0);
@@ -55,7 +55,7 @@ void BoneMapperButton::fetch_textures() {
set_modulate(EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25));
circle = memnew(TextureRect);
- circle->set_texture(get_theme_icon(SNAME("BoneMapperHandleCircle"), SNAME("EditorIcons")));
+ circle->set_texture(get_editor_theme_icon(SNAME("BoneMapperHandleCircle")));
add_child(circle);
set_state(BONE_MAP_STATE_UNSET);
}
@@ -118,7 +118,7 @@ void BoneMapperItem::create_editor() {
hbox->add_child(skeleton_bone_selector);
picker_button = memnew(Button);
- picker_button->set_icon(get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons")));
+ picker_button->set_icon(get_editor_theme_icon(SNAME("ClassList")));
picker_button->connect("pressed", callable_mp(this, &BoneMapperItem::_open_picker));
hbox->add_child(picker_button);
@@ -194,7 +194,7 @@ void BonePicker::create_bones_tree(Skeleton3D *p_skeleton) {
items.insert(-1, root);
- Ref<Texture> bone_icon = get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"));
+ Ref<Texture> bone_icon = get_editor_theme_icon(SNAME("BoneAttachment3D"));
Vector<int> bones_to_process = p_skeleton->get_parentless_bones();
bool is_first = true;
@@ -297,7 +297,7 @@ void BoneMapper::create_editor() {
group_hbox->add_child(profile_group_selector);
clear_mapping_button = memnew(Button);
- clear_mapping_button->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
+ clear_mapping_button->set_icon(get_editor_theme_icon(SNAME("Clear")));
clear_mapping_button->set_tooltip_text(TTR("Clear mappings in current group."));
clear_mapping_button->connect("pressed", callable_mp(this, &BoneMapper::_clear_mapping_current_group));
group_hbox->add_child(clear_mapping_button);
@@ -398,13 +398,13 @@ void BoneMapper::recreate_editor() {
if (hmn) {
StringName hmn_group_name = profile->get_group_name(current_group_idx);
if (hmn_group_name == "Body") {
- profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanBody"), SNAME("EditorIcons")));
+ profile_texture->set_texture(get_editor_theme_icon(SNAME("BoneMapHumanBody")));
} else if (hmn_group_name == "Face") {
- profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanFace"), SNAME("EditorIcons")));
+ profile_texture->set_texture(get_editor_theme_icon(SNAME("BoneMapHumanFace")));
} else if (hmn_group_name == "LeftHand") {
- profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanLeftHand"), SNAME("EditorIcons")));
+ profile_texture->set_texture(get_editor_theme_icon(SNAME("BoneMapHumanLeftHand")));
} else if (hmn_group_name == "RightHand") {
- profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanRightHand"), SNAME("EditorIcons")));
+ profile_texture->set_texture(get_editor_theme_icon(SNAME("BoneMapHumanRightHand")));
}
} else {
profile_texture->set_texture(profile->get_texture(current_group_idx));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 832d0c204d..703cd7ef81 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_run_bar.h"
#include "editor/gui/editor_toaster.h"
@@ -1033,6 +1034,22 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) {
viewport->queue_redraw();
}
+void CanvasItemEditor::_switch_theme_preview(int p_mode) {
+ view_menu->get_popup()->hide();
+
+ if (theme_preview == p_mode) {
+ return;
+ }
+ theme_preview = (ThemePreviewMode)p_mode;
+ EditorSettings::get_singleton()->set_project_metadata("2d_editor", "theme_preview", theme_preview);
+
+ for (int i = 0; i < THEME_PREVIEW_MAX; i++) {
+ theme_menu->set_item_checked(i, i == theme_preview);
+ }
+
+ EditorNode::get_singleton()->update_preview_themes(theme_preview);
+}
+
bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
Ref<InputEventMouseButton> b = p_event;
@@ -2293,17 +2310,17 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::RIGHT) {
add_node_menu->clear();
- add_node_menu->add_icon_item(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here..."), ADD_NODE);
- add_node_menu->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate Scene Here..."), ADD_INSTANCE);
+ add_node_menu->add_icon_item(get_editor_theme_icon(SNAME("Add")), TTR("Add Node Here..."), ADD_NODE);
+ add_node_menu->add_icon_item(get_editor_theme_icon(SNAME("Instance")), TTR("Instantiate Scene Here..."), ADD_INSTANCE);
for (Node *node : SceneTreeDock::get_singleton()->get_node_clipboard()) {
if (Object::cast_to<CanvasItem>(node)) {
- add_node_menu->add_icon_item(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), TTR("Paste Node(s) Here"), ADD_PASTE);
+ add_node_menu->add_icon_item(get_editor_theme_icon(SNAME("ActionPaste")), TTR("Paste Node(s) Here"), ADD_PASTE);
break;
}
}
for (Node *node : EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()) {
if (Object::cast_to<CanvasItem>(node)) {
- add_node_menu->add_icon_item(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")), TTR("Move Node(s) Here"), ADD_MOVE);
+ add_node_menu->add_icon_item(get_editor_theme_icon(SNAME("ToolMove")), TTR("Move Node(s) Here"), ADD_MOVE);
break;
}
}
@@ -2678,7 +2695,7 @@ Control::CursorShape CanvasItemEditor::get_cursor_shape(const Point2 &p_pos) con
}
void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string, Side p_side) {
- Color color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
color.a = 0.8;
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
@@ -2717,7 +2734,7 @@ void CanvasItemEditor::_draw_percentage_at_position(real_t p_value, Point2 p_pos
void CanvasItemEditor::_draw_focus() {
// Draw the focus around the base viewport
if (viewport->has_focus()) {
- get_theme_stylebox(SNAME("FocusViewport"), SNAME("EditorStyles"))->draw(viewport->get_canvas_item(), Rect2(Point2(), viewport->get_size()));
+ get_theme_stylebox(SNAME("FocusViewport"), EditorStringName(EditorStyles))->draw(viewport->get_canvas_item(), Rect2(Point2(), viewport->get_size()));
}
}
@@ -2747,13 +2764,13 @@ void CanvasItemEditor::_draw_guides() {
}
// Dragged guide.
- Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color text_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
Color outline_color = text_color.inverted();
const float outline_size = 2;
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x)));
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
viewport->draw_string_outline(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
@@ -2761,8 +2778,8 @@ void CanvasItemEditor::_draw_guides() {
}
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y)));
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
viewport->draw_string_outline(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
@@ -2785,12 +2802,12 @@ void CanvasItemEditor::_draw_smart_snapping() {
}
void CanvasItemEditor::_draw_rulers() {
- Color bg_color = get_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
- Color graduation_color = get_theme_color(SNAME("font_color"), SNAME("Editor")).lerp(bg_color, 0.5);
- Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color bg_color = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor));
+ Color graduation_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor)).lerp(bg_color, 0.5);
+ Color font_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
font_color.a = 0.8;
- Ref<Font> font = get_theme_font(SNAME("rulers"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("rulers_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("rulers"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("rulers_size"), EditorStringName(EditorFonts));
// The rule transform
Transform2D ruler_transform;
@@ -2951,7 +2968,7 @@ void CanvasItemEditor::_draw_ruler_tool() {
}
if (ruler_tool_active) {
- Color ruler_primary_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color ruler_primary_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
Color ruler_secondary_color = ruler_primary_color;
ruler_secondary_color.a = 0.5;
@@ -2963,9 +2980,9 @@ void CanvasItemEditor::_draw_ruler_tool() {
const real_t horizontal_angle_rad = length_vector.angle();
const real_t vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad;
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
- Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = 1.3 * get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
+ Color font_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
Color font_secondary_color = font_color;
font_secondary_color.set_v(font_secondary_color.get_v() > 0.5 ? 0.7 : 0.3);
Color outline_color = font_color.inverted();
@@ -3018,8 +3035,8 @@ void CanvasItemEditor::_draw_ruler_tool() {
if (begin.is_equal_approx(end)) {
viewport->draw_string_outline(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
- Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
- viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
+ Ref<Texture2D> position_icon = get_editor_theme_icon(SNAME("EditorPosition"));
+ viewport->draw_texture(get_editor_theme_icon(SNAME("EditorPosition")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
return;
}
@@ -3090,8 +3107,8 @@ void CanvasItemEditor::_draw_ruler_tool() {
}
} else {
if (grid_snap_active) {
- Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
- viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
+ Ref<Texture2D> position_icon = get_editor_theme_icon(SNAME("EditorPosition"));
+ viewport->draw_texture(get_editor_theme_icon(SNAME("EditorPosition")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
}
}
}
@@ -3308,9 +3325,9 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
}
void CanvasItemEditor::_draw_selection() {
- Ref<Texture2D> pivot_icon = get_theme_icon(SNAME("EditorPivot"), SNAME("EditorIcons"));
- Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
- Ref<Texture2D> previous_position_icon = get_theme_icon(SNAME("EditorPositionPrevious"), SNAME("EditorIcons"));
+ Ref<Texture2D> pivot_icon = get_editor_theme_icon(SNAME("EditorPivot"));
+ Ref<Texture2D> position_icon = get_editor_theme_icon(SNAME("EditorPosition"));
+ Ref<Texture2D> previous_position_icon = get_editor_theme_icon(SNAME("EditorPositionPrevious"));
RID vp_ci = viewport->get_canvas_item();
@@ -3437,16 +3454,16 @@ void CanvasItemEditor::_draw_selection() {
Vector2((move_factor.x + 10) * EDSCALE, 0)
};
- viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
- viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")), Math::round(EDSCALE));
+ viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
points.clear();
points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE));
points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE));
points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE));
- viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
- viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), SNAME("Editor")), Math::round(EDSCALE));
+ viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
viewport->draw_set_transform_matrix(viewport->get_transform());
}
@@ -3476,12 +3493,12 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_set_transform_matrix(simple_xform);
Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
- viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")), Math::round(EDSCALE));
+ viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE));
Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
- viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
- viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), SNAME("Editor")), Math::round(EDSCALE));
+ viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE));
viewport->draw_set_transform_matrix(viewport->get_transform());
}
@@ -3496,11 +3513,11 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_rect(
Rect2(bsfrom, bsto - bsfrom),
- get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")));
+ get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
viewport->draw_rect(
Rect2(bsfrom, bsto - bsfrom),
- get_theme_color(SNAME("box_selection_stroke_color"), SNAME("Editor")),
+ get_theme_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)),
false,
Math::round(EDSCALE));
}
@@ -3510,7 +3527,7 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_line(
transform.xform(drag_rotation_center),
transform.xform(drag_to),
- get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.6),
+ get_theme_color(SNAME("accent_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6),
Math::round(2 * EDSCALE));
}
}
@@ -3558,8 +3575,8 @@ void CanvasItemEditor::_draw_straight_line(Point2 p_from, Point2 p_to, Color p_c
void CanvasItemEditor::_draw_axis() {
if (show_origin) {
- _draw_straight_line(Point2(), Point2(1, 0), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")) * Color(1, 1, 1, 0.75));
- _draw_straight_line(Point2(), Point2(0, 1), get_theme_color(SNAME("axis_y_color"), SNAME("Editor")) * Color(1, 1, 1, 0.75));
+ _draw_straight_line(Point2(), Point2(1, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.75));
+ _draw_straight_line(Point2(), Point2(0, 1), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.75));
}
if (show_viewport) {
@@ -3613,7 +3630,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
Transform2D xform = transform * canvas_xform * parent_xform;
// Draw the node's position
- Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPositionUnselected"), SNAME("EditorIcons"));
+ Ref<Texture2D> position_icon = get_editor_theme_icon(SNAME("EditorPositionUnselected"));
Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized();
Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
viewport->draw_set_transform_matrix(simple_xform);
@@ -3744,13 +3761,13 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
if (ci) {
real_t offset = 0;
- Ref<Texture2D> lock = get_theme_icon(SNAME("LockViewport"), SNAME("EditorIcons"));
+ Ref<Texture2D> lock = get_editor_theme_icon(SNAME("LockViewport"));
if (p_node->has_meta("_edit_lock_") && show_edit_locks) {
lock->draw(viewport_ci, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0));
offset += lock->get_size().x;
}
- Ref<Texture2D> group = get_theme_icon(SNAME("GroupViewport"), SNAME("EditorIcons"));
+ Ref<Texture2D> group = get_editor_theme_icon(SNAME("GroupViewport"));
if (ci->has_meta("_edit_group_") && show_edit_locks) {
group->draw(viewport_ci, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0));
//offset += group->get_size().x;
@@ -3837,41 +3854,41 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) {
}
void CanvasItemEditor::_update_editor_settings() {
- button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
- select_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
- list_select_button->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
- move_button->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
- scale_button->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
- rotate_button->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
- smart_snap_button->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- grid_snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- snap_config_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- skeleton_menu->set_icon(get_theme_icon(SNAME("Bone"), SNAME("EditorIcons")));
- override_camera_button->set_icon(get_theme_icon(SNAME("Camera2D"), SNAME("EditorIcons")));
- pan_button->set_icon(get_theme_icon(SNAME("ToolPan"), SNAME("EditorIcons")));
- ruler_button->set_icon(get_theme_icon(SNAME("Ruler"), SNAME("EditorIcons")));
- pivot_button->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- select_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
- anchor_handle = get_theme_icon(SNAME("EditorControlAnchor"), SNAME("EditorIcons"));
- lock_button->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
- unlock_button->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
- group_button->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
- ungroup_button->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
- key_loc_button->set_icon(get_theme_icon(SNAME("KeyPosition"), SNAME("EditorIcons")));
- key_rot_button->set_icon(get_theme_icon(SNAME("KeyRotation"), SNAME("EditorIcons")));
- key_scale_button->set_icon(get_theme_icon(SNAME("KeyScale"), SNAME("EditorIcons")));
- key_insert_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
- key_auto_insert_button->set_icon(get_theme_icon(SNAME("AutoKey"), SNAME("EditorIcons")));
+ button_center_view->set_icon(get_editor_theme_icon(SNAME("CenterView")));
+ select_button->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ select_sb->set_texture(get_editor_theme_icon(SNAME("EditorRect2D")));
+ list_select_button->set_icon(get_editor_theme_icon(SNAME("ListSelect")));
+ move_button->set_icon(get_editor_theme_icon(SNAME("ToolMove")));
+ scale_button->set_icon(get_editor_theme_icon(SNAME("ToolScale")));
+ rotate_button->set_icon(get_editor_theme_icon(SNAME("ToolRotate")));
+ smart_snap_button->set_icon(get_editor_theme_icon(SNAME("Snap")));
+ grid_snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
+ snap_config_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ skeleton_menu->set_icon(get_editor_theme_icon(SNAME("Bone")));
+ override_camera_button->set_icon(get_editor_theme_icon(SNAME("Camera2D")));
+ pan_button->set_icon(get_editor_theme_icon(SNAME("ToolPan")));
+ ruler_button->set_icon(get_editor_theme_icon(SNAME("Ruler")));
+ pivot_button->set_icon(get_editor_theme_icon(SNAME("EditPivot")));
+ select_handle = get_editor_theme_icon(SNAME("EditorHandle"));
+ anchor_handle = get_editor_theme_icon(SNAME("EditorControlAnchor"));
+ lock_button->set_icon(get_editor_theme_icon(SNAME("Lock")));
+ unlock_button->set_icon(get_editor_theme_icon(SNAME("Unlock")));
+ group_button->set_icon(get_editor_theme_icon(SNAME("Group")));
+ ungroup_button->set_icon(get_editor_theme_icon(SNAME("Ungroup")));
+ key_loc_button->set_icon(get_editor_theme_icon(SNAME("KeyPosition")));
+ key_rot_button->set_icon(get_editor_theme_icon(SNAME("KeyRotation")));
+ key_scale_button->set_icon(get_editor_theme_icon(SNAME("KeyScale")));
+ key_insert_button->set_icon(get_editor_theme_icon(SNAME("Key")));
+ key_auto_insert_button->set_icon(get_editor_theme_icon(SNAME("AutoKey")));
// Use a different color for the active autokey icon to make them easier
// to distinguish from the other key icons at the top. On a light theme,
// the icon will be dark, so we need to lighten it before blending it
// with the red color.
const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
- animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ animation_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
- context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
+ context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
panner->set_scroll_speed(EDITOR_GET("editors/panning/2d_editor_pan_speed"));
@@ -3962,7 +3979,7 @@ void CanvasItemEditor::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
- select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
+ select_sb->set_texture(get_editor_theme_icon(SNAME("EditorRect2D")));
select_sb->set_texture_margin_all(4);
select_sb->set_content_margin_all(4);
@@ -5321,6 +5338,20 @@ CanvasItemEditor::CanvasItemEditor() {
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale")), PREVIEW_CANVAS_SCALE);
+ theme_menu = memnew(PopupMenu);
+ theme_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_switch_theme_preview));
+ theme_menu->set_name("ThemeMenu");
+ theme_menu->add_radio_check_item(TTR("Project theme"), THEME_PREVIEW_PROJECT);
+ theme_menu->add_radio_check_item(TTR("Editor theme"), THEME_PREVIEW_EDITOR);
+ theme_menu->add_radio_check_item(TTR("Default theme"), THEME_PREVIEW_DEFAULT);
+ p->add_child(theme_menu);
+ p->add_submenu_item(TTR("Preview Theme"), "ThemeMenu");
+
+ theme_preview = (ThemePreviewMode)(int)EditorSettings::get_singleton()->get_project_metadata("2d_editor", "theme_preview", THEME_PREVIEW_PROJECT);
+ for (int i = 0; i < THEME_PREVIEW_MAX; i++) {
+ theme_menu->set_item_checked(i, i == theme_preview);
+ }
+
main_menu_hbox->add_child(memnew(VSeparator));
// Contextual toolbars.
@@ -5870,10 +5901,10 @@ void CanvasItemEditorViewport::_update_theme() {
for (int i = 0; i < btn_list.size(); i++) {
CheckBox *check = Object::cast_to<CheckBox>(btn_list[i]);
- check->set_icon(get_theme_icon(check->get_text(), SNAME("EditorIcons")));
+ check->set_icon(get_editor_theme_icon(check->get_text()));
}
- label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
}
void CanvasItemEditorViewport::_notification(int p_what) {
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 74f150fd65..674f38c8c0 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -325,6 +325,7 @@ private:
Button *override_camera_button = nullptr;
MenuButton *view_menu = nullptr;
PopupMenu *grid_menu = nullptr;
+ PopupMenu *theme_menu = nullptr;
HBoxContainer *animation_hb = nullptr;
MenuButton *animation_menu = nullptr;
@@ -404,6 +405,19 @@ private:
void _prepare_grid_menu();
void _on_grid_menu_id_pressed(int p_id);
+public:
+ enum ThemePreviewMode {
+ THEME_PREVIEW_PROJECT,
+ THEME_PREVIEW_EDITOR,
+ THEME_PREVIEW_DEFAULT,
+
+ THEME_PREVIEW_MAX // The number of options for enumerating.
+ };
+
+private:
+ ThemePreviewMode theme_preview = THEME_PREVIEW_PROJECT;
+ void _switch_theme_preview(int p_mode);
+
List<CanvasItem *> _get_edited_canvas_items(bool retrieve_locked = false, bool remove_canvas_item_if_parent_in_selection = true) const;
Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list);
void _expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D(), bool include_locked_nodes = true);
@@ -558,6 +572,8 @@ public:
virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override;
+ ThemePreviewMode get_theme_preview() const { return theme_preview; }
+
EditorSelection *editor_selection = nullptr;
CanvasItemEditor();
diff --git a/editor/plugins/cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp
index 331b4749cc..a6457e38a7 100644
--- a/editor/plugins/cast_2d_editor_plugin.cpp
+++ b/editor/plugins/cast_2d_editor_plugin.cpp
@@ -113,7 +113,7 @@ void Cast2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorHandle"));
p_overlay->draw_texture(handle, gt.xform((Vector2)node->get("target_position")) - handle->get_size() / 2);
}
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 65e7ee0a3d..a2feea8488 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -435,7 +435,7 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Ref<Texture2D> h = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> h = get_editor_theme_icon(SNAME("EditorHandle"));
Vector2 size = h->get_size() * 0.5;
handles.clear();
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index d7c4686bbf..f1667d14ab 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -50,15 +50,15 @@ void ControlPositioningWarning::_update_warning() {
Node *parent_node = control_node->get_parent_control();
if (!parent_node) {
- title_icon->set_texture(get_theme_icon(SNAME("SubViewport"), SNAME("EditorIcons")));
+ title_icon->set_texture(get_editor_theme_icon(SNAME("SubViewport")));
title_label->set_text(TTR("This node doesn't have a control parent."));
hint_label->set_text(TTR("Use the appropriate layout properties depending on where you are going to put it."));
} else if (Object::cast_to<Container>(parent_node)) {
- title_icon->set_texture(get_theme_icon(SNAME("ContainerLayout"), SNAME("EditorIcons")));
+ title_icon->set_texture(get_editor_theme_icon(SNAME("ContainerLayout")));
title_label->set_text(TTR("This node is a child of a container."));
hint_label->set_text(TTR("Use container properties for positioning."));
} else {
- title_icon->set_texture(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
+ title_icon->set_texture(get_editor_theme_icon(SNAME("ControlLayout")));
title_label->set_text(TTR("This node is a child of a regular control."));
hint_label->set_text(TTR("Use anchors and the rectangle for positioning."));
}
@@ -193,7 +193,7 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) {
String preset_name = option_name.trim_prefix("Preset");
String humanized_name = preset_name.capitalize();
String icon_name = "ControlAlign" + preset_name;
- options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(icon_name, "EditorIcons"), humanized_name);
+ options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(icon_name), humanized_name);
} else {
options->add_item(option_name);
}
@@ -369,15 +369,15 @@ void EditorPropertySizeFlags::setup(const Vector<String> &p_options, bool p_vert
flag_presets->clear();
if (flags.has(SIZE_FILL)) {
- flag_presets->add_icon_item(gui_base->get_theme_icon(wide_preset_icon, SNAME("EditorIcons")), TTR("Fill"), SIZE_FLAGS_PRESET_FILL);
+ flag_presets->add_icon_item(gui_base->get_editor_theme_icon(wide_preset_icon), TTR("Fill"), SIZE_FLAGS_PRESET_FILL);
}
// Shrink Begin is the same as no flags at all, as such it cannot be disabled.
- flag_presets->add_icon_item(gui_base->get_theme_icon(begin_preset_icon, SNAME("EditorIcons")), TTR("Shrink Begin"), SIZE_FLAGS_PRESET_SHRINK_BEGIN);
+ flag_presets->add_icon_item(gui_base->get_editor_theme_icon(begin_preset_icon), TTR("Shrink Begin"), SIZE_FLAGS_PRESET_SHRINK_BEGIN);
if (flags.has(SIZE_SHRINK_CENTER)) {
- flag_presets->add_icon_item(gui_base->get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), SIZE_FLAGS_PRESET_SHRINK_CENTER);
+ flag_presets->add_icon_item(gui_base->get_editor_theme_icon(SNAME("ControlAlignCenter")), TTR("Shrink Center"), SIZE_FLAGS_PRESET_SHRINK_CENTER);
}
if (flags.has(SIZE_SHRINK_END)) {
- flag_presets->add_icon_item(gui_base->get_theme_icon(end_preset_icon, SNAME("EditorIcons")), TTR("Shrink End"), SIZE_FLAGS_PRESET_SHRINK_END);
+ flag_presets->add_icon_item(gui_base->get_editor_theme_icon(end_preset_icon), TTR("Shrink End"), SIZE_FLAGS_PRESET_SHRINK_END);
}
flag_presets->add_separator();
flag_presets->add_item(TTR("Custom"), SIZE_FLAGS_PRESET_CUSTOM);
@@ -561,27 +561,27 @@ void AnchorPresetPicker::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- preset_buttons[PRESET_TOP_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")));
- preset_buttons[PRESET_CENTER_TOP]->set_icon(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")));
- preset_buttons[PRESET_TOP_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_TOP_LEFT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignTopLeft")));
+ preset_buttons[PRESET_CENTER_TOP]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop")));
+ preset_buttons[PRESET_TOP_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignTopRight")));
- preset_buttons[PRESET_CENTER_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")));
- preset_buttons[PRESET_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")));
- preset_buttons[PRESET_CENTER_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_CENTER_LEFT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft")));
+ preset_buttons[PRESET_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter")));
+ preset_buttons[PRESET_CENTER_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight")));
- preset_buttons[PRESET_BOTTOM_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")));
- preset_buttons[PRESET_CENTER_BOTTOM]->set_icon(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")));
- preset_buttons[PRESET_BOTTOM_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_BOTTOM_LEFT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomLeft")));
+ preset_buttons[PRESET_CENTER_BOTTOM]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom")));
+ preset_buttons[PRESET_BOTTOM_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomRight")));
- preset_buttons[PRESET_TOP_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")));
- preset_buttons[PRESET_HCENTER_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")));
- preset_buttons[PRESET_BOTTOM_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_TOP_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignTopWide")));
+ preset_buttons[PRESET_HCENTER_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide")));
+ preset_buttons[PRESET_BOTTOM_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomWide")));
- preset_buttons[PRESET_LEFT_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")));
- preset_buttons[PRESET_VCENTER_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")));
- preset_buttons[PRESET_RIGHT_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_LEFT_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignLeftWide")));
+ preset_buttons[PRESET_VCENTER_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide")));
+ preset_buttons[PRESET_RIGHT_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignRightWide")));
- preset_buttons[PRESET_FULL_RECT]->set_icon(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons")));
+ preset_buttons[PRESET_FULL_RECT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignFullRect")));
} break;
}
}
@@ -671,17 +671,17 @@ void SizeFlagPresetPicker::_notification(int p_notification) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
if (vertical) {
- preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")));
- preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")));
- preset_buttons[SIZE_SHRINK_END]->set_icon(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")));
+ preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop")));
+ preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter")));
+ preset_buttons[SIZE_SHRINK_END]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom")));
- preset_buttons[SIZE_FILL]->set_icon(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")));
+ preset_buttons[SIZE_FILL]->set_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide")));
} else {
- preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")));
- preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")));
- preset_buttons[SIZE_SHRINK_END]->set_icon(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")));
+ preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft")));
+ preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter")));
+ preset_buttons[SIZE_SHRINK_END]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight")));
- preset_buttons[SIZE_FILL]->set_icon(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")));
+ preset_buttons[SIZE_FILL]->set_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide")));
}
} break;
}
@@ -968,9 +968,9 @@ void ControlEditorToolbar::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- anchors_button->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
- anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
- containers_button->set_icon(get_theme_icon(SNAME("ContainerLayout"), SNAME("EditorIcons")));
+ anchors_button->set_icon(get_editor_theme_icon(SNAME("ControlLayout")));
+ anchor_mode_button->set_icon(get_editor_theme_icon(SNAME("Anchor")));
+ containers_button->set_icon(get_editor_theme_icon(SNAME("ContainerLayout")));
} break;
}
}
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 3ac9fee03f..967ef3cb6b 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -251,7 +251,7 @@ void CPUParticles2DEditorPlugin::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
menu->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles2DEditorPlugin::_menu_callback));
- menu->set_icon(epoints->get_theme_icon(SNAME("CPUParticles2D"), SNAME("EditorIcons")));
+ menu->set_icon(epoints->get_editor_theme_icon(SNAME("CPUParticles2D")));
file->connect("file_selected", callable_mp(this, &CPUParticles2DEditorPlugin::_file_selected));
} break;
}
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
index 1f1bc0e561..7e5fa70f3f 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
@@ -47,7 +47,7 @@ void CPUParticles3DEditor::_node_removed(Node *p_node) {
void CPUParticles3DEditor::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE: {
- options->set_icon(get_theme_icon(SNAME("CPUParticles3D"), SNAME("EditorIcons")));
+ options->set_icon(get_editor_theme_icon(SNAME("CPUParticles3D")));
} break;
}
}
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 6b5b0f9214..468278bd27 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_spin_slider.h"
#include "scene/gui/flow_container.h"
@@ -787,8 +788,8 @@ void CurveEdit::_redraw() {
Vector2 min_edge = get_world_pos(Vector2(0, view_size.y));
Vector2 max_edge = get_world_pos(Vector2(view_size.x, 0));
- const Color grid_color_primary = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.25);
- const Color grid_color = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.1);
+ const Color grid_color_primary = get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.25);
+ const Color grid_color = get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.1);
const Vector2i grid_steps = Vector2i(4, 2);
const Vector2 step_size = Vector2(1, curve->get_range()) / grid_steps;
@@ -814,7 +815,7 @@ void CurveEdit::_redraw() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
float font_height = font->get_height(font_size);
- Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color text_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
for (int i = 0; i <= grid_steps.x; ++i) {
real_t x = i * step_size.x;
@@ -832,8 +833,8 @@ void CurveEdit::_redraw() {
// The scaling up ensures that the curve rendering doesn't break when we use a quad line to draw it.
draw_set_transform_matrix(Transform2D(0, get_view_pos(Vector2(0, 0))));
- const Color line_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- const Color edge_line_color = get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.75);
+ const Color line_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
+ const Color edge_line_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.75);
CanvasItemPlotCurve plot_func(*this, line_color, edge_line_color);
plot_curve_accurate(**curve, 2.f, (get_view_pos(Vector2(1, curve->get_max_value())) - get_view_pos(Vector2(0, curve->get_min_value()))) / Vector2(1, curve->get_range()), plot_func);
@@ -843,7 +844,7 @@ void CurveEdit::_redraw() {
bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
- const Color point_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ const Color point_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
for (int i = 0; i < curve->get_point_count(); ++i) {
Vector2 pos = get_view_pos(curve->get_point_position(i));
@@ -859,12 +860,12 @@ void CurveEdit::_redraw() {
if (selected_index >= 0) {
const Vector2 point_pos = curve->get_point_position(selected_index);
- const Color selected_point_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ const Color selected_point_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
// Draw tangents if not dragging a point, or if holding a point without having moved it yet.
if (grabbing == GRAB_NONE || initial_grab_pos == point_pos || selected_tangent_index != TANGENT_NONE) {
- const Color selected_tangent_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")).darkened(0.25);
- const Color tangent_color = get_theme_color(SNAME("font_color"), SNAME("Editor")).darkened(0.25);
+ const Color selected_tangent_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)).darkened(0.25);
+ const Color tangent_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor)).darkened(0.25);
if (selected_index != 0) {
Vector2 control_pos = get_tangent_view_pos(selected_index, TANGENT_LEFT);
@@ -939,8 +940,8 @@ void CurveEdit::_redraw() {
}
if (shift_pressed && grabbing != GRAB_NONE && selected_tangent_index == TANGENT_NONE) {
- draw_line(Vector2(initial_grab_pos.x, curve->get_min_value()), Vector2(initial_grab_pos.x, curve->get_max_value()), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")).darkened(0.4));
- draw_line(Vector2(0, initial_grab_pos.y), Vector2(1, initial_grab_pos.y), get_theme_color(SNAME("axis_y_color"), SNAME("Editor")).darkened(0.4));
+ draw_line(Vector2(initial_grab_pos.x, curve->get_min_value()), Vector2(initial_grab_pos.x, curve->get_max_value()), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)).darkened(0.4));
+ draw_line(Vector2(0, initial_grab_pos.y), Vector2(1, initial_grab_pos.y), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)).darkened(0.4));
}
}
@@ -969,14 +970,14 @@ void CurveEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
spacing = Math::round(BASE_SPACING * get_theme_default_base_scale());
- snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
PopupMenu *p = presets_button->get_popup();
p->clear();
- p->add_icon_item(get_theme_icon(SNAME("CurveConstant"), SNAME("EditorIcons")), TTR("Constant"), CurveEdit::PRESET_CONSTANT);
- p->add_icon_item(get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")), TTR("Linear"), CurveEdit::PRESET_LINEAR);
- p->add_icon_item(get_theme_icon(SNAME("CurveIn"), SNAME("EditorIcons")), TTR("Ease In"), CurveEdit::PRESET_EASE_IN);
- p->add_icon_item(get_theme_icon(SNAME("CurveOut"), SNAME("EditorIcons")), TTR("Ease Out"), CurveEdit::PRESET_EASE_OUT);
- p->add_icon_item(get_theme_icon(SNAME("CurveInOut"), SNAME("EditorIcons")), TTR("Smoothstep"), CurveEdit::PRESET_SMOOTHSTEP);
+ p->add_icon_item(get_editor_theme_icon(SNAME("CurveConstant")), TTR("Constant"), CurveEdit::PRESET_CONSTANT);
+ p->add_icon_item(get_editor_theme_icon(SNAME("CurveLinear")), TTR("Linear"), CurveEdit::PRESET_LINEAR);
+ p->add_icon_item(get_editor_theme_icon(SNAME("CurveIn")), TTR("Ease In"), CurveEdit::PRESET_EASE_IN);
+ p->add_icon_item(get_editor_theme_icon(SNAME("CurveOut")), TTR("Ease Out"), CurveEdit::PRESET_EASE_OUT);
+ p->add_icon_item(get_editor_theme_icon(SNAME("CurveInOut")), TTR("Smoothstep"), CurveEdit::PRESET_SMOOTHSTEP);
} break;
case NOTIFICATION_READY: {
Ref<Curve> curve = curve_editor_rect->get_curve();
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index fba45e5372..1872857130 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/io/file_access_memory.h"
#include "core/io/resource_loader.h"
+#include "core/object/script_language.h"
#include "core/os/os.h"
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
diff --git a/editor/plugins/editor_resource_conversion_plugin.h b/editor/plugins/editor_resource_conversion_plugin.h
index 32e05585ee..1f8aad51ff 100644
--- a/editor/plugins/editor_resource_conversion_plugin.h
+++ b/editor/plugins/editor_resource_conversion_plugin.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class EditorResourceConversionPlugin : public RefCounted {
GDCLASS(EditorResourceConversionPlugin, RefCounted);
diff --git a/editor/plugins/editor_resource_tooltip_plugins.h b/editor/plugins/editor_resource_tooltip_plugins.h
index 3720396842..e3a27de0bb 100644
--- a/editor/plugins/editor_resource_tooltip_plugins.h
+++ b/editor/plugins/editor_resource_tooltip_plugins.h
@@ -33,7 +33,6 @@
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "core/object/script_language.h"
#include <scene/gui/control.h>
class Control;
diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp
index 5d90a746f9..5dd5de224f 100644
--- a/editor/plugins/font_config_plugin.cpp
+++ b/editor/plugins/font_config_plugin.cpp
@@ -156,7 +156,7 @@ void EditorPropertyFontMetaOverride::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
if (button_add) {
- button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add->set_icon(get_editor_theme_icon(SNAME("Add")));
}
} break;
}
@@ -302,7 +302,7 @@ void EditorPropertyFontMetaOverride::update_property() {
hbox->add_child(prop);
prop->set_h_size_flags(SIZE_EXPAND_FILL);
Button *remove = memnew(Button);
- remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ remove->set_icon(get_editor_theme_icon(SNAME("Remove")));
hbox->add_child(remove);
remove->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_remove).bind(remove, name));
@@ -552,7 +552,7 @@ void EditorPropertyOTFeatures::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
if (button_add) {
- button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add->set_icon(get_editor_theme_icon(SNAME("Add")));
}
} break;
}
@@ -789,7 +789,7 @@ void EditorPropertyOTFeatures::update_property() {
hbox->add_child(prop);
prop->set_h_size_flags(SIZE_EXPAND_FILL);
Button *remove = memnew(Button);
- remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ remove->set_icon(get_editor_theme_icon(SNAME("Remove")));
hbox->add_child(remove);
remove->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_remove).bind(remove, name_tag));
@@ -798,7 +798,7 @@ void EditorPropertyOTFeatures::update_property() {
}
button_add = EditorInspector::create_inspector_action_button(TTR("Add Feature"));
- button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add->set_icon(get_editor_theme_icon(SNAME("Add")));
button_add->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_add_menu));
property_vbox->add_child(button_add);
diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h
index 54e6899796..bbde652c8d 100644
--- a/editor/plugins/gdextension_export_plugin.h
+++ b/editor/plugins/gdextension_export_plugin.h
@@ -50,6 +50,15 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
Error err = config->load(p_path);
ERR_FAIL_COND_MSG(err, "Failed to load GDExtension file: " + p_path);
+ // Check whether this GDExtension should be exported.
+ bool android_aar_plugin = config->get_value("configuration", "android_aar_plugin", false);
+ if (android_aar_plugin && p_features.has("android")) {
+ // The gdextension configuration and Android .so files will be provided by the Android aar
+ // plugin it's part of, so we abort here.
+ skip();
+ return;
+ }
+
ERR_FAIL_COND_MSG(!config->has_section_key("configuration", "entry_symbol"), "Failed to export GDExtension file, missing entry symbol: " + p_path);
String entry_symbol = config->get_value("configuration", "entry_symbol");
diff --git a/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
index ed0597efd3..894047c524 100644
--- a/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
@@ -34,7 +34,7 @@
#include "scene/3d/audio_listener_3d.h"
AudioListener3DGizmoPlugin::AudioListener3DGizmoPlugin() {
- create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoAudioListener3D"), SNAME("EditorIcons")));
+ create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoAudioListener3D")));
}
bool AudioListener3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
index 611d4b3c1c..ad40af7784 100644
--- a/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
@@ -38,7 +38,7 @@
AudioStreamPlayer3DGizmoPlugin::AudioStreamPlayer3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
- create_icon_material("stream_player_3d_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("Gizmo3DSamplePlayer"), SNAME("EditorIcons")));
+ create_icon_material("stream_player_3d_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("Gizmo3DSamplePlayer")));
create_material("stream_player_3d_material_primary", gizmo_color);
create_material("stream_player_3d_material_secondary", gizmo_color * Color(1, 1, 1, 0.35));
// Enable vertex colors for the billboard material as the gizmo color depends on the
diff --git a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
index 2ef2e3a666..b0fc5d1ec0 100644
--- a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
@@ -41,7 +41,7 @@ Camera3DGizmoPlugin::Camera3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
create_material("camera_material", gizmo_color);
- create_icon_material("camera_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoCamera3D", "EditorIcons"));
+ create_icon_material("camera_icon", Node3DEditor::get_singleton()->get_editor_theme_icon("GizmoCamera3D"));
create_handle_material("handles");
}
diff --git a/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
index a8ac842945..e00b5349d2 100644
--- a/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
@@ -34,7 +34,7 @@
#include "scene/3d/cpu_particles_3d.h"
CPUParticles3DGizmoPlugin::CPUParticles3DGizmoPlugin() {
- create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoCPUParticles3D"), SNAME("EditorIcons")));
+ create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoCPUParticles3D")));
}
bool CPUParticles3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
index a46de82e76..f17518482a 100644
--- a/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
@@ -40,7 +40,7 @@ GPUParticles3DGizmoPlugin::GPUParticles3DGizmoPlugin() {
create_material("particles_material", gizmo_color);
gizmo_color.a = MAX((gizmo_color.a - 0.2) * 0.02, 0.0);
create_material("particles_solid_material", gizmo_color);
- create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoGPUParticles3D"), SNAME("EditorIcons")));
+ create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoGPUParticles3D")));
create_handle_material("handles");
}
diff --git a/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
index ff959ae836..021cf4e8f1 100644
--- a/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
@@ -43,9 +43,9 @@ Light3DGizmoPlugin::Light3DGizmoPlugin() {
create_material("lines_secondary", Color(1, 1, 1, 0.35), false, false, true);
create_material("lines_billboard", Color(1, 1, 1), true, false, true);
- create_icon_material("light_directional_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoDirectionalLight"), SNAME("EditorIcons")));
- create_icon_material("light_omni_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoLight"), SNAME("EditorIcons")));
- create_icon_material("light_spot_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoSpotLight"), SNAME("EditorIcons")));
+ create_icon_material("light_directional_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoDirectionalLight")));
+ create_icon_material("light_omni_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoLight")));
+ create_icon_material("light_spot_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoSpotLight")));
create_handle_material("handles");
create_handle_material("handles_billboard", true);
diff --git a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
index b16a894e6d..a1a25958c4 100644
--- a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
@@ -48,7 +48,7 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() {
add_material("lightmap_probe_material", mat);
- create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoLightmapGI"), SNAME("EditorIcons")));
+ create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoLightmapGI")));
}
bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
index 50e6f87fcf..d86ede5e44 100644
--- a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
@@ -31,6 +31,7 @@
#include "marker_3d_gizmo_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/marker_3d.h"
@@ -60,7 +61,7 @@ Marker3DGizmoPlugin::Marker3DGizmoPlugin() {
// Use a darkened axis color for the negative axis.
// This makes it possible to see in which direction the Marker3D node is rotated
// (which can be important depending on how it's used).
- const Color color_x = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_x_color"), SNAME("Editor"));
+ const Color color_x = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor));
cursor_colors.push_back(color_x);
cursor_colors.push_back(color_x);
// FIXME: Use less strong darkening factor once GH-48573 is fixed.
@@ -68,13 +69,13 @@ Marker3DGizmoPlugin::Marker3DGizmoPlugin() {
cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75));
cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75));
- const Color color_y = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_y_color"), SNAME("Editor"));
+ const Color color_y = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor));
cursor_colors.push_back(color_y);
cursor_colors.push_back(color_y);
cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75));
cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75));
- const Color color_z = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_z_color"), SNAME("Editor"));
+ const Color color_z = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor));
cursor_colors.push_back(color_z);
cursor_colors.push_back(color_z);
cursor_colors.push_back(color_z.lerp(Color(0, 0, 0), 0.75));
diff --git a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
index 8d61eb0711..d9c2316ce0 100644
--- a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
@@ -46,7 +46,7 @@ ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
gizmo_color.a = 0.1;
create_material("reflection_probe_solid_material", gizmo_color);
- create_icon_material("reflection_probe_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoReflectionProbe"), SNAME("EditorIcons")));
+ create_icon_material("reflection_probe_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoReflectionProbe")));
create_handle_material("handles");
}
diff --git a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
index dfcee00eec..08dbe76d87 100644
--- a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
@@ -47,7 +47,7 @@ VoxelGIGizmoPlugin::VoxelGIGizmoPlugin() {
gizmo_color.a = 0.05;
create_material("voxel_gi_solid_material", gizmo_color);
- create_icon_material("voxel_gi_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoVoxelGI"), SNAME("EditorIcons")));
+ create_icon_material("voxel_gi_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoVoxelGI")));
create_handle_material("handles");
}
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 78bbc1484b..a6ae6c1256 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -352,7 +352,7 @@ void GPUParticles2DEditorPlugin::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
menu->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles2DEditorPlugin::_menu_callback));
- menu->set_icon(menu->get_theme_icon(SNAME("GPUParticles2D"), SNAME("EditorIcons")));
+ menu->set_icon(menu->get_editor_theme_icon(SNAME("GPUParticles2D")));
file->connect("file_selected", callable_mp(this, &GPUParticles2DEditorPlugin::_file_selected));
EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", callable_mp(this, &GPUParticles2DEditorPlugin::_selection_changed));
} break;
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index 108f85152f..e47af62b5b 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -237,7 +237,7 @@ void GPUParticles3DEditor::_node_removed(Node *p_node) {
void GPUParticles3DEditor::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE: {
- options->set_icon(options->get_popup()->get_theme_icon(SNAME("GPUParticles3D"), SNAME("EditorIcons")));
+ options->set_icon(options->get_popup()->get_editor_theme_icon(SNAME("GPUParticles3D")));
get_tree()->connect("node_removed", callable_mp(this, &GPUParticles3DEditor::_node_removed));
} break;
}
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index 938a541a22..af861b04b5 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -183,7 +183,7 @@ GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin()
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
bake->set_text(TTR("Bake SDF"));
bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/plugins/gradient_editor.cpp b/editor/plugins/gradient_editor.cpp
index 59bd0f02fc..63dede4850 100644
--- a/editor/plugins/gradient_editor.cpp
+++ b/editor/plugins/gradient_editor.cpp
@@ -33,6 +33,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/resources/gradient_texture.h"
@@ -393,7 +394,7 @@ void GradientEditor::_notification(int p_what) {
int total_w = get_size().width - get_size().height - draw_spacing - handle_width;
// Draw checker pattern for ramp.
- draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(handle_width / 2, 0, total_w, h), true);
+ draw_texture_rect(get_editor_theme_icon(SNAME("GuiMiniCheckerboard")), Rect2(handle_width / 2, 0, total_w, h), true);
// Draw color ramp.
gradient_cache->set_points(points);
@@ -417,7 +418,7 @@ void GradientEditor::_notification(int p_what) {
draw_rect(rect, points[i].color, true);
draw_rect(rect, col, false, 1);
if (grabbed == i) {
- const Color focus_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ const Color focus_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
rect = rect.grow(-1);
if (has_focus()) {
draw_rect(rect, focus_color, false, 1);
@@ -432,7 +433,7 @@ void GradientEditor::_notification(int p_what) {
// Draw "button" for color selector.
int button_offset = total_w + handle_width + draw_spacing;
- draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(button_offset, 0, h, h), true);
+ draw_texture_rect(get_editor_theme_icon(SNAME("GuiMiniCheckerboard")), Rect2(button_offset, 0, h, h), true);
if (grabbed != -1) {
// Draw with selection color.
draw_rect(Rect2(button_offset, 0, h, h), points[grabbed].color);
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 57a7f527ec..c85e19fda6 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -40,7 +40,7 @@
void GradientReverseButton::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
- Ref<Texture2D> icon = get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("ReverseGradient"));
if (is_pressed()) {
draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()), false, get_theme_color(SNAME("icon_pressed_color"), SNAME("Button")));
} else {
@@ -51,7 +51,7 @@ void GradientReverseButton::_notification(int p_what) {
}
Size2 GradientReverseButton::get_minimum_size() const {
- return (get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"))->get_size() + Size2(margin * 2, margin * 2));
+ return (get_editor_theme_icon(SNAME("ReverseGradient"))->get_size() + Size2(margin * 2, margin * 2));
}
///////////////////////
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
index c48de7c3dd..494d97c45c 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
@@ -169,7 +169,7 @@ void GradientTexture2DEdit::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
- checkerboard->set_texture(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")));
+ checkerboard->set_texture(get_editor_theme_icon(SNAME("GuiMiniCheckerboard")));
} break;
case NOTIFICATION_DRAW: {
_draw();
@@ -182,8 +182,8 @@ void GradientTexture2DEdit::_draw() {
return;
}
- const Ref<Texture2D> fill_from_icon = get_theme_icon(SNAME("EditorPathSmoothHandle"), SNAME("EditorIcons"));
- const Ref<Texture2D> fill_to_icon = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> fill_from_icon = get_editor_theme_icon(SNAME("EditorPathSmoothHandle"));
+ const Ref<Texture2D> fill_to_icon = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
handle_size = fill_from_icon->get_size();
Size2 rect_size = get_size();
@@ -262,8 +262,8 @@ void GradientTexture2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- reverse_button->set_icon(get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons")));
- snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ reverse_button->set_icon(get_editor_theme_icon(SNAME("ReverseGradient")));
+ snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
} break;
case NOTIFICATION_READY: {
if (texture.is_valid()) {
diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp
index 9a54a8c1a1..973c929059 100644
--- a/editor/plugins/input_event_editor_plugin.cpp
+++ b/editor/plugins/input_event_editor_plugin.cpp
@@ -40,7 +40,7 @@ void InputEventConfigContainer::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- open_config_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ open_config_button->set_icon(get_editor_theme_icon(SNAME("Edit")));
} break;
}
}
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index b549a958e6..db5593a132 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -165,7 +165,7 @@ void LightmapGIEditorPlugin::_bind_methods() {
LightmapGIEditorPlugin::LightmapGIEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 60119a5499..2a712caf92 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -63,13 +63,13 @@ void MaterialEditor::gui_input(const Ref<InputEvent> &p_event) {
void MaterialEditor::_update_theme_item_cache() {
Control::_update_theme_item_cache();
- theme_cache.light_1_icon = get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons"));
- theme_cache.light_2_icon = get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons"));
+ theme_cache.light_1_icon = get_editor_theme_icon(SNAME("MaterialPreviewLight1"));
+ theme_cache.light_2_icon = get_editor_theme_icon(SNAME("MaterialPreviewLight2"));
- theme_cache.sphere_icon = get_theme_icon(SNAME("MaterialPreviewSphere"), SNAME("EditorIcons"));
- theme_cache.box_icon = get_theme_icon(SNAME("MaterialPreviewCube"), SNAME("EditorIcons"));
+ theme_cache.sphere_icon = get_editor_theme_icon(SNAME("MaterialPreviewSphere"));
+ theme_cache.box_icon = get_editor_theme_icon(SNAME("MaterialPreviewCube"));
- theme_cache.checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ theme_cache.checkerboard = get_editor_theme_icon(SNAME("Checkerboard"));
}
void MaterialEditor::_notification(int p_what) {
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index b6be971370..729ca5d7f9 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -51,8 +51,8 @@ void MeshEditor::gui_input(const Ref<InputEvent> &p_event) {
void MeshEditor::_update_theme_item_cache() {
SubViewportContainer::_update_theme_item_cache();
- theme_cache.light_1_icon = get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons"));
- theme_cache.light_2_icon = get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons"));
+ theme_cache.light_1_icon = get_editor_theme_icon(SNAME("MaterialPreviewLight1"));
+ theme_cache.light_2_icon = get_editor_theme_icon(SNAME("MaterialPreviewLight2"));
}
void MeshEditor::_notification(int p_what) {
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index a53e254dcc..c299ba97d5 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/collision_shape_3d.h"
@@ -463,10 +464,10 @@ void MeshInstance3DEditor::_debug_uv_draw() {
}
debug_uv->set_clip_contents(true);
- debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), get_theme_color(SNAME("dark_color_3"), SNAME("Editor")));
+ debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor)));
debug_uv->draw_set_transform(Vector2(), 0, debug_uv->get_size());
// Use a translucent color to allow overlapping triangles to be visible.
- debug_uv->draw_multiline(uv_lines, get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5));
+ debug_uv->draw_multiline(uv_lines, get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5));
}
void MeshInstance3DEditor::_create_outline_mesh() {
@@ -521,7 +522,7 @@ MeshInstance3DEditor::MeshInstance3DEditor() {
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text(TTR("Mesh"));
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MeshInstance3D"), SNAME("EditorIcons")));
+ options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MeshInstance3D")));
options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
options->get_popup()->set_item_tooltip(-1, TTR("Creates a StaticBody3D and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection."));
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 4cc96126de..750a71905b 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -275,7 +275,7 @@ MeshLibraryEditor::MeshLibraryEditor() {
Node3DEditor::get_singleton()->add_control_to_menu_panel(menu);
menu->set_position(Point2(1, 1));
menu->set_text(TTR("MeshLibrary"));
- menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MeshLibrary"), SNAME("EditorIcons")));
+ menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MeshLibrary")));
menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM);
menu->get_popup()->add_item(TTR("Remove Selected Item"), MENU_OPTION_REMOVE_ITEM);
menu->get_popup()->add_separator();
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 15647e1364..a980b30bfe 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -272,7 +272,7 @@ MultiMeshEditor::MultiMeshEditor() {
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text("MultiMesh");
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MultiMeshInstance3D"), SNAME("EditorIcons")));
+ options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MultiMeshInstance3D")));
options->get_popup()->add_item(TTR("Populate Surface"));
options->get_popup()->connect("id_pressed", callable_mp(this, &MultiMeshEditor::_menu_option));
diff --git a/editor/plugins/navigation_link_2d_editor_plugin.cpp b/editor/plugins/navigation_link_2d_editor_plugin.cpp
index dff92ced27..5419e487bf 100644
--- a/editor/plugins/navigation_link_2d_editor_plugin.cpp
+++ b/editor/plugins/navigation_link_2d_editor_plugin.cpp
@@ -147,7 +147,7 @@ void NavigationLink2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
Vector2 global_end_position = gt.xform(node->get_end_position());
// Only drawing the handles here, since the debug rendering will fill in the rest.
- const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorHandle"));
p_overlay->draw_texture(handle, global_start_position - handle->get_size() / 2);
p_overlay->draw_texture(handle, global_end_position - handle->get_size() / 2);
}
diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
index 2e39d6f67c..4892538a0a 100644
--- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
+++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
@@ -46,8 +46,8 @@
void NavigationObstacle3DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- button_create->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- button_edit->set_icon(get_theme_icon(SNAME("MovePoint"), SNAME("EditorIcons")));
+ button_create->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ button_edit->set_icon(get_editor_theme_icon(SNAME("MovePoint")));
button_edit->set_pressed(true);
get_tree()->connect("node_removed", callable_mp(this, &NavigationObstacle3DEditor::_node_removed));
@@ -554,7 +554,7 @@ NavigationObstacle3DEditor::NavigationObstacle3DEditor() {
handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Editor3DHandle"));
handle_material->set_point_size(handle->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 2a91d9f108..f6e93e292f 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -940,7 +940,7 @@ void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool
handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true);
- Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : Node3DEditor::get_singleton()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("Editor3DHandle"));
handle_material->set_point_size(handle_t->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle_t);
handle_material->set_albedo(Color(1, 1, 1));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 4284fd8ae2..17c9a097ba 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -39,6 +39,7 @@
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_run_bar.h"
#include "editor/gui/editor_spin_slider.h"
@@ -302,9 +303,9 @@ void ViewportRotationControl::_notification(int p_what) {
axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR);
axis_colors.clear();
- axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
- axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
- axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
+ axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor)));
queue_redraw();
if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) {
@@ -353,7 +354,7 @@ void ViewportRotationControl::_draw_axis(const Axis2D &p_axis) {
// Draw the axis letter for the positive axes.
const String axis_name = direction == 0 ? "X" : (direction == 1 ? "Y" : "Z");
- draw_char(get_theme_font(SNAME("rotation_control"), SNAME("EditorFonts")), p_axis.screen_point + Vector2i(Math::round(-4.0 * EDSCALE), Math::round(5.0 * EDSCALE)), axis_name, get_theme_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts")), Color(0.0, 0.0, 0.0, alpha));
+ draw_char(get_theme_font(SNAME("rotation_control"), EditorStringName(EditorFonts)), p_axis.screen_point + Vector2i(Math::round(-4.0 * EDSCALE), Math::round(5.0 * EDSCALE)), axis_name, get_theme_font_size(SNAME("rotation_control_size"), EditorStringName(EditorFonts)), Color(0.0, 0.0, 0.0, alpha));
} else {
// Draw an outline around the negative axes.
draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS, c);
@@ -2984,32 +2985,32 @@ void Node3DEditorViewport::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
+ view_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ preview_camera->set_icon(get_editor_theme_icon(SNAME("Camera3D")));
Control *gui_base = EditorNode::get_singleton()->get_gui_base();
- view_menu->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
-
- preview_camera->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
-
- frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor")));
- frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor")));
-
- info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ view_menu->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ view_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ view_menu->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ view_menu->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ view_menu->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+
+ preview_camera->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ preview_camera->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ preview_camera->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ preview_camera->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ preview_camera->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+
+ frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
+ frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+
+ info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
+ locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)));
} break;
case NOTIFICATION_DRAG_END: {
@@ -3059,7 +3060,7 @@ void Node3DEditorViewport::_draw() {
if (surface->has_focus()) {
Size2 size = surface->get_size();
Rect2 r = Rect2(Point2(), size);
- get_theme_stylebox(SNAME("FocusViewport"), SNAME("EditorStyles"))->draw(surface->get_canvas_item(), r);
+ get_theme_stylebox(SNAME("FocusViewport"), EditorStringName(EditorStyles))->draw(surface->get_canvas_item(), r);
}
if (cursor.region_select) {
@@ -3067,11 +3068,11 @@ void Node3DEditorViewport::_draw() {
surface->draw_rect(
selection_rect,
- get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")));
+ get_theme_color(SNAME("box_selection_fill_color"), EditorStringName(Editor)));
surface->draw_rect(
selection_rect,
- get_theme_color(SNAME("box_selection_stroke_color"), SNAME("Editor")),
+ get_theme_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)),
false,
Math::round(EDSCALE));
}
@@ -3093,16 +3094,16 @@ void Node3DEditorViewport::_draw() {
Color handle_color;
switch (_edit.plane) {
case TRANSFORM_X_AXIS:
- handle_color = get_theme_color(SNAME("axis_x_color"), SNAME("Editor"));
+ handle_color = get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor));
break;
case TRANSFORM_Y_AXIS:
- handle_color = get_theme_color(SNAME("axis_y_color"), SNAME("Editor"));
+ handle_color = get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor));
break;
case TRANSFORM_Z_AXIS:
- handle_color = get_theme_color(SNAME("axis_z_color"), SNAME("Editor"));
+ handle_color = get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor));
break;
default:
- handle_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ handle_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
break;
}
handle_color = handle_color.from_hsv(handle_color.get_h(), 0.25, 1.0, 1);
@@ -3157,7 +3158,7 @@ void Node3DEditorViewport::_draw() {
draw_indicator_bar(
*surface,
1.0 - logscale_t,
- get_theme_icon(SNAME("ViewportSpeed"), SNAME("EditorIcons")),
+ get_editor_theme_icon(SNAME("ViewportSpeed")),
get_theme_font(SNAME("font"), SNAME("Label")),
get_theme_font_size(SNAME("font_size"), SNAME("Label")),
vformat("%s u/s", String::num(freelook_speed).pad_decimals(precision)),
@@ -3180,7 +3181,7 @@ void Node3DEditorViewport::_draw() {
draw_indicator_bar(
*surface,
logscale_t,
- get_theme_icon(SNAME("ViewportZoom"), SNAME("EditorIcons")),
+ get_editor_theme_icon(SNAME("ViewportZoom")),
get_theme_font(SNAME("font"), SNAME("Label")),
get_theme_font_size(SNAME("font_size"), SNAME("Label")),
vformat("%s u", String::num(cursor.distance).pad_decimals(precision)),
@@ -5439,9 +5440,9 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
- Ref<Texture2D> hdiag_grabber = get_theme_icon(SNAME("GuiViewportHdiagsplitter"), SNAME("EditorIcons"));
- Ref<Texture2D> vdiag_grabber = get_theme_icon(SNAME("GuiViewportVdiagsplitter"), SNAME("EditorIcons"));
- Ref<Texture2D> vh_grabber = get_theme_icon(SNAME("GuiViewportVhsplitter"), SNAME("EditorIcons"));
+ Ref<Texture2D> hdiag_grabber = get_editor_theme_icon(SNAME("GuiViewportHdiagsplitter"));
+ Ref<Texture2D> vdiag_grabber = get_editor_theme_icon(SNAME("GuiViewportVdiagsplitter"));
+ Ref<Texture2D> vh_grabber = get_editor_theme_icon(SNAME("GuiViewportVhsplitter"));
Vector2 size = get_size();
@@ -6499,13 +6500,13 @@ void Node3DEditor::_init_indicators() {
Color origin_color;
switch (i) {
case 0:
- origin_color = get_theme_color(SNAME("axis_x_color"), SNAME("Editor"));
+ origin_color = get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor));
break;
case 1:
- origin_color = get_theme_color(SNAME("axis_y_color"), SNAME("Editor"));
+ origin_color = get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor));
break;
case 2:
- origin_color = get_theme_color(SNAME("axis_z_color"), SNAME("Editor"));
+ origin_color = get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor));
break;
default:
origin_color = Color();
@@ -6612,13 +6613,13 @@ void fragment() {
Color col;
switch (i) {
case 0:
- col = get_theme_color(SNAME("axis_x_color"), SNAME("Editor"));
+ col = get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor));
break;
case 1:
- col = get_theme_color(SNAME("axis_y_color"), SNAME("Editor"));
+ col = get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor));
break;
case 2:
- col = get_theme_color(SNAME("axis_z_color"), SNAME("Editor"));
+ col = get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor));
break;
default:
col = Color();
@@ -7548,39 +7549,39 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
}
void Node3DEditor::_update_theme() {
- tool_button[TOOL_MODE_SELECT]->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_button[TOOL_MODE_MOVE]->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
- tool_button[TOOL_MODE_ROTATE]->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
- tool_button[TOOL_MODE_SCALE]->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
- tool_button[TOOL_MODE_LIST_SELECT]->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
- tool_button[TOOL_LOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
- tool_button[TOOL_UNLOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
- tool_button[TOOL_GROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
- tool_button[TOOL_UNGROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
-
- tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_icon(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")));
- tool_option_button[TOOL_OPT_USE_SNAP]->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
-
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_theme_icon(SNAME("Panels1"), SNAME("EditorIcons")));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons")));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), get_theme_icon(SNAME("Panels2Alt"), SNAME("EditorIcons")));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_theme_icon(SNAME("Panels3"), SNAME("EditorIcons")));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_theme_icon(SNAME("Panels3Alt"), SNAME("EditorIcons")));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_theme_icon(SNAME("Panels4"), SNAME("EditorIcons")));
-
- sun_button->set_icon(get_theme_icon(SNAME("PreviewSun"), SNAME("EditorIcons")));
- environ_button->set_icon(get_theme_icon(SNAME("PreviewEnvironment"), SNAME("EditorIcons")));
- sun_environ_settings->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_SELECT]->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ tool_button[TOOL_MODE_MOVE]->set_icon(get_editor_theme_icon(SNAME("ToolMove")));
+ tool_button[TOOL_MODE_ROTATE]->set_icon(get_editor_theme_icon(SNAME("ToolRotate")));
+ tool_button[TOOL_MODE_SCALE]->set_icon(get_editor_theme_icon(SNAME("ToolScale")));
+ tool_button[TOOL_MODE_LIST_SELECT]->set_icon(get_editor_theme_icon(SNAME("ListSelect")));
+ tool_button[TOOL_LOCK_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Lock")));
+ tool_button[TOOL_UNLOCK_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Unlock")));
+ tool_button[TOOL_GROUP_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Group")));
+ tool_button[TOOL_UNGROUP_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Ungroup")));
+
+ tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_icon(get_editor_theme_icon(SNAME("Object")));
+ tool_option_button[TOOL_OPT_USE_SNAP]->set_icon(get_editor_theme_icon(SNAME("Snap")));
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_editor_theme_icon(SNAME("Camera3D")));
+
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_editor_theme_icon(SNAME("Panels1")));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_editor_theme_icon(SNAME("Panels2")));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), get_editor_theme_icon(SNAME("Panels2Alt")));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_editor_theme_icon(SNAME("Panels3")));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_editor_theme_icon(SNAME("Panels3Alt")));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_editor_theme_icon(SNAME("Panels4")));
+
+ sun_button->set_icon(get_editor_theme_icon(SNAME("PreviewSun")));
+ environ_button->set_icon(get_editor_theme_icon(SNAME("PreviewEnvironment")));
+ sun_environ_settings->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
- sun_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
- environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
- environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
+ sun_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
+ environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
+ environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
- context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
+ context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
}
void Node3DEditor::_notification(int p_what) {
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
index 9e9e602841..3a05352ecf 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
@@ -104,7 +104,7 @@ void OccluderInstance3DEditorPlugin::_bind_methods() {
OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
bake->set_text(TTR("Bake Occluders"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
diff --git a/editor/plugins/packed_scene_editor_plugin.cpp b/editor/plugins/packed_scene_editor_plugin.cpp
index 3239375e1e..00fb94b6ae 100644
--- a/editor/plugins/packed_scene_editor_plugin.cpp
+++ b/editor/plugins/packed_scene_editor_plugin.cpp
@@ -44,7 +44,7 @@ void PackedSceneEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- open_scene_button->set_icon(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")));
+ open_scene_button->set_icon(get_editor_theme_icon(SNAME("PackedScene")));
} break;
}
}
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp
index 83d7778196..7cb5244af9 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.cpp
+++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp
@@ -31,6 +31,7 @@
#include "packed_scene_translation_parser_plugin.h"
#include "core/io/resource_loader.h"
+#include "core/object/script_language.h"
#include "scene/gui/option_button.h"
#include "scene/resources/packed_scene.h"
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 63f6643ba3..3a7805ba4c 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -43,11 +43,11 @@ void Path2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- curve_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- curve_edit_curve->set_icon(get_theme_icon(SNAME("CurveCurve"), SNAME("EditorIcons")));
- curve_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- curve_del->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
- curve_close->set_icon(get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
+ curve_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit")));
+ curve_edit_curve->set_icon(get_editor_theme_icon(SNAME("CurveCurve")));
+ curve_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate")));
+ curve_del->set_icon(get_editor_theme_icon(SNAME("CurveDelete")));
+ curve_close->set_icon(get_editor_theme_icon(SNAME("CurveClose")));
} break;
}
}
@@ -370,12 +370,12 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- const Ref<Texture2D> path_sharp_handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
- const Ref<Texture2D> path_smooth_handle = get_theme_icon(SNAME("EditorPathSmoothHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> path_sharp_handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
+ const Ref<Texture2D> path_smooth_handle = get_editor_theme_icon(SNAME("EditorPathSmoothHandle"));
// Both handle icons must be of the same size
const Size2 handle_size = path_sharp_handle->get_size();
- const Ref<Texture2D> curve_handle = get_theme_icon(SNAME("EditorCurveHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> curve_handle = get_editor_theme_icon(SNAME("EditorCurveHandle"));
const Size2 curve_handle_size = curve_handle->get_size();
Ref<Curve2D> curve = node->get_curve();
@@ -417,7 +417,7 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
if (on_edge) {
- Ref<Texture2D> add_handle = get_theme_icon(SNAME("EditorHandleAdd"), SNAME("EditorIcons"));
+ Ref<Texture2D> add_handle = get_editor_theme_icon(SNAME("EditorHandleAdd"));
p_overlay->draw_texture(add_handle, edge_point - add_handle->get_size() * 0.5);
}
}
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 3a2fcb691b..f4c36f3816 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -696,11 +696,11 @@ void Path3DEditorPlugin::_handle_option_pressed(int p_option) {
void Path3DEditorPlugin::_update_theme() {
// TODO: Split the EditorPlugin instance from the UI instance and connect this properly.
// See the 2D path editor for inspiration.
- curve_edit->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- curve_edit_curve->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveCurve"), SNAME("EditorIcons")));
- curve_create->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- curve_del->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
- curve_close->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
+ curve_edit->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveEdit")));
+ curve_edit_curve->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveCurve")));
+ curve_create->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveCreate")));
+ curve_del->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveDelete")));
+ curve_close->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveClose")));
}
void Path3DEditorPlugin::_notification(int p_what) {
@@ -822,6 +822,6 @@ Path3DGizmoPlugin::Path3DGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
create_material("path_thin_material", Color(0.5, 0.5, 0.5));
- create_handle_material("handles", false, Node3DEditor::get_singleton()->get_theme_icon(SNAME("EditorPathSmoothHandle"), SNAME("EditorIcons")));
- create_handle_material("sec_handles", false, Node3DEditor::get_singleton()->get_theme_icon(SNAME("EditorCurveHandle"), SNAME("EditorIcons")));
+ create_handle_material("handles", false, Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorPathSmoothHandle")));
+ create_handle_material("sec_handles", false, Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorCurveHandle")));
}
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index a8d3ab948f..c9b77b3edb 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -60,7 +60,7 @@ PhysicalBone3DEditor::PhysicalBone3DEditor() {
spatial_editor_hb->add_child(button_transform_joint);
button_transform_joint->set_text(TTR("Move Joint"));
- button_transform_joint->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("PhysicalBone3D"), SNAME("EditorIcons")));
+ button_transform_joint->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("PhysicalBone3D")));
button_transform_joint->set_toggle_mode(true);
button_transform_joint->connect("toggled", callable_mp(this, &PhysicalBone3DEditor::_on_toggle_button_transform_joint));
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index d2b3efcd65..5ed9f4946d 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -80,23 +80,23 @@ void Polygon2DEditor::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
- button_uv->set_icon(get_theme_icon(SNAME("Uv"), SNAME("EditorIcons")));
-
- uv_button[UV_MODE_CREATE]->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- uv_button[UV_MODE_CREATE_INTERNAL]->set_icon(get_theme_icon(SNAME("EditInternal"), SNAME("EditorIcons")));
- uv_button[UV_MODE_REMOVE_INTERNAL]->set_icon(get_theme_icon(SNAME("RemoveInternal"), SNAME("EditorIcons")));
- uv_button[UV_MODE_EDIT_POINT]->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- uv_button[UV_MODE_MOVE]->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
- uv_button[UV_MODE_ROTATE]->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
- uv_button[UV_MODE_SCALE]->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
- uv_button[UV_MODE_ADD_POLYGON]->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- uv_button[UV_MODE_REMOVE_POLYGON]->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
- uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons")));
- uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
-
- b_snap_grid->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons")));
- b_snap_enable->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- uv_icon_zoom->set_texture(get_theme_icon(SNAME("Zoom"), SNAME("EditorIcons")));
+ button_uv->set_icon(get_editor_theme_icon(SNAME("Uv")));
+
+ uv_button[UV_MODE_CREATE]->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ uv_button[UV_MODE_CREATE_INTERNAL]->set_icon(get_editor_theme_icon(SNAME("EditInternal")));
+ uv_button[UV_MODE_REMOVE_INTERNAL]->set_icon(get_editor_theme_icon(SNAME("RemoveInternal")));
+ uv_button[UV_MODE_EDIT_POINT]->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ uv_button[UV_MODE_MOVE]->set_icon(get_editor_theme_icon(SNAME("ToolMove")));
+ uv_button[UV_MODE_ROTATE]->set_icon(get_editor_theme_icon(SNAME("ToolRotate")));
+ uv_button[UV_MODE_SCALE]->set_icon(get_editor_theme_icon(SNAME("ToolScale")));
+ uv_button[UV_MODE_ADD_POLYGON]->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ uv_button[UV_MODE_REMOVE_POLYGON]->set_icon(get_editor_theme_icon(SNAME("Close")));
+ uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_editor_theme_icon(SNAME("Bucket")));
+ uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_editor_theme_icon(SNAME("Clear")));
+
+ b_snap_grid->set_icon(get_editor_theme_icon(SNAME("Grid")));
+ b_snap_enable->set_icon(get_editor_theme_icon(SNAME("SnapGrid")));
+ uv_icon_zoom->set_texture(get_editor_theme_icon(SNAME("Zoom")));
uv_vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE);
uv_hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
@@ -1043,7 +1043,7 @@ void Polygon2DEditor::_uv_draw() {
}
// All UV points are sharp, so use the sharp handle icon
- Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
Color poly_line_color = Color(0.9, 0.5, 0.5);
if (polygons.size() || polygon_create.size()) {
diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp
index ceff9cb5f3..451bd7a738 100644
--- a/editor/plugins/polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/polygon_3d_editor_plugin.cpp
@@ -45,8 +45,8 @@
void Polygon3DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- button_create->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- button_edit->set_icon(get_theme_icon(SNAME("MovePoint"), SNAME("EditorIcons")));
+ button_create->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ button_edit->set_icon(get_editor_theme_icon(SNAME("MovePoint")));
button_edit->set_pressed(true);
get_tree()->connect("node_removed", callable_mp(this, &Polygon3DEditor::_node_removed));
@@ -569,7 +569,7 @@ Polygon3DEditor::Polygon3DEditor() {
handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Editor3DHandle"));
handle_material->set_point_size(handle->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle);
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index b59bf3a37b..e352fd27ad 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -43,7 +43,7 @@ void ResourcePreloaderEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- load->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ load->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
}
}
@@ -209,11 +209,11 @@ void ResourcePreloaderEditor::_update_library() {
ti->set_selectable(1, false);
if (type == "PackedScene") {
- ti->add_button(1, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_OPEN_SCENE, false, TTR("Open in Editor"));
+ ti->add_button(1, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_OPEN_SCENE, false, TTR("Open in Editor"));
} else {
- ti->add_button(1, get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), BUTTON_EDIT_RESOURCE, false, TTR("Open in Editor"));
+ ti->add_button(1, get_editor_theme_icon(SNAME("Load")), BUTTON_EDIT_RESOURCE, false, TTR("Open in Editor"));
}
- ti->add_button(1, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE, false, TTR("Remove"));
+ ti->add_button(1, get_editor_theme_icon(SNAME("Remove")), BUTTON_REMOVE, false, TTR("Remove"));
}
//player->add_resource("default",resource);
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 09b0864559..10b0b214ae 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -132,7 +132,7 @@ void EditorPropertyRootMotion::_node_assign() {
if (skeleton) {
HashMap<int, TreeItem *> items;
items.insert(-1, ti);
- Ref<Texture> bone_icon = get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"));
+ Ref<Texture> bone_icon = get_editor_theme_icon(SNAME("BoneAttachment3D"));
Vector<int> bones_to_process = skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
int current_bone_idx = bones_to_process[0];
@@ -190,7 +190,7 @@ void EditorPropertyRootMotion::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- Ref<Texture2D> t = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
+ Ref<Texture2D> t = get_editor_theme_icon(SNAME("Clear"));
clear->set_icon(t);
} break;
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 39f4e4eb6a..2fe607a08c 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -48,6 +48,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_script.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/filesystem_dock.h"
#include "editor/find_in_files.h"
#include "editor/gui/editor_file_dialog.h"
@@ -382,7 +383,7 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_VISIBILITY_CHANGED: {
- search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -663,7 +664,7 @@ void ScriptEditor::_go_to_tab(int p_idx) {
}
if (Object::cast_to<EditorHelp>(c)) {
script_name_label->set_text(Object::cast_to<EditorHelp>(c)->get_class());
- script_icon->set_texture(get_theme_icon(SNAME("Help"), SNAME("EditorIcons")));
+ script_icon->set_texture(get_editor_theme_icon(SNAME("Help")));
if (is_visible_in_tree()) {
Object::cast_to<EditorHelp>(c)->set_focused();
}
@@ -1611,23 +1612,25 @@ void ScriptEditor::_notification(int p_what) {
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED: {
- help_search->set_icon(get_theme_icon(SNAME("HelpSearch"), SNAME("EditorIcons")));
- site_search->set_icon(get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
+ tab_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ScriptEditor"), EditorStringName(EditorStyles)));
+
+ help_search->set_icon(get_editor_theme_icon(SNAME("HelpSearch")));
+ site_search->set_icon(get_editor_theme_icon(SNAME("ExternalLink")));
if (is_layout_rtl()) {
- script_forward->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
- script_back->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
+ script_forward->set_icon(get_editor_theme_icon(SNAME("Back")));
+ script_back->set_icon(get_editor_theme_icon(SNAME("Forward")));
} else {
- script_forward->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
- script_back->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
+ script_forward->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ script_back->set_icon(get_editor_theme_icon(SNAME("Back")));
}
- members_overview_alphabeta_sort_button->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
+ members_overview_alphabeta_sort_button->set_icon(get_editor_theme_icon(SNAME("Sort")));
- filter_scripts->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filter_methods->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ filter_scripts->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ filter_methods->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
+ filename->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
recent_scripts->reset_size();
@@ -1638,6 +1641,9 @@ void ScriptEditor::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
+ // Can't set own styles in NOTIFICATION_THEME_CHANGED, so for now this will do.
+ add_theme_style_override("panel", get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
+
get_tree()->connect("tree_changed", callable_mp(this, &ScriptEditor::_tree_changed));
InspectorDock::get_singleton()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open));
EditorNode::get_singleton()->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search));
@@ -1957,9 +1963,9 @@ void ScriptEditor::_update_script_colors() {
bool script_temperature_enabled = EDITOR_GET("text_editor/script_list/script_temperature_enabled");
int hist_size = EDITOR_GET("text_editor/script_list/script_temperature_history_size");
- Color hot_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color hot_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
hot_color.set_s(hot_color.get_s() * 0.9);
- Color cold_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ Color cold_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
for (int i = 0; i < script_list->get_item_count(); i++) {
int c = script_list->get_item_metadata(i);
@@ -2099,7 +2105,7 @@ void ScriptEditor::_update_script_names() {
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh) {
String name = eh->get_class();
- Ref<Texture2D> icon = get_theme_icon(SNAME("Help"), SNAME("EditorIcons"));
+ Ref<Texture2D> icon = get_editor_theme_icon(SNAME("Help"));
String tooltip = vformat(TTR("%s Class Reference"), name);
_ScriptEditorItemData sd;
@@ -2150,7 +2156,7 @@ void ScriptEditor::_update_script_names() {
}
}
- Color tool_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ Color tool_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
tool_color.set_s(tool_color.get_s() * 1.5);
for (int i = 0; i < sedata_filtered.size(); i++) {
script_list->add_item(sedata_filtered[i].name, sedata_filtered[i].icon);
@@ -2885,7 +2891,7 @@ Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
EditorHelp *eh = Object::cast_to<EditorHelp>(cur_node);
if (eh) {
preview_name = eh->get_class();
- preview_icon = get_theme_icon(SNAME("Help"), SNAME("EditorIcons"));
+ preview_icon = get_editor_theme_icon(SNAME("Help"));
}
if (!preview_icon.is_null()) {
@@ -4138,9 +4144,6 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
ScriptServer::edit_request_func = _open_script_request;
- add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
- tab_container->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles")));
-
Ref<EditorJSONSyntaxHighlighter> json_syntax_highlighter;
json_syntax_highlighter.instantiate();
register_syntax_highlighter(json_syntax_highlighter);
@@ -4166,9 +4169,9 @@ void ScriptEditorPlugin::_save_last_editor(String p_editor) {
void ScriptEditorPlugin::_window_visibility_changed(bool p_visible) {
_focus_another_editor();
if (p_visible) {
- script_editor->add_theme_style_override("panel", script_editor->get_theme_stylebox("ScriptEditorPanelFloating", "EditorStyles"));
+ script_editor->add_theme_style_override("panel", script_editor->get_theme_stylebox("ScriptEditorPanelFloating", EditorStringName(EditorStyles)));
} else {
- script_editor->add_theme_style_override("panel", script_editor->get_theme_stylebox("ScriptEditorPanel", "EditorStyles"));
+ script_editor->add_theme_style_override("panel", script_editor->get_theme_stylebox("ScriptEditorPanel", EditorStringName(EditorStyles)));
}
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index a33c877d2d..0241ca0e3e 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -31,6 +31,7 @@
#ifndef SCRIPT_EDITOR_PLUGIN_H
#define SCRIPT_EDITOR_PLUGIN_H
+#include "core/object/script_language.h"
#include "editor/editor_plugin.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/panel_container.h"
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index f8da47b45e..511e4dfd15 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_toaster.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/split_container.h"
@@ -69,7 +70,7 @@ void ConnectionInfoDialog::popup_connections(String p_method, Vector<Node *> p_n
node_item->set_text(1, connection.signal.get_name());
Control *p = Object::cast_to<Control>(get_parent());
- node_item->set_icon(1, p->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
+ node_item->set_icon(1, p->get_editor_theme_icon(SNAME("Slot")));
node_item->set_selectable(1, false);
node_item->set_editable(1, false);
@@ -457,10 +458,10 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
icon_name += "Internal";
}
- if (get_parent_control()->has_theme_icon(icon_name, SNAME("EditorIcons"))) {
- return get_parent_control()->get_theme_icon(icon_name, SNAME("EditorIcons"));
- } else if (get_parent_control()->has_theme_icon(script->get_class(), SNAME("EditorIcons"))) {
- return get_parent_control()->get_theme_icon(script->get_class(), SNAME("EditorIcons"));
+ if (get_parent_control()->has_theme_icon(icon_name, EditorStringName(EditorIcons))) {
+ return get_parent_control()->get_editor_theme_icon(icon_name);
+ } else if (get_parent_control()->has_theme_icon(script->get_class(), EditorStringName(EditorIcons))) {
+ return get_parent_control()->get_editor_theme_icon(script->get_class());
}
}
@@ -532,7 +533,7 @@ void ScriptTextEditor::_update_warnings() {
String target_path = base == connection.callable.get_object() ? base_path : base_path + "/" + base->get_path_to(Object::cast_to<Node>(connection.callable.get_object()));
warnings_panel->push_cell();
- warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
warnings_panel->add_text(vformat(TTR("Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."), connection.callable.get_method(), connection.signal.get_name(), source_path, target_path));
warnings_panel->pop(); // Color.
warnings_panel->pop(); // Cell.
@@ -558,7 +559,7 @@ void ScriptTextEditor::_update_warnings() {
warnings_panel->push_cell();
warnings_panel->push_meta(ignore_meta);
warnings_panel->push_color(
- warnings_panel->get_theme_color(SNAME("accent_color"), SNAME("Editor")).lerp(warnings_panel->get_theme_color(SNAME("mono_color"), SNAME("Editor")), 0.5f));
+ warnings_panel->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)).lerp(warnings_panel->get_theme_color(SNAME("mono_color"), EditorStringName(Editor)), 0.5f));
warnings_panel->add_text(TTR("[Ignore]"));
warnings_panel->pop(); // Color.
warnings_panel->pop(); // Meta ignore.
@@ -566,7 +567,7 @@ void ScriptTextEditor::_update_warnings() {
warnings_panel->push_cell();
warnings_panel->push_meta(w.start_line - 1);
- warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
warnings_panel->add_text(TTR("Line") + " " + itos(w.start_line));
warnings_panel->add_text(" (" + w.string_code + "):");
warnings_panel->pop(); // Color.
@@ -593,7 +594,7 @@ void ScriptTextEditor::_update_errors() {
errors_panel->push_cell();
errors_panel->push_meta(err.line - 1);
- errors_panel->push_color(warnings_panel->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ errors_panel->push_color(warnings_panel->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
errors_panel->add_text(TTR("Line") + " " + itos(err.line) + ":");
errors_panel->pop(); // Color.
errors_panel->pop(); // Meta goto.
@@ -627,7 +628,7 @@ void ScriptTextEditor::_update_errors() {
errors_panel->push_cell();
errors_panel->push_meta(click_meta);
- errors_panel->push_color(errors_panel->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ errors_panel->push_color(errors_panel->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
errors_panel->add_text(TTR("Line") + " " + itos(err.line) + ":");
errors_panel->pop(); // Color.
errors_panel->pop(); // Meta goto.
@@ -1092,7 +1093,7 @@ void ScriptTextEditor::_update_connected_methods() {
line_meta["method"] = method;
line = functions[j].get_slice(":", 1).to_int() - 1;
text_edit->set_line_gutter_metadata(line, connection_gutter, line_meta);
- text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
+ text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_editor_theme_icon(SNAME("Slot")));
text_edit->set_line_gutter_clickable(line, connection_gutter, true);
methods_found.insert(method);
break;
@@ -1171,11 +1172,11 @@ void ScriptTextEditor::_update_connected_methods() {
line_meta["type"] = "inherits";
line_meta["method"] = name;
line_meta["base_class"] = found_base_class;
- text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverride"), SNAME("EditorIcons")));
+ text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_editor_theme_icon(SNAME("MethodOverride")));
text_edit->set_line_gutter_clickable(line, connection_gutter, true);
} else {
// If method is also connected to signal, then merge icons and keep the click behavior of the slot.
- text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverrideAndSlot"), SNAME("EditorIcons")));
+ text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_editor_theme_icon(SNAME("MethodOverrideAndSlot")));
}
methods_found.insert(name);
@@ -2111,16 +2112,16 @@ void ScriptTextEditor::_enable_code_editor() {
editor_box->add_child(warnings_panel);
warnings_panel->add_theme_font_override(
- "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts")));
+ "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
warnings_panel->add_theme_font_size_override(
- "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")));
+ "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked));
editor_box->add_child(errors_panel);
errors_panel->add_theme_font_override(
- "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts")));
+ "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
errors_panel->add_theme_font_size_override(
- "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")));
+ "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
errors_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_error_clicked));
add_child(context_menu);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 247586fbfc..9eebf958ff 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_command_palette.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/inspector_dock.h"
@@ -74,10 +75,10 @@ void ShaderEditorPlugin::_update_shader_list() {
}
String _class = shader->get_class();
- if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) {
+ if (!shader_list->has_theme_icon(_class, EditorStringName(EditorIcons))) {
_class = "TextFile";
}
- Ref<Texture2D> icon = shader_list->get_theme_icon(_class, SNAME("EditorIcons"));
+ Ref<Texture2D> icon = shader_list->get_editor_theme_icon(_class);
shader_list->add_item(text, icon);
shader_list->set_item_tooltip(shader_list->get_item_count() - 1, path);
@@ -101,7 +102,7 @@ void ShaderEditorPlugin::_update_shader_list_status() {
if (se->was_compilation_successful()) {
shader_list->set_item_tag_icon(i, Ref<Texture2D>());
} else {
- shader_list->set_item_tag_icon(i, shader_list->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ shader_list->set_item_tag_icon(i, shader_list->get_editor_theme_icon(SNAME("Error")));
}
}
}
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index b0e532b136..11bec4f61c 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/item_list.h"
#include "scene/gui/split_container.h"
#include "servers/display_server.h"
@@ -67,9 +68,9 @@ void ShaderFileEditor::_version_selected(int p_option) {
Ref<Texture2D> icon;
if (bytecode->get_stage_compile_error(RD::ShaderStage(i)) != String()) {
- icon = get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("ImportFail"));
} else {
- icon = get_theme_icon(SNAME("ImportCheck"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("ImportCheck"));
}
stages[i]->set_icon(icon);
@@ -96,7 +97,7 @@ void ShaderFileEditor::_version_selected(int p_option) {
String error = bytecode->get_stage_compile_error(stage);
- error_text->push_font(get_theme_font(SNAME("source"), SNAME("EditorFonts")));
+ error_text->push_font(get_theme_font(SNAME("source"), EditorStringName(EditorFonts)));
if (error.is_empty()) {
error_text->add_text(TTR("Shader stage compiled without errors."));
@@ -112,7 +113,7 @@ void ShaderFileEditor::_update_options() {
stage_hb->hide();
versions->hide();
error_text->clear();
- error_text->push_font(get_theme_font(SNAME("source"), SNAME("EditorFonts")));
+ error_text->push_font(get_theme_font(SNAME("source"), EditorStringName(EditorFonts)));
error_text->add_text(vformat(TTR("File structure for '%s' contains unrecoverable errors:\n\n"), shader_file->get_path().get_file()));
error_text->add_text(shader_file->get_base_error());
return;
@@ -155,9 +156,9 @@ void ShaderFileEditor::_update_options() {
}
if (failed) {
- icon = get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("ImportFail"));
} else {
- icon = get_theme_icon(SNAME("ImportCheck"), SNAME("EditorIcons"));
+ icon = get_editor_theme_icon(SNAME("ImportCheck"));
}
versions->add_item(title, icon);
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index 18c2b0c6e0..9b67648322 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -98,7 +98,7 @@ Skeleton2DEditor::Skeleton2DEditor() {
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text(TTR("Skeleton2D"));
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Skeleton2D"), SNAME("EditorIcons")));
+ options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Skeleton2D")));
options->get_popup()->add_item(TTR("Reset to Rest Pose"), MENU_OPTION_SET_REST);
options->get_popup()->add_separator();
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 0a3de70e2a..7aa333c198 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_properties_vector.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "node_3d_editor_plugin.h"
@@ -106,7 +107,7 @@ void BoneTransformEditor::create_editors() {
void BoneTransformEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- const Color section_color = get_theme_color(SNAME("prop_subsection"), SNAME("Editor"));
+ const Color section_color = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor));
section->set_bg_color(section_color);
rest_section->set_bg_color(section_color);
} break;
@@ -671,7 +672,7 @@ void Skeleton3DEditor::update_joint_tree() {
items.insert(-1, root);
- Ref<Texture> bone_icon = get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"));
+ Ref<Texture> bone_icon = get_editor_theme_icon(SNAME("BoneAttachment3D"));
Vector<int> bones_to_process = skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
@@ -847,14 +848,14 @@ void Skeleton3DEditor::_notification(int p_what) {
add_theme_constant_override("separation", 0);
} break;
case NOTIFICATION_THEME_CHANGED: {
- skeleton_options->set_icon(get_theme_icon(SNAME("Skeleton3D"), SNAME("EditorIcons")));
- edit_mode_button->set_icon(get_theme_icon(SNAME("ToolBoneSelect"), SNAME("EditorIcons")));
- key_loc_button->set_icon(get_theme_icon(SNAME("KeyPosition"), SNAME("EditorIcons")));
- key_rot_button->set_icon(get_theme_icon(SNAME("KeyRotation"), SNAME("EditorIcons")));
- key_scale_button->set_icon(get_theme_icon(SNAME("KeyScale"), SNAME("EditorIcons")));
- key_insert_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
- key_insert_all_button->set_icon(get_theme_icon(SNAME("NewKey"), SNAME("EditorIcons")));
- bones_section->set_bg_color(get_theme_color(SNAME("prop_subsection"), SNAME("Editor")));
+ skeleton_options->set_icon(get_editor_theme_icon(SNAME("Skeleton3D")));
+ edit_mode_button->set_icon(get_editor_theme_icon(SNAME("ToolBoneSelect")));
+ key_loc_button->set_icon(get_editor_theme_icon(SNAME("KeyPosition")));
+ key_rot_button->set_icon(get_editor_theme_icon(SNAME("KeyRotation")));
+ key_scale_button->set_icon(get_editor_theme_icon(SNAME("KeyScale")));
+ key_insert_button->set_icon(get_editor_theme_icon(SNAME("Key")));
+ key_insert_all_button->set_icon(get_editor_theme_icon(SNAME("NewKey")));
+ bones_section->set_bg_color(get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)));
update_joint_tree();
} break;
@@ -935,7 +936,7 @@ void fragment() {
}
)");
handle_material->set_shader(handle_shader);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("EditorBoneHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("EditorBoneHandle"));
handle_material->set_shader_parameter("point_size", handle->get_width());
handle_material->set_shader_parameter("texture_albedo", handle);
@@ -1371,9 +1372,9 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
int bone_shape = EDITOR_GET("editors/3d_gizmos/gizmo_settings/bone_shape");
LocalVector<Color> axis_colors;
- axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
- axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
- axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
+ axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)));
+ axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)));
+ axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor)));
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
surface_tool->begin(Mesh::PRIMITIVE_LINES);
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index 6331209281..d081dd7c06 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -84,7 +84,7 @@ void SkeletonIK3DEditorPlugin::_bind_methods() {
SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin() {
play_btn = memnew(Button);
- play_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ play_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Play")));
play_btn->set_text(TTR("Play IK"));
play_btn->set_toggle_mode(true);
play_btn->hide();
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index f647bded95..1363669928 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -503,12 +503,12 @@ void Sprite2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- options->set_icon(get_theme_icon(SNAME("Sprite2D"), SNAME("EditorIcons")));
+ options->set_icon(get_editor_theme_icon(SNAME("Sprite2D")));
- options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_MESH_2D, get_theme_icon(SNAME("MeshInstance2D"), SNAME("EditorIcons")));
- options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_POLYGON_2D, get_theme_icon(SNAME("Polygon2D"), SNAME("EditorIcons")));
- options->get_popup()->set_item_icon(MENU_OPTION_CREATE_COLLISION_POLY_2D, get_theme_icon(SNAME("CollisionPolygon2D"), SNAME("EditorIcons")));
- options->get_popup()->set_item_icon(MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D, get_theme_icon(SNAME("LightOccluder2D"), SNAME("EditorIcons")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_MESH_2D, get_editor_theme_icon(SNAME("MeshInstance2D")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_POLYGON_2D, get_editor_theme_icon(SNAME("Polygon2D")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CREATE_COLLISION_POLY_2D, get_editor_theme_icon(SNAME("CollisionPolygon2D")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D, get_editor_theme_icon(SNAME("LightOccluder2D")));
} break;
}
}
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 720cfb5928..54b72b6b3e 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/scene_tree_dock.h"
@@ -132,12 +133,12 @@ void SpriteFramesEditor::_sheet_preview_draw() {
return;
}
- Color accent = get_theme_color("accent_color", "Editor");
+ Color accent = get_theme_color("accent_color", EditorStringName(Editor));
_sheet_sort_frames();
- Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
for (int i = 0; i < frames_ordered.size(); ++i) {
const int idx = frames_ordered[i].second;
@@ -494,9 +495,9 @@ void SpriteFramesEditor::_toggle_show_settings() {
void SpriteFramesEditor::_update_show_settings() {
if (is_layout_rtl()) {
- toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons")));
+ toggle_settings_button->set_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward")));
} else {
- toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons")));
+ toggle_settings_button->set_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back")));
}
}
@@ -550,36 +551,36 @@ void SpriteFramesEditor::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- autoplay_icon = get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons"));
- stop_icon = get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"));
- pause_icon = get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"));
+ autoplay_icon = get_editor_theme_icon(SNAME("AutoPlay"));
+ stop_icon = get_editor_theme_icon(SNAME("Stop"));
+ pause_icon = get_editor_theme_icon(SNAME("Pause"));
_update_stop_icon();
- autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")));
- anim_loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons")));
- play->set_icon(get_theme_icon(SNAME("PlayStart"), SNAME("EditorIcons")));
- play_from->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
- play_bw->set_icon(get_theme_icon(SNAME("PlayStartBackwards"), SNAME("EditorIcons")));
- play_bw_from->set_icon(get_theme_icon(SNAME("PlayBackwards"), SNAME("EditorIcons")));
-
- load->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
- load_sheet->set_icon(get_theme_icon(SNAME("SpriteSheet"), SNAME("EditorIcons")));
- copy->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
- paste->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")));
- empty_before->set_icon(get_theme_icon(SNAME("InsertBefore"), SNAME("EditorIcons")));
- empty_after->set_icon(get_theme_icon(SNAME("InsertAfter"), SNAME("EditorIcons")));
- move_up->set_icon(get_theme_icon(SNAME("MoveLeft"), SNAME("EditorIcons")));
- move_down->set_icon(get_theme_icon(SNAME("MoveRight"), SNAME("EditorIcons")));
- delete_frame->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
- zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
- add_anim->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons")));
- delete_anim->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- anim_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- split_sheet_zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
- split_sheet_zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
+ autoplay->set_icon(get_editor_theme_icon(SNAME("AutoPlay")));
+ anim_loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
+ play->set_icon(get_editor_theme_icon(SNAME("PlayStart")));
+ play_from->set_icon(get_editor_theme_icon(SNAME("Play")));
+ play_bw->set_icon(get_editor_theme_icon(SNAME("PlayStartBackwards")));
+ play_bw_from->set_icon(get_editor_theme_icon(SNAME("PlayBackwards")));
+
+ load->set_icon(get_editor_theme_icon(SNAME("Load")));
+ load_sheet->set_icon(get_editor_theme_icon(SNAME("SpriteSheet")));
+ copy->set_icon(get_editor_theme_icon(SNAME("ActionCopy")));
+ paste->set_icon(get_editor_theme_icon(SNAME("ActionPaste")));
+ empty_before->set_icon(get_editor_theme_icon(SNAME("InsertBefore")));
+ empty_after->set_icon(get_editor_theme_icon(SNAME("InsertAfter")));
+ move_up->set_icon(get_editor_theme_icon(SNAME("MoveLeft")));
+ move_down->set_icon(get_editor_theme_icon(SNAME("MoveRight")));
+ delete_frame->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess")));
+ zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset")));
+ zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore")));
+ add_anim->set_icon(get_editor_theme_icon(SNAME("New")));
+ delete_anim->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ anim_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ split_sheet_zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess")));
+ split_sheet_zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset")));
+ split_sheet_zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore")));
split_sheet_scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
_update_show_settings();
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index 9364b96c90..9b1c208a9f 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -57,8 +57,8 @@ void StyleBoxPreview::edit(const Ref<StyleBox> &p_stylebox) {
void StyleBoxPreview::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- set_texture(get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons")));
- grid_preview->set_icon(get_theme_icon(SNAME("StyleBoxGrid"), SNAME("EditorIcons")));
+ set_texture(get_editor_theme_icon(SNAME("Checkerboard")));
+ grid_preview->set_icon(get_editor_theme_icon(SNAME("StyleBoxGrid")));
} break;
case NOTIFICATION_DRAW: {
_redraw();
@@ -68,7 +68,7 @@ void StyleBoxPreview::_notification(int p_what) {
void StyleBoxPreview::_redraw() {
if (stylebox.is_valid()) {
- float grid_button_width = get_theme_icon(SNAME("StyleBoxGrid"), SNAME("EditorIcons"))->get_size().x;
+ float grid_button_width = get_editor_theme_icon(SNAME("StyleBoxGrid"))->get_size().x;
Rect2 preview_rect = get_rect();
preview_rect = preview_rect.grow(-grid_button_width);
diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp
index 932a255982..27e32cc8f7 100644
--- a/editor/plugins/text_shader_editor.cpp
+++ b/editor/plugins/text_shader_editor.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/filesystem_dock.h"
#include "editor/project_settings_editor.h"
#include "scene/gui/split_container.h"
@@ -178,7 +179,14 @@ void ShaderTextEditor::set_edited_code(const String &p_code) {
}
void ShaderTextEditor::reload_text() {
- ERR_FAIL_COND(shader.is_null());
+ ERR_FAIL_COND(shader.is_null() && shader_inc.is_null());
+
+ String code;
+ if (shader.is_valid()) {
+ code = shader->get_code();
+ } else {
+ code = shader_inc->get_code();
+ }
CodeEdit *te = get_text_editor();
int column = te->get_caret_column();
@@ -186,7 +194,7 @@ void ShaderTextEditor::reload_text() {
int h = te->get_h_scroll();
int v = te->get_v_scroll();
- te->set_text(shader->get_code());
+ te->set_text(code);
te->set_caret_line(row);
te->set_caret_column(column);
te->set_h_scroll(h);
@@ -319,8 +327,8 @@ void ShaderTextEditor::_load_theme_settings() {
if (warnings_panel) {
// Warnings panel.
- warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts")));
- warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")));
+ warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
+ warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
}
}
@@ -586,7 +594,7 @@ void ShaderTextEditor::_update_warning_panel() {
// First cell.
warnings_panel->push_cell();
- warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
if (line != -1) {
warnings_panel->push_meta(line - 1);
warnings_panel->add_text(TTR("Line") + " " + itos(line));
@@ -717,7 +725,7 @@ void TextShaderEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
PopupMenu *popup = help_menu->get_popup();
- popup->set_item_icon(popup->get_item_index(HELP_DOCS), get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
+ popup->set_item_icon(popup->get_item_index(HELP_DOCS), get_editor_theme_icon(SNAME("ExternalLink")));
} break;
case NOTIFICATION_APPLICATION_FOCUS_IN: {
@@ -1159,7 +1167,7 @@ TextShaderEditor::TextShaderEditor() {
hbc->add_child(edit_menu);
hbc->add_child(goto_menu);
hbc->add_child(help_menu);
- hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
+ hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles)));
VSplitContainer *editor_box = memnew(VSplitContainer);
main_container->add_child(editor_box);
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index 2702e94188..1b5c2dcab1 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -43,7 +43,7 @@ void Texture3DEditor::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
- Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ Ref<Texture2D> checkerboard = get_editor_theme_icon(SNAME("Checkerboard"));
Size2 size = get_size();
draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 87b207ebcd..74a03c1e97 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "texture_editor_plugin.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/label.h"
#include "scene/gui/texture_rect.h"
#include "scene/resources/animated_texture.h"
@@ -55,11 +56,11 @@ void TexturePreview::_notification(int p_what) {
}
if (metadata_label) {
- Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), SNAME("EditorFonts"));
+ Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), EditorStringName(EditorFonts));
metadata_label->add_theme_font_override("font", metadata_label_font);
}
- checkerboard->set_texture(get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons")));
+ checkerboard->set_texture(get_editor_theme_icon(SNAME("Checkerboard")));
} break;
}
}
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index a0188b08e5..20e7b5d8c4 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -54,7 +54,7 @@ void TextureLayeredEditor::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
- Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ Ref<Texture2D> checkerboard = get_editor_theme_icon(SNAME("Checkerboard"));
Size2 size = get_size();
draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 124cd79126..8df7be766b 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/check_box.h"
#include "scene/gui/option_button.h"
@@ -73,7 +74,7 @@ void TextureRegionEditor::_texture_overlay_draw() {
}
Transform2D mtx = _get_offset_transform();
- const Color color = get_theme_color(SNAME("mono_color"), SNAME("Editor"));
+ const Color color = get_theme_color(SNAME("mono_color"), EditorStringName(Editor));
if (snap_mode == SNAP_GRID) {
const Color grid_color = Color(color.r, color.g, color.b, color.a * 0.15);
@@ -146,7 +147,7 @@ void TextureRegionEditor::_texture_overlay_draw() {
}
}
- Ref<Texture2D> select_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> select_handle = get_editor_theme_icon(SNAME("EditorHandle"));
Rect2 scroll_rect(Point2(), object_texture->get_size());
@@ -264,7 +265,7 @@ void TextureRegionEditor::_draw_margin_line(Vector2 p_from, Vector2 p_to) {
Vector2 dash_size = (p_to - p_from).normalized() * 10;
const int dash_thickness = Math::round(2 * EDSCALE);
- const Color dash_color = get_theme_color(SNAME("mono_color"), SNAME("Editor"));
+ const Color dash_color = get_theme_color(SNAME("mono_color"), EditorStringName(Editor));
const Color dash_bg_color = dash_color.inverted() * Color(1, 1, 1, 0.5);
const int line_threshold = 200;
@@ -822,12 +823,12 @@ void TextureRegionEditor::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- texture_preview->add_theme_style_override("panel", get_theme_stylebox(SNAME("TextureRegionPreviewBG"), SNAME("EditorStyles")));
- texture_overlay->add_theme_style_override("panel", get_theme_stylebox(SNAME("TextureRegionPreviewFG"), SNAME("EditorStyles")));
+ texture_preview->add_theme_style_override("panel", get_theme_stylebox(SNAME("TextureRegionPreviewBG"), EditorStringName(EditorStyles)));
+ texture_overlay->add_theme_style_override("panel", get_theme_stylebox(SNAME("TextureRegionPreviewFG"), EditorStringName(EditorStyles)));
- zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
- zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
- zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
+ zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess")));
+ zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset")));
+ zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore")));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -1226,7 +1227,7 @@ bool EditorInspectorPluginTextureRegion::parse_property(Object *p_object, const
if ((p_type == Variant::RECT2 || p_type == Variant::RECT2I)) {
if (((Object::cast_to<Sprite2D>(p_object) || Object::cast_to<Sprite3D>(p_object) || Object::cast_to<NinePatchRect>(p_object) || Object::cast_to<StyleBoxTexture>(p_object)) && p_path == "region_rect") || (Object::cast_to<AtlasTexture>(p_object) && p_path == "region")) {
Button *button = EditorInspector::create_inspector_action_button(TTR("Edit Region"));
- button->set_icon(texture_region_editor->get_theme_icon(SNAME("RegionEdit"), SNAME("EditorIcons")));
+ button->set_icon(texture_region_editor->get_editor_theme_icon(SNAME("RegionEdit")));
button->connect("pressed", callable_mp(this, &EditorInspectorPluginTextureRegion::_region_edit).bind(p_object));
add_property_editor(p_path, button, true);
}
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 97ab6d04f4..ffe6c01ef0 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_resource_picker.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/progress_dialog.h"
@@ -84,7 +85,7 @@ void ThemeItemImportTree::_update_items_tree() {
Ref<Texture2D> type_icon;
if (E == "") {
- type_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons"));
+ type_icon = get_editor_theme_icon(SNAME("NodeDisabled"));
} else {
type_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
}
@@ -147,7 +148,7 @@ void ThemeItemImportTree::_update_items_tree() {
switch (dt) {
case Theme::DATA_TYPE_COLOR:
- data_type_node->set_icon(0, get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("Color")));
data_type_node->set_text(0, TTR("Colors"));
item_list = &tree_color_items;
@@ -155,7 +156,7 @@ void ThemeItemImportTree::_update_items_tree() {
break;
case Theme::DATA_TYPE_CONSTANT:
- data_type_node->set_icon(0, get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("MemberConstant")));
data_type_node->set_text(0, TTR("Constants"));
item_list = &tree_constant_items;
@@ -163,7 +164,7 @@ void ThemeItemImportTree::_update_items_tree() {
break;
case Theme::DATA_TYPE_FONT:
- data_type_node->set_icon(0, get_theme_icon(SNAME("Font"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("Font")));
data_type_node->set_text(0, TTR("Fonts"));
item_list = &tree_font_items;
@@ -171,7 +172,7 @@ void ThemeItemImportTree::_update_items_tree() {
break;
case Theme::DATA_TYPE_FONT_SIZE:
- data_type_node->set_icon(0, get_theme_icon(SNAME("FontSize"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("FontSize")));
data_type_node->set_text(0, TTR("Font Sizes"));
item_list = &tree_font_size_items;
@@ -179,7 +180,7 @@ void ThemeItemImportTree::_update_items_tree() {
break;
case Theme::DATA_TYPE_ICON:
- data_type_node->set_icon(0, get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("ImageTexture")));
data_type_node->set_text(0, TTR("Icons"));
item_list = &tree_icon_items;
@@ -187,7 +188,7 @@ void ThemeItemImportTree::_update_items_tree() {
break;
case Theme::DATA_TYPE_STYLEBOX:
- data_type_node->set_icon(0, get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons")));
+ data_type_node->set_icon(0, get_editor_theme_icon(SNAME("StyleBoxFlat")));
data_type_node->set_text(0, TTR("Styleboxes"));
item_list = &tree_stylebox_items;
@@ -851,49 +852,49 @@ void ThemeItemImportTree::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- select_icons_warning_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ select_icons_warning_icon->set_texture(get_editor_theme_icon(SNAME("StatusWarning")));
+ select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
- import_items_filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ import_items_filter->set_right_icon(get_editor_theme_icon(SNAME("Search")));
// Bottom panel buttons.
- import_collapse_types_button->set_icon(get_theme_icon(SNAME("CollapseTree"), SNAME("EditorIcons")));
- import_expand_types_button->set_icon(get_theme_icon(SNAME("ExpandTree"), SNAME("EditorIcons")));
+ import_collapse_types_button->set_icon(get_editor_theme_icon(SNAME("CollapseTree")));
+ import_expand_types_button->set_icon(get_editor_theme_icon(SNAME("ExpandTree")));
- import_select_all_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- import_select_full_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
- import_deselect_all_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
+ import_select_all_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ import_select_full_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+ import_deselect_all_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
// Side panel buttons.
- select_colors_icon->set_texture(get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
- deselect_all_colors_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_colors_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_colors_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
-
- select_constants_icon->set_texture(get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons")));
- deselect_all_constants_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_constants_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_constants_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
-
- select_fonts_icon->set_texture(get_theme_icon(SNAME("Font"), SNAME("EditorIcons")));
- deselect_all_fonts_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_fonts_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_fonts_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
-
- select_font_sizes_icon->set_texture(get_theme_icon(SNAME("FontSize"), SNAME("EditorIcons")));
- deselect_all_font_sizes_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_font_sizes_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_font_sizes_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
-
- select_icons_icon->set_texture(get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
- deselect_all_icons_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_icons_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_icons_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
-
- select_styleboxes_icon->set_texture(get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons")));
- deselect_all_styleboxes_button->set_icon(get_theme_icon(SNAME("ThemeDeselectAll"), SNAME("EditorIcons")));
- select_all_styleboxes_button->set_icon(get_theme_icon(SNAME("ThemeSelectAll"), SNAME("EditorIcons")));
- select_full_styleboxes_button->set_icon(get_theme_icon(SNAME("ThemeSelectFull"), SNAME("EditorIcons")));
+ select_colors_icon->set_texture(get_editor_theme_icon(SNAME("Color")));
+ deselect_all_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+
+ select_constants_icon->set_texture(get_editor_theme_icon(SNAME("MemberConstant")));
+ deselect_all_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+
+ select_fonts_icon->set_texture(get_editor_theme_icon(SNAME("Font")));
+ deselect_all_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+
+ select_font_sizes_icon->set_texture(get_editor_theme_icon(SNAME("FontSize")));
+ deselect_all_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+
+ select_icons_icon->set_texture(get_editor_theme_icon(SNAME("ImageTexture")));
+ deselect_all_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
+
+ select_styleboxes_icon->set_texture(get_editor_theme_icon(SNAME("StyleBoxFlat")));
+ deselect_all_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll")));
+ select_all_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll")));
+ select_full_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull")));
} break;
}
}
@@ -1216,7 +1217,7 @@ void ThemeItemEditorDialog::_dialog_about_to_show() {
import_default_theme_items->reset_item_tree();
import_editor_theme_items->set_edited_theme(edited_theme);
- import_editor_theme_items->set_base_theme(EditorNode::get_singleton()->get_theme_base()->get_theme());
+ import_editor_theme_items->set_base_theme(EditorNode::get_singleton()->get_editor_theme());
import_editor_theme_items->reset_item_tree();
import_other_theme_items->set_edited_theme(edited_theme);
@@ -1237,14 +1238,14 @@ void ThemeItemEditorDialog::_update_edit_types() {
for (const StringName &E : theme_types) {
Ref<Texture2D> item_icon;
if (E == "") {
- item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons"));
+ item_icon = get_editor_theme_icon(SNAME("NodeDisabled"));
} else {
item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
}
TreeItem *list_item = edit_type_list->create_item(list_root);
list_item->set_text(0, E);
list_item->set_icon(0, item_icon);
- list_item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TYPES_TREE_REMOVE_ITEM, false, TTR("Remove Type"));
+ list_item->add_button(0, get_editor_theme_icon(SNAME("Remove")), TYPES_TREE_REMOVE_ITEM, false, TTR("Remove Type"));
if (E == edited_item_type) {
list_item->select(0);
@@ -1340,16 +1341,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *color_root = edit_items_tree->create_item(root);
color_root->set_metadata(0, Theme::DATA_TYPE_COLOR);
- color_root->set_icon(0, get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
+ color_root->set_icon(0, get_editor_theme_icon(SNAME("Color")));
color_root->set_text(0, TTR("Colors"));
- color_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Color Items"));
+ color_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Color Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(color_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1363,16 +1364,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *constant_root = edit_items_tree->create_item(root);
constant_root->set_metadata(0, Theme::DATA_TYPE_CONSTANT);
- constant_root->set_icon(0, get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons")));
+ constant_root->set_icon(0, get_editor_theme_icon(SNAME("MemberConstant")));
constant_root->set_text(0, TTR("Constants"));
- constant_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Constant Items"));
+ constant_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Constant Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(constant_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1386,16 +1387,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *font_root = edit_items_tree->create_item(root);
font_root->set_metadata(0, Theme::DATA_TYPE_FONT);
- font_root->set_icon(0, get_theme_icon(SNAME("Font"), SNAME("EditorIcons")));
+ font_root->set_icon(0, get_editor_theme_icon(SNAME("Font")));
font_root->set_text(0, TTR("Fonts"));
- font_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Items"));
+ font_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(font_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1409,16 +1410,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *font_size_root = edit_items_tree->create_item(root);
font_size_root->set_metadata(0, Theme::DATA_TYPE_FONT_SIZE);
- font_size_root->set_icon(0, get_theme_icon(SNAME("FontSize"), SNAME("EditorIcons")));
+ font_size_root->set_icon(0, get_editor_theme_icon(SNAME("FontSize")));
font_size_root->set_text(0, TTR("Font Sizes"));
- font_size_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Size Items"));
+ font_size_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Font Size Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(font_size_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1432,16 +1433,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *icon_root = edit_items_tree->create_item(root);
icon_root->set_metadata(0, Theme::DATA_TYPE_ICON);
- icon_root->set_icon(0, get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
+ icon_root->set_icon(0, get_editor_theme_icon(SNAME("ImageTexture")));
icon_root->set_text(0, TTR("Icons"));
- icon_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Icon Items"));
+ icon_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All Icon Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(icon_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1455,16 +1456,16 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
if (names.size() > 0) {
TreeItem *stylebox_root = edit_items_tree->create_item(root);
stylebox_root->set_metadata(0, Theme::DATA_TYPE_STYLEBOX);
- stylebox_root->set_icon(0, get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons")));
+ stylebox_root->set_icon(0, get_editor_theme_icon(SNAME("StyleBoxFlat")));
stylebox_root->set_text(0, TTR("Styleboxes"));
- stylebox_root->add_button(0, get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All StyleBox Items"));
+ stylebox_root->add_button(0, get_editor_theme_icon(SNAME("Clear")), ITEMS_TREE_REMOVE_DATA_TYPE, false, TTR("Remove All StyleBox Items"));
names.sort_custom<StringName::AlphCompare>();
for (const StringName &E : names) {
TreeItem *item = edit_items_tree->create_item(stylebox_root);
item->set_text(0, E);
- item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
- item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Edit")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
+ item->add_button(0, get_editor_theme_icon(SNAME("Remove")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
has_any_items = true;
@@ -1872,20 +1873,20 @@ void ThemeItemEditorDialog::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
- edit_items_add_color->set_icon(get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
- edit_items_add_constant->set_icon(get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons")));
- edit_items_add_font->set_icon(get_theme_icon(SNAME("Font"), SNAME("EditorIcons")));
- edit_items_add_font_size->set_icon(get_theme_icon(SNAME("FontSize"), SNAME("EditorIcons")));
- edit_items_add_icon->set_icon(get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
- edit_items_add_stylebox->set_icon(get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons")));
+ edit_items_add_color->set_icon(get_editor_theme_icon(SNAME("Color")));
+ edit_items_add_constant->set_icon(get_editor_theme_icon(SNAME("MemberConstant")));
+ edit_items_add_font->set_icon(get_editor_theme_icon(SNAME("Font")));
+ edit_items_add_font_size->set_icon(get_editor_theme_icon(SNAME("FontSize")));
+ edit_items_add_icon->set_icon(get_editor_theme_icon(SNAME("ImageTexture")));
+ edit_items_add_stylebox->set_icon(get_editor_theme_icon(SNAME("StyleBoxFlat")));
- edit_items_remove_class->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
- edit_items_remove_custom->set_icon(get_theme_icon(SNAME("ThemeRemoveCustomItems"), SNAME("EditorIcons")));
- edit_items_remove_all->set_icon(get_theme_icon(SNAME("ThemeRemoveAllItems"), SNAME("EditorIcons")));
+ edit_items_remove_class->set_icon(get_editor_theme_icon(SNAME("Control")));
+ edit_items_remove_custom->set_icon(get_editor_theme_icon(SNAME("ThemeRemoveCustomItems")));
+ edit_items_remove_all->set_icon(get_editor_theme_icon(SNAME("ThemeRemoveAllItems")));
- edit_add_type_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ edit_add_type_button->set_icon(get_editor_theme_icon(SNAME("Add")));
- import_another_theme_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ import_another_theme_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
} break;
}
}
@@ -2154,7 +2155,7 @@ void ThemeTypeDialog::_update_add_type_options(const String &p_filter) {
Ref<Texture2D> item_icon;
if (E == "") {
- item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons"));
+ item_icon = get_editor_theme_icon(SNAME("NodeDisabled"));
} else {
item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
}
@@ -2329,7 +2330,7 @@ void ThemeTypeEditor::_update_type_list() {
for (const StringName &E : theme_types) {
Ref<Texture2D> item_icon;
if (E == "") {
- item_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons"));
+ item_icon = get_editor_theme_icon(SNAME("NodeDisabled"));
} else {
item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
}
@@ -2428,21 +2429,21 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_
item_name_edit->hide();
Button *item_rename_button = memnew(Button);
- item_rename_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ item_rename_button->set_icon(get_editor_theme_icon(SNAME("Edit")));
item_rename_button->set_tooltip_text(TTR("Rename Item"));
item_rename_button->set_flat(true);
item_name_container->add_child(item_rename_button);
item_rename_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_cbk).bind(p_data_type, p_item_name, item_name_container));
Button *item_remove_button = memnew(Button);
- item_remove_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ item_remove_button->set_icon(get_editor_theme_icon(SNAME("Remove")));
item_remove_button->set_tooltip_text(TTR("Remove Item"));
item_remove_button->set_flat(true);
item_name_container->add_child(item_remove_button);
item_remove_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_remove_cbk).bind(p_data_type, p_item_name));
Button *item_rename_confirm_button = memnew(Button);
- item_rename_confirm_button->set_icon(get_theme_icon(SNAME("ImportCheck"), SNAME("EditorIcons")));
+ item_rename_confirm_button->set_icon(get_editor_theme_icon(SNAME("ImportCheck")));
item_rename_confirm_button->set_tooltip_text(TTR("Confirm Item Rename"));
item_rename_confirm_button->set_flat(true);
item_name_container->add_child(item_rename_confirm_button);
@@ -2450,17 +2451,17 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_
item_rename_confirm_button->hide();
Button *item_rename_cancel_button = memnew(Button);
- item_rename_cancel_button->set_icon(get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons")));
+ item_rename_cancel_button->set_icon(get_editor_theme_icon(SNAME("ImportFail")));
item_rename_cancel_button->set_tooltip_text(TTR("Cancel Item Rename"));
item_rename_cancel_button->set_flat(true);
item_name_container->add_child(item_rename_cancel_button);
item_rename_cancel_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_canceled).bind(p_data_type, p_item_name, item_name_container));
item_rename_cancel_button->hide();
} else {
- item_name->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ item_name->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)));
Button *item_override_button = memnew(Button);
- item_override_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ item_override_button->set_icon(get_editor_theme_icon(SNAME("Add")));
item_override_button->set_tooltip_text(TTR("Override Item"));
item_override_button->set_flat(true);
item_name_container->add_child(item_override_button);
@@ -2670,7 +2671,7 @@ void ThemeTypeEditor::_update_type_items() {
pin_leader_button->set_flat(true);
pin_leader_button->set_toggle_mode(true);
pin_leader_button->set_pressed(true);
- pin_leader_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
+ pin_leader_button->set_icon(get_editor_theme_icon(SNAME("Pin")));
pin_leader_button->set_tooltip_text(TTR("Unpin this StyleBox as a main style."));
item_control->add_child(pin_leader_button);
pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_unpin_leader_button_pressed));
@@ -2713,7 +2714,7 @@ void ThemeTypeEditor::_update_type_items() {
Button *pin_leader_button = memnew(Button);
pin_leader_button->set_flat(true);
pin_leader_button->set_toggle_mode(true);
- pin_leader_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
+ pin_leader_button->set_icon(get_editor_theme_icon(SNAME("Pin")));
pin_leader_button->set_tooltip_text(TTR("Pin this StyleBox as a main style. Editing its properties will update the same properties in all other StyleBoxes of this type."));
item_control->add_child(pin_leader_button);
pin_leader_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed).bind(item_editor, E.key));
@@ -3313,17 +3314,17 @@ void ThemeTypeEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- add_type_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ add_type_button->set_icon(get_editor_theme_icon(SNAME("Add")));
- data_type_tabs->set_tab_icon(0, get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(1, get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(2, get_theme_icon(SNAME("Font"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(3, get_theme_icon(SNAME("FontSize"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(4, get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(5, get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons")));
- data_type_tabs->set_tab_icon(6, get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
+ data_type_tabs->set_tab_icon(0, get_editor_theme_icon(SNAME("Color")));
+ data_type_tabs->set_tab_icon(1, get_editor_theme_icon(SNAME("MemberConstant")));
+ data_type_tabs->set_tab_icon(2, get_editor_theme_icon(SNAME("Font")));
+ data_type_tabs->set_tab_icon(3, get_editor_theme_icon(SNAME("FontSize")));
+ data_type_tabs->set_tab_icon(4, get_editor_theme_icon(SNAME("ImageTexture")));
+ data_type_tabs->set_tab_icon(5, get_editor_theme_icon(SNAME("StyleBoxFlat")));
+ data_type_tabs->set_tab_icon(6, get_editor_theme_icon(SNAME("Tools")));
- type_variation_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ type_variation_button->set_icon(get_editor_theme_icon(SNAME("Add")));
} break;
}
}
@@ -3537,7 +3538,7 @@ void ThemeEditor::_preview_scene_dialog_cbk(const String &p_path) {
return;
}
- _add_preview_tab(preview_tab, p_path.get_file(), get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")));
+ _add_preview_tab(preview_tab, p_path.get_file(), get_editor_theme_icon(SNAME("PackedScene")));
preview_tab->connect("scene_invalidated", callable_mp(this, &ThemeEditor::_remove_preview_tab_invalid).bind(preview_tab));
preview_tab->connect("scene_reloaded", callable_mp(this, &ThemeEditor::_update_preview_tab).bind(preview_tab));
}
@@ -3610,11 +3611,11 @@ void ThemeEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- preview_tabs->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("ThemeEditorPreviewFG"), SNAME("EditorStyles")));
- preview_tabs->add_theme_style_override("tab_unselected", get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), SNAME("EditorStyles")));
+ preview_tabs->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("ThemeEditorPreviewFG"), EditorStringName(EditorStyles)));
+ preview_tabs->add_theme_style_override("tab_unselected", get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), EditorStringName(EditorStyles)));
preview_tabs_content->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainerOdd")));
- add_preview_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ add_preview_button->set_icon(get_editor_theme_icon(SNAME("Add")));
} break;
}
}
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index fb8cb57d4d..61bce0a89c 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -35,6 +35,7 @@
#include "core/math/math_funcs.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/button.h"
#include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
@@ -201,16 +202,22 @@ void ThemeEditorPreview::_notification(int p_what) {
}
connect("visibility_changed", callable_mp(this, &ThemeEditorPreview::_preview_visibility_changed));
- [[fallthrough]];
- }
+ } break;
+
+ case NOTIFICATION_READY: {
+ List<Ref<Theme>> preview_themes;
+ preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme());
+ ThemeDB::get_singleton()->create_theme_context(preview_root, preview_themes);
+ } break;
+
case NOTIFICATION_THEME_CHANGED: {
- picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
+ picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick")));
theme_cache.preview_picker_overlay = get_theme_stylebox(SNAME("preview_picker_overlay"), SNAME("ThemeEditor"));
theme_cache.preview_picker_overlay_color = get_theme_color(SNAME("preview_picker_overlay_color"), SNAME("ThemeEditor"));
theme_cache.preview_picker_label = get_theme_stylebox(SNAME("preview_picker_label"), SNAME("ThemeEditor"));
- theme_cache.preview_picker_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts"));
- theme_cache.font_size = get_theme_font_size(SNAME("font_size"), SNAME("EditorFonts"));
+ theme_cache.preview_picker_font = get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts));
+ theme_cache.font_size = get_theme_font_size(SNAME("font_size"), EditorStringName(EditorFonts));
} break;
case NOTIFICATION_PROCESS: {
@@ -246,9 +253,8 @@ ThemeEditorPreview::ThemeEditorPreview() {
preview_container = memnew(ScrollContainer);
preview_body->add_child(preview_container);
- MarginContainer *preview_root = memnew(MarginContainer);
+ preview_root = memnew(MarginContainer);
preview_container->add_child(preview_root);
- preview_root->set_theme(ThemeDB::get_singleton()->get_default_theme());
preview_root->set_clip_contents(true);
preview_root->set_custom_minimum_size(Size2(450, 0) * EDSCALE);
preview_root->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -282,7 +288,7 @@ void DefaultThemeEditorPreview::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- test_color_picker_button->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
+ test_color_picker_button->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
} break;
}
}
@@ -485,7 +491,7 @@ void SceneThemeEditorPreview::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- reload_scene_button->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ reload_scene_button->set_icon(get_editor_theme_icon(SNAME("Reload")));
} break;
}
}
diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h
index bd9663904a..ed888e6c14 100644
--- a/editor/plugins/theme_editor_preview.h
+++ b/editor/plugins/theme_editor_preview.h
@@ -44,6 +44,7 @@ class ThemeEditorPreview : public VBoxContainer {
GDCLASS(ThemeEditorPreview, VBoxContainer);
ScrollContainer *preview_container = nullptr;
+ MarginContainer *preview_root = nullptr;
ColorRect *preview_bg = nullptr;
MarginContainer *preview_overlay = nullptr;
Control *picker_overlay = nullptr;
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index fd74e6f8ca..b55be8b3f8 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -572,8 +572,8 @@ void TileAtlasView::queue_redraw() {
void TileAtlasView::_update_theme_item_cache() {
Control::_update_theme_item_cache();
- theme_cache.center_view_icon = get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons"));
- theme_cache.checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ theme_cache.center_view_icon = get_editor_theme_icon(SNAME("CenterView"));
+ theme_cache.checkerboard = get_editor_theme_icon(SNAME("Checkerboard"));
}
void TileAtlasView::_notification(int p_what) {
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 0fbce2a677..26487e8dfd 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/control.h"
@@ -137,9 +138,9 @@ void GenericTilePolygonEditor::_base_control_draw() {
real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color");
- const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
- const Ref<Texture2D> add_handle = get_theme_icon(SNAME("EditorHandleAdd"), SNAME("EditorIcons"));
- const Ref<StyleBox> focus_stylebox = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"));
+ const Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
+ const Ref<Texture2D> add_handle = get_editor_theme_icon(SNAME("EditorHandleAdd"));
+ const Ref<StyleBox> focus_stylebox = get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles));
// Draw the focus rectangle.
if (base_control->has_focus()) {
@@ -807,22 +808,22 @@ void GenericTilePolygonEditor::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
- button_expand->set_icon(get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons")));
- button_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
- button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
- button_advanced_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- button_pixel_snap->get_popup()->set_item_icon(0, get_theme_icon(SNAME("SnapDisable"), SNAME("EditorIcons")));
- button_pixel_snap->get_popup()->set_item_icon(1, get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- button_pixel_snap->get_popup()->set_item_icon(2, get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ button_expand->set_icon(get_editor_theme_icon(SNAME("DistractionFree")));
+ button_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate")));
+ button_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit")));
+ button_delete->set_icon(get_editor_theme_icon(SNAME("CurveDelete")));
+ button_center_view->set_icon(get_editor_theme_icon(SNAME("CenterView")));
+ button_advanced_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ button_pixel_snap->get_popup()->set_item_icon(0, get_editor_theme_icon(SNAME("SnapDisable")));
+ button_pixel_snap->get_popup()->set_item_icon(1, get_editor_theme_icon(SNAME("Snap")));
+ button_pixel_snap->get_popup()->set_item_icon(2, get_editor_theme_icon(SNAME("SnapGrid")));
button_pixel_snap->set_icon(button_pixel_snap->get_popup()->get_item_icon(current_snap_option));
PopupMenu *p = button_advanced_menu->get_popup();
- p->set_item_icon(p->get_item_index(ROTATE_RIGHT), get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons")));
- p->set_item_icon(p->get_item_index(ROTATE_LEFT), get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons")));
- p->set_item_icon(p->get_item_index(FLIP_HORIZONTALLY), get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons")));
- p->set_item_icon(p->get_item_index(FLIP_VERTICALLY), get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons")));
+ p->set_item_icon(p->get_item_index(ROTATE_RIGHT), get_editor_theme_icon(SNAME("RotateRight")));
+ p->set_item_icon(p->get_item_index(ROTATE_LEFT), get_editor_theme_icon(SNAME("RotateLeft")));
+ p->set_item_icon(p->get_item_index(FLIP_HORIZONTALLY), get_editor_theme_icon(SNAME("MirrorX")));
+ p->set_item_icon(p->get_item_index(FLIP_VERTICALLY), get_editor_theme_icon(SNAME("MirrorY")));
} break;
}
}
@@ -882,10 +883,10 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
button_advanced_menu->get_popup()->add_item(TTR("Reset to default tile shape"), RESET_TO_DEFAULT_TILE, Key::F);
button_advanced_menu->get_popup()->add_item(TTR("Clear"), CLEAR_TILE, Key::C);
button_advanced_menu->get_popup()->add_separator();
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons")), TTR("Rotate Right"), ROTATE_RIGHT, Key::R);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons")), TTR("Rotate Left"), ROTATE_LEFT, Key::E);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons")), TTR("Flip Horizontally"), FLIP_HORIZONTALLY, Key::H);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons")), TTR("Flip Vertically"), FLIP_VERTICALLY, Key::V);
+ button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("RotateRight")), TTR("Rotate Right"), ROTATE_RIGHT, Key::R);
+ button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("RotateLeft")), TTR("Rotate Left"), ROTATE_LEFT, Key::E);
+ button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("MirrorX")), TTR("Flip Horizontally"), FLIP_HORIZONTALLY, Key::H);
+ button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("MirrorY")), TTR("Flip Vertically"), FLIP_VERTICALLY, Key::V);
button_advanced_menu->get_popup()->connect("id_pressed", callable_mp(this, &GenericTilePolygonEditor::_advanced_menu_item_pressed));
button_advanced_menu->set_focus_mode(FOCUS_ALL);
toolbar->add_child(button_advanced_menu);
@@ -936,7 +937,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
root->add_child(editor_zoom_widget);
button_center_view = memnew(Button);
- button_center_view->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
+ button_center_view->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("CenterView")));
button_center_view->set_anchors_and_offsets_preset(Control::PRESET_TOP_RIGHT, Control::PRESET_MODE_MINSIZE, 5);
button_center_view->connect("pressed", callable_mp(this, &GenericTilePolygonEditor::_center_view));
button_center_view->set_flat(true);
@@ -1205,8 +1206,8 @@ void TileDataDefaultEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2
Rect2 rect = p_transform.xform(Rect2(Vector2(-size / 2, -size / 2) - texture_origin, Vector2(size, size)));
p_canvas_item->draw_rect(rect, value);
} else {
- Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
String text;
// Round floating point precision to 2 digits, as tiles don't have that much space.
switch (value.get_type()) {
@@ -1284,9 +1285,9 @@ void TileDataDefaultEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
- tile_bool_checked = get_theme_icon(SNAME("TileChecked"), SNAME("EditorIcons"));
- tile_bool_unchecked = get_theme_icon(SNAME("TileUnchecked"), SNAME("EditorIcons"));
+ picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick")));
+ tile_bool_checked = get_editor_theme_icon(SNAME("TileChecked"));
+ tile_bool_unchecked = get_editor_theme_icon(SNAME("TileUnchecked"));
} break;
}
}
@@ -1334,11 +1335,11 @@ void TileDataTextureOriginEditor::draw_over_tile(CanvasItem *p_canvas_item, Tran
}
if (atlas_source->is_position_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, Vector2())) {
- Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
+ Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorPosition"));
p_canvas_item->draw_texture(position_icon, p_transform.xform(Vector2()) - (position_icon->get_size() / 2), color);
} else {
- Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
Vector2 texture_origin = tile_data->get_texture_origin();
String text = vformat("%s", texture_origin);
Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
@@ -1364,7 +1365,7 @@ void TileDataPositionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform
Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
color = selection_color;
}
- Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
+ Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorPosition"));
p_canvas_item->draw_texture(position_icon, p_transform.xform(Vector2(value)) - position_icon->get_size() / 2, color);
}
@@ -1382,11 +1383,11 @@ void TileDataYSortEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2D
TileSetSource *source = *(tile_set->get_source(p_cell.source_id));
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source->is_position_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, Vector2(0, tile_data->get_y_sort_origin()))) {
- Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
+ Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorPosition"));
p_canvas_item->draw_texture(position_icon, p_transform.xform(Vector2(0, tile_data->get_y_sort_origin())) - position_icon->get_size() / 2, color);
} else {
- Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
String text = vformat("%s", tile_data->get_y_sort_origin());
Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
@@ -1733,7 +1734,7 @@ void TileDataCollisionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfor
RenderingServer::get_singleton()->canvas_item_add_set_transform(p_canvas_item->get_canvas_item(), p_transform);
- Ref<Texture2D> one_way_icon = get_theme_icon(SNAME("OneWayTile"), SNAME("EditorIcons"));
+ Ref<Texture2D> one_way_icon = get_editor_theme_icon(SNAME("OneWayTile"));
for (int i = 0; i < tile_data->get_collision_polygons_count(physics_layer); i++) {
Vector<Vector2> polygon = tile_data->get_collision_polygon_points(physics_layer, i);
if (polygon.size() < 3) {
@@ -1880,8 +1881,8 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
}
// Dim terrains with wrong terrain set.
- Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
for (int i = 0; i < p_tile_set_atlas_source->get_tiles_count(); i++) {
Vector2i coords = p_tile_set_atlas_source->get_tile_id(i);
if (coords != hovered_coords) {
@@ -2070,8 +2071,8 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til
}
// Dim terrains with wrong terrain set.
- Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
- int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
+ Ref<Font> font = TileSetEditor::get_singleton()->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts));
+ int font_size = TileSetEditor::get_singleton()->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts));
for (int i = 0; i < p_tile_set_atlas_source->get_tiles_count(); i++) {
Vector2i coords = p_tile_set_atlas_source->get_tile_id(i);
for (int j = 1; j < p_tile_set_atlas_source->get_alternative_tiles_count(coords); j++) {
@@ -2776,7 +2777,7 @@ void TileDataTerrainsEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
+ picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick")));
} break;
}
}
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index b181835f6f..fa35a03a22 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -175,7 +175,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
// Scene collection source.
TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
if (scene_collection_source) {
- texture = tiles_bottom_panel->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
+ texture = tiles_bottom_panel->get_editor_theme_icon(SNAME("PackedScene"));
if (item_text.is_empty()) {
if (scene_collection_source->get_scene_tiles_count() > 0) {
item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id);
@@ -393,7 +393,7 @@ void TileMapEditorTilesPlugin::_update_scenes_collection_view() {
Variant udata = i;
EditorResourcePreview::get_singleton()->queue_edited_resource_preview(scene, this, "_scene_thumbnail_done", udata);
} else {
- item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), tiles_bottom_panel->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")));
+ item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), tiles_bottom_panel->get_editor_theme_icon(SNAME("PackedScene")));
}
scene_tiles_list->set_item_metadata(item_index, scene_id);
@@ -469,18 +469,18 @@ void TileMapEditorTilesPlugin::_scenes_list_lmb_empty_clicked(const Vector2 &p_p
}
void TileMapEditorTilesPlugin::_update_theme() {
- source_sort_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
- select_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- paint_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- line_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Line"), SNAME("EditorIcons")));
- rect_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Rectangle"), SNAME("EditorIcons")));
- bucket_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons")));
-
- picker_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
- erase_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons")));
- random_tile_toggle->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("RandomNumberGenerator"), SNAME("EditorIcons")));
-
- missing_atlas_texture_icon = tiles_bottom_panel->get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
+ source_sort_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Sort")));
+ select_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ToolSelect")));
+ paint_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Edit")));
+ line_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Line")));
+ rect_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Rectangle")));
+ bucket_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Bucket")));
+
+ picker_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ColorPick")));
+ erase_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Eraser")));
+ random_tile_toggle->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("RandomNumberGenerator")));
+
+ missing_atlas_texture_icon = tiles_bottom_panel->get_editor_theme_icon(SNAME("TileSet"));
_update_tile_set_sources_list();
}
@@ -3226,13 +3226,13 @@ void TileMapEditorTerrainsPlugin::_update_terrains_tree() {
TreeItem *terrain_set_tree_item = terrains_tree->create_item();
String matches;
if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS_AND_SIDES) {
- terrain_set_tree_item->set_icon(0, main_vbox_container->get_theme_icon(SNAME("TerrainMatchCornersAndSides"), SNAME("EditorIcons")));
+ terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchCornersAndSides")));
matches = String(TTR("Matches Corners and Sides"));
} else if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS) {
- terrain_set_tree_item->set_icon(0, main_vbox_container->get_theme_icon(SNAME("TerrainMatchCorners"), SNAME("EditorIcons")));
+ terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchCorners")));
matches = String(TTR("Matches Corners Only"));
} else {
- terrain_set_tree_item->set_icon(0, main_vbox_container->get_theme_icon(SNAME("TerrainMatchSides"), SNAME("EditorIcons")));
+ terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchSides")));
matches = String(TTR("Matches Sides Only"));
}
terrain_set_tree_item->set_text(0, vformat(TTR("Terrain Set %d (%s)"), terrain_set_index, matches));
@@ -3275,13 +3275,13 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() {
ERR_FAIL_INDEX(sel_terrain_id, tile_set->get_terrains_count(sel_terrain_set));
// Add the two first generic modes
- int item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_theme_icon(SNAME("TerrainConnect"), SNAME("EditorIcons")));
+ int item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_editor_theme_icon(SNAME("TerrainConnect")));
terrains_tile_list->set_item_tooltip(item_index, TTR("Connect mode: paints a terrain, then connects it with the surrounding tiles with the same terrain."));
Dictionary list_metadata_dict;
list_metadata_dict["type"] = SELECTED_TYPE_CONNECT;
terrains_tile_list->set_item_metadata(item_index, list_metadata_dict);
- item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_theme_icon(SNAME("TerrainPath"), SNAME("EditorIcons")));
+ item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_editor_theme_icon(SNAME("TerrainPath")));
terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, thens connects it to the previous tile painted within the same stroke."));
list_metadata_dict = Dictionary();
list_metadata_dict["type"] = SELECTED_TYPE_PATH;
@@ -3354,13 +3354,13 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() {
}
void TileMapEditorTerrainsPlugin::_update_theme() {
- paint_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- line_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Line"), SNAME("EditorIcons")));
- rect_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Rectangle"), SNAME("EditorIcons")));
- bucket_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons")));
+ paint_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Edit")));
+ line_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Line")));
+ rect_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Rectangle")));
+ bucket_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Bucket")));
- picker_button->set_icon(main_vbox_container->get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
- erase_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons")));
+ picker_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("ColorPick")));
+ erase_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Eraser")));
_update_tiles_list();
}
@@ -3498,12 +3498,12 @@ void TileMapEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- missing_tile_texture = get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
- warning_pattern_texture = get_theme_icon(SNAME("WarningPattern"), SNAME("EditorIcons"));
- advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
- toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons")));
+ missing_tile_texture = get_editor_theme_icon(SNAME("StatusWarning"));
+ warning_pattern_texture = get_editor_theme_icon(SNAME("WarningPattern"));
+ advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("Tools")));
+ toggle_grid_button->set_icon(get_editor_theme_icon(SNAME("Grid")));
toggle_grid_button->set_pressed(EDITOR_GET("editors/tiles_editor/display_grid"));
- toggle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons")));
+ toggle_highlight_selected_layer_button->set_icon(get_editor_theme_icon(SNAME("TileMapHighlightSelected")));
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index a9a1cd76a3..a2e4c4a784 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_toaster.h"
#include "editor/plugins/tiles/tile_set_editor.h"
@@ -649,7 +650,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
tile_data_editors_tree->add_theme_constant_override("v_separation", 1);
tile_data_editors_tree->add_theme_constant_override("h_separation", 3);
- Color group_color = get_theme_color(SNAME("prop_category"), SNAME("Editor"));
+ Color group_color = get_theme_color(SNAME("prop_category"), EditorStringName(Editor));
// List of editors.
// --- Rendering ---
@@ -732,7 +733,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
tile_data_editors["probability"] = tile_data_probability_editor;
}
- Color disabled_color = get_theme_color("disabled_font_color", "Editor");
+ Color disabled_color = get_theme_color("disabled_font_color", EditorStringName(Editor));
// --- Physics ---
ADD_TILE_DATA_EDITOR_GROUP(TTR("Physics"));
@@ -754,7 +755,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
if (tile_set->get_physics_layers_count() == 0) {
item = tile_data_editors_tree->create_item(group);
- item->set_icon(0, get_theme_icon("Info", "EditorIcons"));
+ item->set_icon(0, get_editor_theme_icon("Info"));
item->set_icon_modulate(0, disabled_color);
item->set_text(0, TTR("No physics layers"));
item->set_tooltip_text(0, TTR("Create and customize physics layers in the inspector of the TileSet resource."));
@@ -782,7 +783,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
if (tile_set->get_navigation_layers_count() == 0) {
item = tile_data_editors_tree->create_item(group);
- item->set_icon(0, get_theme_icon("Info", "EditorIcons"));
+ item->set_icon(0, get_editor_theme_icon("Info"));
item->set_icon_modulate(0, disabled_color);
item->set_text(0, TTR("No navigation layers"));
item->set_tooltip_text(0, TTR("Create and customize navigation layers in the inspector of the TileSet resource."));
@@ -825,7 +826,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
if (tile_set->get_custom_data_layers_count() == 0) {
item = tile_data_editors_tree->create_item(group);
- item->set_icon(0, get_theme_icon("Info", "EditorIcons"));
+ item->set_icon(0, get_editor_theme_icon("Info"));
item->set_icon_modulate(0, disabled_color);
item->set_text(0, TTR("No custom data layers"));
item->set_tooltip_text(0, TTR("Create and customize custom data layers in the inspector of the TileSet resource."));
@@ -992,7 +993,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() {
// Create and position the button.
Button *button = memnew(Button);
button->set_flat(true);
- button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button->set_icon(get_editor_theme_icon(SNAME("Add")));
button->add_theme_style_override("normal", memnew(StyleBoxEmpty));
button->add_theme_style_override("hover", memnew(StyleBoxEmpty));
button->add_theme_style_override("focus", memnew(StyleBoxEmpty));
@@ -2403,16 +2404,16 @@ void TileSetAtlasSourceEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- tool_setup_atlas_source_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
- tool_select_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_paint_button->set_icon(get_theme_icon(SNAME("CanvasItem"), SNAME("EditorIcons")));
+ tool_setup_atlas_source_button->set_icon(get_editor_theme_icon(SNAME("Tools")));
+ tool_select_button->set_icon(get_editor_theme_icon(SNAME("ToolSelect")));
+ tool_paint_button->set_icon(get_editor_theme_icon(SNAME("CanvasItem")));
- tools_settings_erase_button->set_icon(get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons")));
- tool_advanced_menu_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- outside_tiles_warning->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ tools_settings_erase_button->set_icon(get_editor_theme_icon(SNAME("Eraser")));
+ tool_advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ outside_tiles_warning->set_texture(get_editor_theme_icon(SNAME("StatusWarning")));
- resize_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
- resize_handle_disabled = get_theme_icon(SNAME("EditorHandleDisabled"), SNAME("EditorIcons"));
+ resize_handle = get_editor_theme_icon(SNAME("EditorHandle"));
+ resize_handle_disabled = get_editor_theme_icon(SNAME("EditorHandleDisabled"));
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp
index 3a21bff947..53cc59b718 100644
--- a/editor/plugins/tiles/tile_set_editor.cpp
+++ b/editor/plugins/tiles/tile_set_editor.cpp
@@ -190,7 +190,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
// Scene collection source.
TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
if (scene_collection_source) {
- texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
+ texture = get_editor_theme_icon(SNAME("PackedScene"));
if (item_text.is_empty()) {
if (scene_collection_source->get_scene_tiles_count() > 0) {
item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id);
@@ -364,11 +364,11 @@ void TileSetEditor::_set_source_sort(int p_sort) {
void TileSetEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- sources_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- sources_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- source_sort_button->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
- sources_advanced_menu_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- missing_texture_texture = get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
+ sources_delete_button->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ sources_add_button->set_icon(get_editor_theme_icon(SNAME("Add")));
+ source_sort_button->set_icon(get_editor_theme_icon(SNAME("Sort")));
+ sources_advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ missing_texture_texture = get_editor_theme_icon(SNAME("TileSet"));
expanded_area->add_theme_style_override("panel", get_theme_stylebox("panel", "Tree"));
_update_sources_list();
} break;
diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
index e357e262c2..6b9250010e 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
@@ -332,7 +332,7 @@ void TileSetScenesCollectionSourceEditor::_update_scenes_list() {
Variant udata = i;
EditorResourcePreview::get_singleton()->queue_edited_resource_preview(scene, this, "_scene_thumbnail_done", udata);
} else {
- item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")));
+ item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), get_editor_theme_icon(SNAME("PackedScene")));
}
scene_tiles_list->set_item_metadata(item_index, scene_id);
@@ -358,8 +358,8 @@ void TileSetScenesCollectionSourceEditor::_update_scenes_list() {
void TileSetScenesCollectionSourceEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- scene_tile_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- scene_tile_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ scene_tile_add_button->set_icon(get_editor_theme_icon(SNAME("Add")));
+ scene_tile_delete_button->set_icon(get_editor_theme_icon(SNAME("Remove")));
_update_scenes_list();
} break;
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 7c1cf52925..904348d3bf 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -292,7 +292,7 @@ void TilesEditorUtils::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect
real_t scale = p_ci->get_global_transform().get_scale().x * 0.5;
p_ci->draw_set_transform(p_rect.position, 0, Vector2(1, 1) / scale);
RS::get_singleton()->canvas_item_add_nine_patch(
- p_ci->get_canvas_item(), Rect2(Vector2(), p_rect.size * scale), Rect2(), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("TileSelection"), SNAME("EditorIcons"))->get_rid(),
+ p_ci->get_canvas_item(), Rect2(Vector2(), p_rect.size * scale), Rect2(), EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("TileSelection"))->get_rid(),
Vector2(2, 2), Vector2(2, 2), RS::NINE_PATCH_STRETCH, RS::NINE_PATCH_STRETCH, false, p_color);
p_ci->draw_set_transform_matrix(Transform2D());
}
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index a4ff9143f2..a6c98e646e 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/filesystem_dock.h"
#include "editor/plugins/script_editor_plugin.h"
#include "scene/gui/separator.h"
@@ -173,7 +174,7 @@ void VersionControlEditorPlugin::_update_set_up_warning(String p_new_text) {
set_up_ssh_passphrase->get_text().is_empty();
if (empty_settings) {
- set_up_warning_text->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ set_up_warning_text->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
set_up_warning_text->set_text(TTR("Remote settings are empty. VCS features that use the network may not work."));
} else {
set_up_warning_text->set_text("");
@@ -191,7 +192,7 @@ void VersionControlEditorPlugin::_refresh_branch_list() {
String current_branch = EditorVCSInterface::get_singleton()->get_current_branch_name();
for (int i = 0; i < branch_list.size(); i++) {
- branch_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("VcsBranches"), SNAME("EditorIcons")), branch_list[i], i);
+ branch_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("VcsBranches")), branch_list[i], i);
if (branch_list[i] == current_branch) {
branch_select->select(i);
@@ -251,7 +252,7 @@ void VersionControlEditorPlugin::_refresh_remote_list() {
remote_select->set_disabled(remotes.is_empty());
for (int i = 0; i < remotes.size(); i++) {
- remote_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons")), remotes[i], i);
+ remote_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ArrowUp")), remotes[i], i);
remote_select->set_item_metadata(i, remotes[i]);
if (remotes[i] == current_remote) {
@@ -421,9 +422,9 @@ void VersionControlEditorPlugin::_add_new_item(Tree *p_tree, String p_file_path,
new_item->set_meta(SNAME("change_type"), p_change);
new_item->set_custom_color(0, change_type_to_color[p_change]);
- new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("File"), SNAME("EditorIcons")), BUTTON_TYPE_OPEN, false, TTR("Open in editor"));
+ new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("File")), BUTTON_TYPE_OPEN, false, TTR("Open in editor"));
if (p_tree == unstaged_files) {
- new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), BUTTON_TYPE_DISCARD, false, TTR("Discard changes"));
+ new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Close")), BUTTON_TYPE_DISCARD, false, TTR("Discard changes"));
}
}
@@ -569,8 +570,8 @@ void VersionControlEditorPlugin::_display_diff(int p_idx) {
String commit_author = meta_data[SNAME("commit_author")];
String commit_date_string = meta_data[SNAME("commit_date_string")];
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")));
- diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
+ diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
diff->add_text(TTR("Commit:") + " " + commit_id);
diff->add_newline();
diff->add_text(TTR("Author:") + " " + commit_author);
@@ -589,13 +590,13 @@ void VersionControlEditorPlugin::_display_diff(int p_idx) {
for (int i = 0; i < diff_content.size(); i++) {
EditorVCSInterface::DiffFile diff_file = diff_content[i];
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")));
- diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
+ diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
diff->add_text(TTR("File:") + " " + diff_file.new_file);
diff->pop();
diff->pop();
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
for (int j = 0; j < diff_file.diff_hunks.size(); j++) {
EditorVCSInterface::DiffHunk hunk = diff_file.diff_hunks[j];
@@ -678,8 +679,8 @@ void VersionControlEditorPlugin::_display_diff_split_view(List<EditorVCSInterfac
EditorVCSInterface::DiffLine diff_line = parsed_diff[i];
bool has_change = diff_line.status != " ";
- static const Color red = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"));
- static const Color green = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"));
+ static const Color red = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ static const Color green = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
static const Color white = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.6);
if (diff_line.old_line_no >= 0) {
@@ -760,9 +761,9 @@ void VersionControlEditorPlugin::_display_diff_unified_view(List<EditorVCSInterf
Color color;
if (diff_line.status == "+") {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"));
+ color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
} else if (diff_line.status == "-") {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
} else {
color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label"));
color *= Color(1, 1, 1, 0.6);
@@ -855,13 +856,13 @@ void VersionControlEditorPlugin::_popup_remote_remove_confirm(int p_index) {
void VersionControlEditorPlugin::_update_extra_options() {
extra_options_remove_branch_list->clear();
for (int i = 0; i < branch_select->get_item_count(); i++) {
- extra_options_remove_branch_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("VcsBranches"), SNAME("EditorIcons")), branch_select->get_item_text(branch_select->get_item_id(i)));
+ extra_options_remove_branch_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("VcsBranches")), branch_select->get_item_text(branch_select->get_item_id(i)));
}
extra_options_remove_branch_list->update_canvas_items();
extra_options_remove_remote_list->clear();
for (int i = 0; i < remote_select->get_item_count(); i++) {
- extra_options_remove_remote_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons")), remote_select->get_item_text(remote_select->get_item_id(i)));
+ extra_options_remove_remote_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ArrowUp")), remote_select->get_item_text(remote_select->get_item_id(i)));
}
extra_options_remove_remote_list->update_canvas_items();
}
@@ -1082,7 +1083,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
set_up_ssh_public_key_input_hbc->add_child(set_up_ssh_public_key_file_dialog);
Button *select_public_path_button = memnew(Button);
- select_public_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Folder", "EditorIcons"));
+ select_public_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder"));
select_public_path_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_popup_file_dialog).bind(set_up_ssh_public_key_file_dialog));
select_public_path_button->set_tooltip_text(TTR("Select SSH public key path"));
set_up_ssh_public_key_input_hbc->add_child(select_public_path_button);
@@ -1115,7 +1116,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
set_up_ssh_private_key_input_hbc->add_child(set_up_ssh_private_key_file_dialog);
Button *select_private_path_button = memnew(Button);
- select_private_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Folder", "EditorIcons"));
+ select_private_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder"));
select_private_path_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_popup_file_dialog).bind(set_up_ssh_private_key_file_dialog));
select_private_path_button->set_tooltip_text(TTR("Select SSH private key path"));
set_up_ssh_private_key_input_hbc->add_child(select_private_path_button);
@@ -1160,7 +1161,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
refresh_button = memnew(Button);
refresh_button->set_tooltip_text(TTR("Detect new changes"));
refresh_button->set_flat(true);
- refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Reload")));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_commit_list));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_branch_list));
@@ -1180,14 +1181,14 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
discard_all_button = memnew(Button);
discard_all_button->set_tooltip_text(TTR("Discard all changes"));
- discard_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ discard_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Close")));
discard_all_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_confirm_discard_all));
discard_all_button->set_flat(true);
unstage_title->add_child(discard_all_button);
stage_all_button = memnew(Button);
stage_all_button->set_flat(true);
- stage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
+ stage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveDown")));
stage_all_button->set_tooltip_text(TTR("Stage all changes"));
unstage_title->add_child(stage_all_button);
@@ -1217,7 +1218,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
unstage_all_button = memnew(Button);
unstage_all_button->set_flat(true);
- unstage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
+ unstage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveUp")));
unstage_all_button->set_tooltip_text(TTR("Unstage all changes"));
stage_title->add_child(unstage_all_button);
@@ -1412,26 +1413,26 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
fetch_button = memnew(Button);
fetch_button->set_flat(true);
fetch_button->set_tooltip_text(TTR("Fetch"));
- fetch_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ fetch_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Reload")));
fetch_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_fetch));
menu_bar->add_child(fetch_button);
pull_button = memnew(Button);
pull_button->set_flat(true);
pull_button->set_tooltip_text(TTR("Pull"));
- pull_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")));
+ pull_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveDown")));
pull_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_pull));
menu_bar->add_child(pull_button);
push_button = memnew(Button);
push_button->set_flat(true);
push_button->set_tooltip_text(TTR("Push"));
- push_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")));
+ push_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveUp")));
push_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_push));
menu_bar->add_child(push_button);
extra_options = memnew(MenuButton);
- extra_options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ extra_options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("GuiTabMenuHl")));
extra_options->get_popup()->connect(SNAME("about_to_popup"), callable_mp(this, &VersionControlEditorPlugin::_update_extra_options));
extra_options->get_popup()->connect(SNAME("id_pressed"), callable_mp(this, &VersionControlEditorPlugin::_extra_option_selected));
menu_bar->add_child(extra_options);
@@ -1462,19 +1463,19 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = TTR("Typechange");
change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = TTR("Unmerged");
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Editor"));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
-
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusSuccess"));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusError"));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
version_control_dock = memnew(VBoxContainer);
version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 330a9a36eb..8e1862d88b 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_properties_vector.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/inspector_dock.h"
@@ -143,22 +144,26 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p
bool is_dirty = link.preview_pos < 0;
if (!is_dirty && link.preview_visible && link.preview_box != nullptr) {
- link.graph_node->remove_child(link.preview_box);
+ link.graph_element->remove_child(link.preview_box);
memdelete(link.preview_box);
link.preview_box = nullptr;
- link.graph_node->reset_size();
+ link.graph_element->reset_size();
link.preview_visible = false;
}
if (p_port_id != -1 && link.output_ports[p_port_id].preview_button != nullptr) {
if (is_dirty) {
- link.preview_pos = link.graph_node->get_child_count();
+ link.preview_pos = link.graph_element->get_child_count();
}
VBoxContainer *vbox = memnew(VBoxContainer);
- link.graph_node->add_child(vbox);
- link.graph_node->move_child(vbox, link.preview_pos);
- link.graph_node->set_slot_draw_stylebox(vbox->get_index(), false);
+ link.graph_element->add_child(vbox);
+ link.graph_element->move_child(vbox, link.preview_pos);
+
+ GraphNode *graph_node = Object::cast_to<GraphNode>(link.graph_element);
+ if (graph_node) {
+ graph_node->set_slot_draw_stylebox(vbox->get_index(false), false);
+ }
Control *offset = memnew(Control);
offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
@@ -292,7 +297,7 @@ void VisualShaderGraphPlugin::update_node_size(int p_node_id) {
if (!links.has(p_node_id)) {
return;
}
- links[p_node_id].graph_node->reset_size();
+ links[p_node_id].graph_element->reset_size();
}
void VisualShaderGraphPlugin::register_default_input_button(int p_node_id, int p_port_id, Button *p_button) {
@@ -323,7 +328,7 @@ VisualShader::Type VisualShaderGraphPlugin::get_shader_type() const {
void VisualShaderGraphPlugin::set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position) {
if (visual_shader->get_shader_type() == p_type && links.has(p_id)) {
- links[p_id].graph_node->set_position_offset(p_position);
+ links[p_id].graph_element->set_position_offset(p_position);
}
}
@@ -335,8 +340,8 @@ void VisualShaderGraphPlugin::clear_links() {
links.clear();
}
-void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) {
- links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, HashMap<int, InputPort>(), HashMap<int, Port>(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } });
+void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphElement *p_graph_element) {
+ links.insert(p_id, { p_type, p_visual_node, p_graph_element, p_visual_node->get_output_port_for_preview() != -1, -1, HashMap<int, InputPort>(), HashMap<int, Port>(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } });
}
void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) {
@@ -348,10 +353,10 @@ void VisualShaderGraphPlugin::register_parameter_name(int p_node_id, LineEdit *p
}
void VisualShaderGraphPlugin::update_theme() {
- vector_expanded_color[0] = editor->get_theme_color(SNAME("axis_x_color"), SNAME("Editor")); // red
- vector_expanded_color[1] = editor->get_theme_color(SNAME("axis_y_color"), SNAME("Editor")); // green
- vector_expanded_color[2] = editor->get_theme_color(SNAME("axis_z_color"), SNAME("Editor")); // blue
- vector_expanded_color[3] = editor->get_theme_color(SNAME("axis_w_color"), SNAME("Editor")); // alpha
+ vector_expanded_color[0] = editor->get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)); // red
+ vector_expanded_color[1] = editor->get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)); // green
+ vector_expanded_color[2] = editor->get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor)); // blue
+ vector_expanded_color[3] = editor->get_theme_color(SNAME("axis_w_color"), EditorStringName(Editor)); // alpha
}
bool VisualShaderGraphPlugin::is_node_has_parameter_instances_relatively(VisualShader::Type p_type, int p_node) const {
@@ -414,42 +419,49 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
// Visual shader specific theme for MSDF font.
Ref<Theme> vstheme;
vstheme.instantiate();
- Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", "EditorFonts");
+ Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorIcons));
+ Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorIcons));
vstheme->set_font("font", "Label", label_font);
+ vstheme->set_font("font", "GraphNodeTitleLabel", label_bold_font);
vstheme->set_font("font", "LineEdit", label_font);
vstheme->set_font("font", "Button", label_font);
Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id);
- Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(vsnode.ptr());
- bool is_resizable = !resizable_node.is_null();
+ Ref<VisualShaderNodeResizableBase> resizable_node = vsnode;
+ bool is_resizable = resizable_node.is_valid();
Size2 size = Size2(0, 0);
- Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr());
- bool is_group = !group_node.is_null();
+ Ref<VisualShaderNodeGroupBase> group_node = vsnode;
+ bool is_group = group_node.is_valid();
- Ref<VisualShaderNodeComment> comment_node = Object::cast_to<VisualShaderNodeComment>(vsnode.ptr());
+ Ref<VisualShaderNodeComment> comment_node = vsnode;
bool is_comment = comment_node.is_valid();
- Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr());
- bool is_expression = !expression_node.is_null();
+ Ref<VisualShaderNodeExpression> expression_node = group_node;
+ bool is_expression = expression_node.is_valid();
String expression = "";
- VisualShaderNodeCustom *custom_node = Object::cast_to<VisualShaderNodeCustom>(vsnode.ptr());
- if (custom_node) {
+ Ref<VisualShaderNodeCustom> custom_node = vsnode;
+ if (custom_node.is_valid()) {
custom_node->_set_initialized(true);
}
- // Create graph node.
GraphNode *node = memnew(GraphNode);
+ node->set_title(vsnode->get_caption());
+
+ // All nodes are closable except the output node.
+ if (p_id >= 2) {
+ vsnode->set_closable(true);
+ node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_close_node_request).bind(p_type, p_id), CONNECT_DEFERRED);
+ }
graph->add_child(node);
node->set_theme(vstheme);
- editor->_update_created_node(node);
if (p_just_update) {
Link &link = links[p_id];
- link.graph_node = node;
+ link.graph_element = node;
link.preview_box = nullptr;
link.preview_pos = -1;
link.output_ports.clear();
@@ -473,19 +485,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
}
node->set_position_offset(visual_shader->get_node_position(p_type, p_id));
- node->set_title(vsnode->get_caption());
- node->set_name(itos(p_id));
- if (p_id >= 2) {
- node->set_show_close_button(true);
- node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_delete_node_request).bind(p_type, p_id), CONNECT_DEFERRED);
- }
+ node->set_name(itos(p_id));
node->connect("dragged", callable_mp(editor, &VisualShaderEditor::_node_dragged).bind(p_id));
Control *custom_editor = nullptr;
int port_offset = 1;
+ if (is_resizable) {
+ editor->call_deferred(SNAME("_set_node_size"), (int)p_type, p_id, size);
+ }
+
Control *content_offset = memnew(Control);
content_offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
node->add_child(content_offset);
@@ -494,10 +505,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
port_offset += 1;
}
- if (is_resizable) {
- editor->call_deferred(SNAME("_set_node_size"), (int)p_type, p_id, size);
- }
-
Ref<VisualShaderNodeParticleEmit> emit = vsnode;
if (emit.is_valid()) {
node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
@@ -607,7 +614,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (custom_editor) {
if (is_curve || (hb == nullptr && !vsnode->is_use_prop_slots() && (vsnode->get_output_port_count() == 0 || vsnode->get_output_port_name(0) == "") && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == ""))) {
- //will be embedded in first port
+ // Will be embedded in first port.
} else {
port_offset++;
node->add_child(custom_editor);
@@ -789,7 +796,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out).bind(name_box, p_id, i, false), CONNECT_DEFERRED);
Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Remove")));
remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left);
remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_input_port).bind(p_id, i), CONNECT_DEFERRED);
hb->add_child(remove_btn);
@@ -816,7 +823,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (valid_right) {
if (is_group) {
Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Remove")));
remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left);
remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_output_port).bind(p_id, i), CONNECT_DEFERRED);
hb->add_child(remove_btn);
@@ -855,8 +862,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (vsnode->is_output_port_expandable(i)) {
TextureButton *expand = memnew(TextureButton);
expand->set_toggle_mode(true);
- expand->set_texture_normal(editor->get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")));
- expand->set_texture_pressed(editor->get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")));
+ expand->set_texture_normal(editor->get_editor_theme_icon(SNAME("GuiTreeArrowDown")));
+ expand->set_texture_pressed(editor->get_editor_theme_icon(SNAME("GuiTreeArrowRight")));
expand->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
expand->set_pressed(vsnode->_is_output_port_expanded(i));
expand->connect("pressed", callable_mp(editor, &VisualShaderEditor::_expand_output_port).bind(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED);
@@ -865,8 +872,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (vsnode->has_output_port_preview(i) && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) {
TextureButton *preview = memnew(TextureButton);
preview->set_toggle_mode(true);
- preview->set_texture_normal(editor->get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")));
- preview->set_texture_pressed(editor->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")));
+ preview->set_texture_normal(editor->get_editor_theme_icon(SNAME("GuiVisibilityHidden")));
+ preview->set_texture_pressed(editor->get_editor_theme_icon(SNAME("GuiVisibilityVisible")));
preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
register_output_port(p_id, j, preview);
@@ -895,93 +902,97 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (!is_first_hbox) {
idx = i + port_offset;
}
- node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
+ if (!is_comment) {
+ GraphNode *graph_node = Object::cast_to<GraphNode>(node);
- if (vsnode->_is_output_port_expanded(i)) {
- switch (vsnode->get_output_port_type(i)) {
- case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
- port_offset++;
- valid_left = (i + 1) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 1);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
- port_offset++;
+ graph_node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
- valid_left = (i + 2) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 2);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
-
- expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D;
- } break;
- case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
- port_offset++;
- valid_left = (i + 1) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 1);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
- port_offset++;
+ if (vsnode->_is_output_port_expanded(i)) {
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
- valid_left = (i + 2) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 2);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
- port_offset++;
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
- valid_left = (i + 3) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 3);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+ port_offset++;
- expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D;
- } break;
- case VisualShaderNode::PORT_TYPE_VECTOR_4D: {
- port_offset++;
- valid_left = (i + 1) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 1);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
- port_offset++;
+ valid_left = (i + 3) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 3);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
+
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_4D: {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
- valid_left = (i + 2) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 2);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
- port_offset++;
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+ port_offset++;
- valid_left = (i + 3) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 3);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
- port_offset++;
+ valid_left = (i + 3) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 3);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
+ port_offset++;
- valid_left = (i + 4) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 4);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[3]);
+ valid_left = (i + 4) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 4);
+ }
+ graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[3]);
- expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_4D;
- } break;
- default:
- break;
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_4D;
+ } break;
+ default:
+ break;
+ }
}
}
}
@@ -1002,8 +1013,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
}
if (!error.is_empty()) {
Label *error_label = memnew(Label);
- error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
error_label->set_text(error);
+ error_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);
node->add_child(error_label);
}
@@ -1036,8 +1048,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
}
}
- expression_box->add_theme_font_override("font", editor->get_theme_font(SNAME("expression"), SNAME("EditorFonts")));
- expression_box->add_theme_font_size_override("font_size", editor->get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")));
+ expression_box->add_theme_font_override("font", editor->get_theme_font(SNAME("expression"), EditorStringName(EditorFonts)));
+ expression_box->add_theme_font_size_override("font_size", editor->get_theme_font_size(SNAME("expression_size"), EditorStringName(EditorFonts)));
expression_box->add_theme_color_override("font_color", text_color);
expression_syntax_highlighter->set_number_color(number_color);
expression_syntax_highlighter->set_symbol_color(symbol_color);
@@ -1060,16 +1072,13 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
expression_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_expression_focus_out).bind(expression_box, p_id));
}
-
- if (is_comment) {
- graph->move_child(node, 0); // to prevents a bug where comment node overlaps its content
- }
}
void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id, bool p_just_update) {
if (visual_shader->get_shader_type() == p_type && links.has(p_id)) {
- links[p_id].graph_node->get_parent()->remove_child(links[p_id].graph_node);
- memdelete(links[p_id].graph_node);
+ Node *graph_edit_node = links[p_id].graph_element->get_parent();
+ graph_edit_node->remove_child(links[p_id].graph_element);
+ memdelete(links[p_id].graph_element);
if (!p_just_update) {
links.erase(p_id);
}
@@ -1373,7 +1382,7 @@ void VisualShaderEditor::_update_custom_script(const Ref<Script> &p_script) {
if (vsnode.is_null()) {
continue;
}
- Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr());
+ Ref<VisualShaderNodeCustom> custom_node = vsnode;
if (custom_node.is_null() || custom_node->get_script() != p_script) {
continue;
}
@@ -1485,7 +1494,7 @@ void VisualShaderEditor::_resources_removed() {
if (vsnode.is_null()) {
continue;
}
- Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr());
+ Ref<VisualShaderNodeCustom> custom_node = vsnode;
if (custom_node.is_null() || custom_node->get_script() != scr) {
continue;
}
@@ -1677,8 +1686,8 @@ void VisualShaderEditor::_update_options_menu() {
bool is_first_item = true;
- Color unsupported_color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
- Color supported_color = get_theme_color(SNAME("warning_color"), SNAME("Editor"));
+ Color unsupported_color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ Color supported_color = get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
static bool low_driver = GLOBAL_GET("rendering/renderer/rendering_method") == "gl_compatibility";
@@ -1833,31 +1842,31 @@ void VisualShaderEditor::_update_options_menu() {
}
switch (options[i].return_type) {
case VisualShaderNode::PORT_TYPE_SCALAR:
- item->set_icon(0, get_theme_icon(SNAME("float"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("float")));
break;
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
- item->set_icon(0, get_theme_icon(SNAME("int"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("int")));
break;
case VisualShaderNode::PORT_TYPE_SCALAR_UINT:
- item->set_icon(0, get_theme_icon(SNAME("uint"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("uint")));
break;
case VisualShaderNode::PORT_TYPE_VECTOR_2D:
- item->set_icon(0, get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Vector2")));
break;
case VisualShaderNode::PORT_TYPE_VECTOR_3D:
- item->set_icon(0, get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Vector3")));
break;
case VisualShaderNode::PORT_TYPE_VECTOR_4D:
- item->set_icon(0, get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Vector4")));
break;
case VisualShaderNode::PORT_TYPE_BOOLEAN:
- item->set_icon(0, get_theme_icon(SNAME("bool"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("bool")));
break;
case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("Transform3D")));
break;
case VisualShaderNode::PORT_TYPE_SAMPLER:
- item->set_icon(0, get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")));
+ item->set_icon(0, get_editor_theme_icon(SNAME("ImageTexture")));
break;
default:
break;
@@ -1915,8 +1924,8 @@ Size2 VisualShaderEditor::get_minimum_size() const {
return Size2(10, 200);
}
-void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) {
- Button *button = Object::cast_to<Button>(obj);
+void VisualShaderEditor::_draw_color_over_button(Object *p_obj, Color p_color) {
+ Button *button = Object::cast_to<Button>(p_obj);
if (!button) {
return;
}
@@ -1925,18 +1934,6 @@ void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) {
button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color);
}
-void VisualShaderEditor::_update_created_node(GraphNode *node) {
- const Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("frame"), SNAME("GraphNode"));
- Color c = sb->get_border_color();
- const Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85);
- c = mono_color;
-
- node->add_theme_color_override("title_color", c);
- c.a = 0.7;
- node->add_theme_color_override("close_color", c);
- node->add_theme_color_override("resizer_color", c);
-}
-
void VisualShaderEditor::_update_parameters(bool p_update_refs) {
VisualShaderNodeParameterRef::clear_parameters(visual_shader->get_rid());
@@ -2024,9 +2021,9 @@ void VisualShaderEditor::_update_graph() {
VisualShader::Type type = get_current_shader_type();
graph->clear_connections();
- //erase all nodes
+ // Remove all nodes.
for (int i = 0; i < graph->get_child_count(); i++) {
- if (Object::cast_to<GraphNode>(graph->get_child(i))) {
+ if (Object::cast_to<GraphElement>(graph->get_child(i))) {
Node *node = graph->get_child(i);
graph->remove_child(node);
memdelete(node);
@@ -2405,14 +2402,14 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
undo_redo->commit_action();
}
-void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) {
+void VisualShaderEditor::_expression_focus_out(Object *p_code_edit, int p_node) {
VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
}
- CodeEdit *expression_box = Object::cast_to<CodeEdit>(code_edit);
+ CodeEdit *expression_box = Object::cast_to<CodeEdit>(p_code_edit);
if (node->get_expression() == expression_box->get_text()) {
return;
@@ -2451,20 +2448,20 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p
}
}
- GraphNode *gn = nullptr;
+ GraphElement *graph_element = nullptr;
Node *node2 = graph->get_node(itos(p_node));
- gn = Object::cast_to<GraphNode>(node2);
- if (!gn) {
+ graph_element = Object::cast_to<GraphElement>(node2);
+ if (!graph_element) {
return;
}
- gn->set_custom_minimum_size(size);
- gn->reset_size();
+ graph_element->set_custom_minimum_size(size);
+ graph_element->reset_size();
if (!expression_node.is_null() && text_box) {
Size2 box_size = size;
if (box_size.x < 150 * EDSCALE || box_size.y < 0) {
- box_size.x = gn->get_size().x;
+ box_size.x = graph_element->get_size().x;
}
box_size.x -= text_box->get_offset(SIDE_LEFT);
box_size.x -= 28 * EDSCALE;
@@ -2482,9 +2479,14 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
return;
}
+ Vector2 new_size = p_new_size;
+ if (graph->is_snapping_enabled() ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ new_size = new_size.snapped(Vector2(graph->get_snapping_distance(), graph->get_snapping_distance()));
+ }
+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Resize VisualShader Node"), UndoRedo::MERGE_ENDS);
- undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size);
+ undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, new_size);
undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size());
undo_redo->commit_action();
}
@@ -2546,7 +2548,7 @@ void VisualShaderEditor::_comment_title_popup_hide() {
return; // nothing changed - ignored
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(TTR("Set Comment Node Title"));
+ undo_redo->create_action(TTR("Set Comment Title"));
undo_redo->add_do_method(node.ptr(), "set_title", comment_title_change_edit->get_text());
undo_redo->add_undo_method(node.ptr(), "set_title", node->get_title());
undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
@@ -2589,7 +2591,7 @@ void VisualShaderEditor::_comment_desc_popup_hide() {
return; // nothing changed - ignored
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(TTR("Set Comment Node Description"));
+ undo_redo->create_action(TTR("Set Comment Description"));
undo_redo->add_do_method(node.ptr(), "set_description", comment_desc_change_edit->get_text());
undo_redo->add_undo_method(node.ptr(), "set_description", node->get_title());
undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
@@ -3543,12 +3545,12 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) {
}
}
- // delete nodes from the graph
+ // Delete nodes from the graph.
for (const int &F : p_nodes) {
undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F, false);
}
- // update parameter refs if any parameter has been deleted
+ // Update parameter refs if any parameter has been deleted.
if (parameter_names.size() > 0) {
undo_redo->add_do_method(this, "_update_parameters", true);
undo_redo->add_undo_method(this, "_update_parameters", true);
@@ -3788,7 +3790,12 @@ void VisualShaderEditor::_convert_constants_to_parameters(bool p_vice_versa) {
undo_redo->commit_action();
}
-void VisualShaderEditor::_delete_node_request(int p_type, int p_node) {
+void VisualShaderEditor::_close_node_request(int p_type, int p_node) {
+ Ref<VisualShaderNode> node = visual_shader->get_node((VisualShader::Type)p_type, p_node);
+ if (!node->is_closable()) {
+ return;
+ }
+
List<int> to_erase;
to_erase.push_back(p_node);
@@ -3798,22 +3805,30 @@ void VisualShaderEditor::_delete_node_request(int p_type, int p_node) {
undo_redo->commit_action();
}
-void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_nodes) {
+void VisualShaderEditor::_close_nodes_request(const TypedArray<StringName> &p_nodes) {
List<int> to_erase;
if (p_nodes.is_empty()) {
// Called from context menu.
for (int i = 0; i < graph->get_child_count(); i++) {
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- if (gn->is_selected() && gn->is_close_button_visible()) {
- to_erase.push_back(gn->get_name().operator String().to_int());
+ GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i));
+ if (graph_element && graph_element->is_selected()) {
+ VisualShader::Type type = get_current_shader_type();
+ int id = String(graph_element->get_name()).to_int();
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id);
+ if (vsnode->is_closable()) {
+ to_erase.push_back(graph_element->get_name().operator String().to_int());
}
}
}
} else {
+ VisualShader::Type type = get_current_shader_type();
for (int i = 0; i < p_nodes.size(); i++) {
- to_erase.push_back(p_nodes[i].operator String().to_int());
+ int id = p_nodes[i].operator String().to_int();
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id);
+ if (vsnode->is_closable()) {
+ to_erase.push_back(id);
+ }
}
}
@@ -3830,59 +3845,62 @@ void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_n
void VisualShaderEditor::_node_selected(Object *p_node) {
VisualShader::Type type = get_current_shader_type();
- GraphNode *gn = Object::cast_to<GraphNode>(p_node);
- ERR_FAIL_COND(!gn);
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_COND(!graph_element);
- int id = String(gn->get_name()).to_int();
+ int id = String(graph_element->get_name()).to_int();
Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id);
ERR_FAIL_COND(!vsnode.is_valid());
-
- //do not rely on this, makes editor more complex
- //EditorNode::get_singleton()->push_item(vsnode.ptr(), "", true);
}
void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
VisualShader::Type type = get_current_shader_type();
+ Ref<VisualShaderNode> selected_vsnode;
+ // Right click actions.
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) {
selected_constants.clear();
selected_parameters.clear();
selected_comment = -1;
selected_float_constant = -1;
- List<int> to_change;
+ List<int> selected_closable_graph_elements;
for (int i = 0; i < graph->get_child_count(); i++) {
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- if (gn->is_selected() && gn->is_close_button_visible()) {
- int id = gn->get_name().operator String().to_int();
- to_change.push_back(id);
+ GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i));
+ if (graph_element && graph_element->is_selected()) {
+ int id = String(graph_element->get_name()).to_int();
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id);
+ if (!vsnode->is_closable()) {
+ continue;
+ }
- Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
+ selected_closable_graph_elements.push_back(id);
- VisualShaderNodeComment *comment_node = Object::cast_to<VisualShaderNodeComment>(node.ptr());
- if (comment_node != nullptr) {
- selected_comment = id;
- }
- VisualShaderNodeConstant *constant_node = Object::cast_to<VisualShaderNodeConstant>(node.ptr());
- if (constant_node != nullptr) {
- selected_constants.insert(id);
- }
- VisualShaderNodeFloatConstant *float_constant_node = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr());
- if (float_constant_node != nullptr) {
- selected_float_constant = id;
- }
- VisualShaderNodeParameter *parameter_node = Object::cast_to<VisualShaderNodeParameter>(node.ptr());
- if (parameter_node != nullptr && parameter_node->is_convertible_to_constant()) {
- selected_parameters.insert(id);
- }
+ Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
+ selected_vsnode = node;
+
+ VisualShaderNodeComment *frame_node = Object::cast_to<VisualShaderNodeComment>(node.ptr());
+ if (frame_node != nullptr) {
+ selected_comment = id;
+ }
+ VisualShaderNodeConstant *constant_node = Object::cast_to<VisualShaderNodeConstant>(node.ptr());
+ if (constant_node != nullptr) {
+ selected_constants.insert(id);
+ }
+ VisualShaderNodeFloatConstant *float_constant_node = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr());
+ if (float_constant_node != nullptr) {
+ selected_float_constant = id;
+ }
+ VisualShaderNodeParameter *parameter_node = Object::cast_to<VisualShaderNodeParameter>(node.ptr());
+ if (parameter_node != nullptr && parameter_node->is_convertible_to_constant()) {
+ selected_parameters.insert(id);
}
}
}
- if (to_change.size() > 1) {
+ if (selected_closable_graph_elements.size() > 1) {
selected_comment = -1;
selected_float_constant = -1;
}
@@ -3895,14 +3913,14 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (to_change.is_empty() && copy_buffer_empty) {
+ if (selected_closable_graph_elements.is_empty() && copy_buffer_empty) {
_show_members_dialog(true);
} else {
- popup_menu->set_item_disabled(NodeMenuOptions::CUT, to_change.is_empty());
- popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::CUT, selected_closable_graph_elements.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::COPY, selected_closable_graph_elements.is_empty());
popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_buffer_empty);
- popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty());
- popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::DELETE, selected_closable_graph_elements.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, selected_closable_graph_elements.is_empty());
popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_buffer_empty);
int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2);
@@ -4085,11 +4103,11 @@ void VisualShaderEditor::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- highend_label->set_modulate(get_theme_color(SNAME("highend_color"), SNAME("Editor")));
+ highend_label->set_modulate(get_theme_color(SNAME("highend_color"), EditorStringName(Editor)));
- node_filter->set_right_icon(Control::get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ node_filter->set_right_icon(Control::get_editor_theme_icon(SNAME("Search")));
- preview_shader->set_icon(Control::get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")));
+ preview_shader->set_icon(Control::get_editor_theme_icon(SNAME("Shader")));
{
Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color");
@@ -4101,7 +4119,7 @@ void VisualShaderEditor::_notification(int p_what) {
Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color");
Color number_color = EDITOR_GET("text_editor/theme/highlighting/number_color");
Color members_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color");
- Color error_color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ Color error_color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
preview_text->add_theme_color_override("background_color", background_color);
varying_error_label->add_theme_color_override("font_color", error_color);
@@ -4114,8 +4132,8 @@ void VisualShaderEditor::_notification(int p_what) {
}
}
- preview_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts")));
- preview_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")));
+ preview_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), EditorStringName(EditorFonts)));
+ preview_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), EditorStringName(EditorFonts)));
preview_text->add_theme_color_override("font_color", text_color);
syntax_highlighter->set_number_color(number_color);
syntax_highlighter->set_symbol_color(symbol_color);
@@ -4130,12 +4148,12 @@ void VisualShaderEditor::_notification(int p_what) {
preview_text->add_comment_delimiter("//", "", true);
error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
- error_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+ error_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ error_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), EditorStringName(EditorFonts)));
error_label->add_theme_color_override("font_color", error_color);
}
- tools->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
+ tools->set_icon(get_editor_theme_icon(SNAME("Tools")));
if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
_update_graph();
@@ -4183,9 +4201,9 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li
HashSet<int> nodes;
for (int i = 0; i < graph->get_child_count(); i++) {
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- int id = String(gn->get_name()).to_int();
+ GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i));
+ if (graph_element) {
+ int id = String(graph_element->get_name()).to_int();
Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
Ref<VisualShaderNodeOutput> output = node;
@@ -4193,7 +4211,7 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li
continue;
}
- if (node.is_valid() && gn->is_selected()) {
+ if (node.is_valid() && graph_element->is_selected()) {
Vector2 pos = visual_shader->get_node_position(type, id);
selection_center += pos;
@@ -4319,13 +4337,13 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c
// reselect nodes by excluding the other ones
for (int i = 0; i < graph->get_child_count(); i++) {
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- int id = String(gn->get_name()).to_int();
+ GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i));
+ if (graph_element) {
+ int id = String(graph_element->get_name()).to_int();
if (added_set.has(id)) {
- gn->set_selected(true);
+ graph_element->set_selected(true);
} else {
- gn->set_selected(false);
+ graph_element->set_selected(false);
}
}
}
@@ -4691,28 +4709,28 @@ void VisualShaderEditor::_update_varying_tree() {
switch (varying->type) {
case VisualShader::VARYING_TYPE_FLOAT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")));
break;
case VisualShader::VARYING_TYPE_INT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")));
break;
case VisualShader::VARYING_TYPE_UINT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("uint"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")));
break;
case VisualShader::VARYING_TYPE_VECTOR_2D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")));
break;
case VisualShader::VARYING_TYPE_VECTOR_3D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")));
break;
case VisualShader::VARYING_TYPE_VECTOR_4D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")));
break;
case VisualShader::VARYING_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")));
break;
case VisualShader::VARYING_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")));
break;
default:
break;
@@ -4818,7 +4836,7 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) {
_paste_nodes(true, menu_point);
break;
case NodeMenuOptions::DELETE:
- _delete_nodes_request(TypedArray<StringName>());
+ _close_nodes_request(TypedArray<StringName>());
break;
case NodeMenuOptions::DUPLICATE:
_duplicate_nodes();
@@ -5118,7 +5136,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes));
graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(false));
graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes).bind(false, Point2()));
- graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request));
+ graph->connect("close_nodes_request", callable_mp(this, &VisualShaderEditor::_close_nodes_request));
graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input));
graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty));
graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty));
@@ -6177,15 +6195,15 @@ public:
editor = p_editor;
input = p_input;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("uint"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ImageTexture")),
};
add_item("[None]");
@@ -6227,14 +6245,14 @@ public:
varying = p_varying;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("uint"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
};
bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid();
@@ -6307,16 +6325,16 @@ public:
parameter_ref = p_parameter_ref;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("uint"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Color")),
+ EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ImageTexture")),
};
add_item("[None]");
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index bdb23afa0f..e0a0f3a096 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -38,9 +38,10 @@
#include "scene/resources/visual_shader.h"
class CodeEdit;
+class ColorPicker;
class CurveEditor;
class GraphEdit;
-class GraphNode;
+class GraphElement;
class MenuButton;
class PopupPanel;
class RichTextLabel;
@@ -81,7 +82,7 @@ private:
struct Link {
VisualShader::Type type = VisualShader::Type::TYPE_MAX;
VisualShaderNode *visual_node = nullptr;
- GraphNode *graph_node = nullptr;
+ GraphElement *graph_element = nullptr;
bool preview_visible = false;
int preview_pos = 0;
HashMap<int, InputPort> input_ports;
@@ -105,7 +106,7 @@ public:
void set_editor(VisualShaderEditor *p_editor);
void register_shader(VisualShader *p_visual_shader);
void set_connections(const List<VisualShader::Connection> &p_connections);
- void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node);
+ void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphElement *p_graph_element);
void register_output_port(int p_id, int p_port, TextureButton *p_button);
void register_parameter_name(int p_id, LineEdit *p_parameter_name);
void register_default_input_button(int p_node_id, int p_port_id, Button *p_button);
@@ -343,7 +344,7 @@ class VisualShaderEditor : public VBoxContainer {
List<VisualShaderNodeParameterRef> uniform_refs;
- void _draw_color_over_button(Object *obj, Color p_color);
+ void _draw_color_over_button(Object *p_obj, Color p_color);
void _setup_node(VisualShaderNode *p_node, const Vector<Variant> &p_ops);
void _add_node(int p_idx, const Vector<Variant> &p_ops, String p_resource_path = "", int p_node_idx = -1);
@@ -379,8 +380,8 @@ class VisualShaderEditor : public VBoxContainer {
void _node_selected(Object *p_node);
void _delete_nodes(int p_type, const List<int> &p_nodes);
- void _delete_node_request(int p_type, int p_node);
- void _delete_nodes_request(const TypedArray<StringName> &p_nodes);
+ void _close_node_request(int p_type, int p_node);
+ void _close_nodes_request(const TypedArray<StringName> &p_nodes);
void _node_changed(int p_id);
@@ -417,9 +418,9 @@ class VisualShaderEditor : public VBoxContainer {
void _comment_desc_text_changed();
void _parameter_line_edit_changed(const String &p_text, int p_node_id);
- void _parameter_line_edit_focus_out(Object *line_edit, int p_node_id);
+ void _parameter_line_edit_focus_out(Object *p_line_edit, int p_node_id);
- void _port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output);
+ void _port_name_focus_out(Object *p_line_edit, int p_node_id, int p_port_id, bool p_output);
struct CopyItem {
int id;
@@ -451,7 +452,7 @@ class VisualShaderEditor : public VBoxContainer {
void _mode_selected(int p_id);
void _custom_mode_toggled(bool p_enabled);
- void _input_select_item(Ref<VisualShaderNodeInput> input, String name);
+ void _input_select_item(Ref<VisualShaderNodeInput> p_input, String p_name);
void _parameter_ref_select_item(Ref<VisualShaderNodeParameterRef> p_parameter_ref, String p_name);
void _varying_select_item(Ref<VisualShaderNodeVarying> p_varying, String p_name);
@@ -470,7 +471,7 @@ class VisualShaderEditor : public VBoxContainer {
void _change_output_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port);
void _expand_output_port(int p_node, int p_port, bool p_expand);
- void _expression_focus_out(Object *code_edit, int p_node);
+ void _expression_focus_out(Object *p_code_edit, int p_node);
void _set_node_size(int p_type, int p_node, const Size2 &p_size);
void _node_resized(const Vector2 &p_new_size, int p_type, int p_node);
@@ -500,7 +501,6 @@ class VisualShaderEditor : public VBoxContainer {
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
bool _is_available(int p_mode);
- void _update_created_node(GraphNode *node);
void _update_parameters(bool p_update_refs);
void _update_parameter_refs(HashSet<String> &p_names);
void _update_varyings();
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index af4a027f78..50c68f7d21 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -185,7 +185,7 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin() {
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
bake->set_text(TTR("Bake VoxelGI"));
bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 6736bbc668..feb3d7fa14 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -44,6 +44,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_themes.h"
#include "editor/editor_vcs_interface.h"
#include "editor/gui/editor_file_dialog.h"
@@ -76,21 +77,21 @@ void ProjectDialog::_set_message(const String &p_msg, MessageType p_type, InputT
switch (p_type) {
case MESSAGE_ERROR: {
- msg->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ msg->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
msg->set_modulate(Color(1, 1, 1, 1));
- new_icon = get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"));
+ new_icon = get_editor_theme_icon(SNAME("StatusError"));
} break;
case MESSAGE_WARNING: {
- msg->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ msg->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
msg->set_modulate(Color(1, 1, 1, 1));
- new_icon = get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
+ new_icon = get_editor_theme_icon(SNAME("StatusWarning"));
} break;
case MESSAGE_SUCCESS: {
msg->remove_theme_color_override("font_color");
msg->set_modulate(Color(1, 1, 1, 0));
- new_icon = get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons"));
+ new_icon = get_editor_theme_icon(SNAME("StatusSuccess"));
} break;
}
@@ -647,11 +648,11 @@ void ProjectDialog::cancel_pressed() {
project_name->clear();
_text_changed("");
- if (status_rect->get_texture() == get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))) {
+ if (status_rect->get_texture() == get_editor_theme_icon(SNAME("StatusError"))) {
msg->show();
}
- if (install_status_rect->get_texture() == get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))) {
+ if (install_status_rect->get_texture() == get_editor_theme_icon(SNAME("StatusError"))) {
msg->show();
}
}
@@ -989,20 +990,20 @@ void ProjectListItemControl::_notification(int p_what) {
if (icon_needs_reload) {
// The project icon may not be loaded by the time the control is displayed,
// so use a loading placeholder.
- project_icon->set_texture(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons")));
+ project_icon->set_texture(get_editor_theme_icon(SNAME("ProjectIconLoading")));
}
- project_title->add_theme_font_override("font", get_theme_font(SNAME("title"), SNAME("EditorFonts")));
- project_title->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("title_size"), SNAME("EditorFonts")));
+ project_title->add_theme_font_override("font", get_theme_font(SNAME("title"), EditorStringName(EditorFonts)));
+ project_title->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("title_size"), EditorStringName(EditorFonts)));
project_title->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Tree")));
project_path->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Tree")));
- project_unsupported_features->set_texture(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
+ project_unsupported_features->set_texture(get_editor_theme_icon(SNAME("NodeWarning")));
- favorite_button->set_texture_normal(get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+ favorite_button->set_texture_normal(get_editor_theme_icon(SNAME("Favorites")));
if (project_is_missing) {
- explore_button->set_icon(get_theme_icon(SNAME("FileBroken"), SNAME("EditorIcons")));
+ explore_button->set_icon(get_editor_theme_icon(SNAME("FileBroken")));
} else {
- explore_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
+ explore_button->set_icon(get_editor_theme_icon(SNAME("Load")));
}
} break;
@@ -1104,12 +1105,12 @@ void ProjectListItemControl::set_is_missing(bool p_missing) {
if (project_is_missing) {
project_icon->set_modulate(Color(1, 1, 1, 0.5));
- explore_button->set_icon(get_theme_icon(SNAME("FileBroken"), SNAME("EditorIcons")));
+ explore_button->set_icon(get_editor_theme_icon(SNAME("FileBroken")));
explore_button->set_tooltip_text(TTR("Error: Project is missing on the filesystem."));
} else {
project_icon->set_modulate(Color(1, 1, 1, 1.0));
- explore_button->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
+ explore_button->set_icon(get_editor_theme_icon(SNAME("Load")));
#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
explore_button->set_tooltip_text(TTR("Show in File Manager"));
#else
@@ -1276,7 +1277,7 @@ void ProjectList::_update_icons_async() {
void ProjectList::_load_project_icon(int p_index) {
Item &item = _projects.write[p_index];
- Ref<Texture2D> default_icon = get_theme_icon(SNAME("DefaultProjectIcon"), SNAME("EditorIcons"));
+ Ref<Texture2D> default_icon = get_editor_theme_icon(SNAME("DefaultProjectIcon"));
Ref<Texture2D> icon;
if (!item.icon.is_empty()) {
Ref<Image> img;
@@ -1943,28 +1944,28 @@ void ProjectManager::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- background_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles")));
- loading_label->add_theme_font_override("font", get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
+ background_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
+ loading_label->add_theme_font_override("font", get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
search_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("search_panel"), SNAME("ProjectManager")));
// Top bar.
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- language_btn->set_icon(get_theme_icon(SNAME("Environment"), SNAME("EditorIcons")));
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ language_btn->set_icon(get_editor_theme_icon(SNAME("Environment")));
// Sidebar.
- create_btn->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- import_btn->set_icon(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")));
- scan_btn->set_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- open_btn->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- run_btn->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
- rename_btn->set_icon(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")));
- manage_tags_btn->set_icon(get_theme_icon("Script", "EditorIcons"));
- erase_btn->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- erase_missing_btn->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")));
- create_tag_btn->set_icon(get_theme_icon("Add", "EditorIcons"));
-
- tag_error->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
- tag_edit_error->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
+ create_btn->set_icon(get_editor_theme_icon(SNAME("Add")));
+ import_btn->set_icon(get_editor_theme_icon(SNAME("Load")));
+ scan_btn->set_icon(get_editor_theme_icon(SNAME("Search")));
+ open_btn->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ run_btn->set_icon(get_editor_theme_icon(SNAME("Play")));
+ rename_btn->set_icon(get_editor_theme_icon(SNAME("Rename")));
+ manage_tags_btn->set_icon(get_editor_theme_icon("Script"));
+ erase_btn->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ erase_missing_btn->set_icon(get_editor_theme_icon(SNAME("Clear")));
+ create_tag_btn->set_icon(get_editor_theme_icon("Add"));
+
+ tag_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
+ tag_edit_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
create_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
import_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
@@ -2054,9 +2055,9 @@ void ProjectManager::_build_icon_type_cache(Ref<Theme> p_theme) {
return;
}
List<StringName> tl;
- p_theme->get_icon_list(SNAME("EditorIcons"), &tl);
+ p_theme->get_icon_list(EditorStringName(EditorIcons), &tl);
for (List<StringName>::Element *E = tl.front(); E; E = E->next()) {
- icon_type_cache[E->get()] = p_theme->get_icon(E->get(), SNAME("EditorIcons"));
+ icon_type_cache[E->get()] = p_theme->get_icon(E->get(), EditorStringName(EditorIcons));
}
}
@@ -2837,7 +2838,7 @@ ProjectManager::ProjectManager() {
EditorColorMap::create();
Ref<Theme> theme = create_custom_theme();
- DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), SNAME("Editor")));
+ DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
set_theme(theme);
set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index e33f9f921d..09de9cda49 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h"
#include "scene/gui/check_button.h"
@@ -501,7 +502,7 @@ void ProjectSettingsEditor::_update_action_map_editor() {
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
- const Ref<Texture2D> builtin_icon = get_theme_icon(SNAME("PinPressed"), SNAME("EditorIcons"));
+ const Ref<Texture2D> builtin_icon = get_editor_theme_icon(SNAME("PinPressed"));
for (const PropertyInfo &E : props) {
const String property_name = E.name;
@@ -533,11 +534,11 @@ void ProjectSettingsEditor::_update_action_map_editor() {
}
void ProjectSettingsEditor::_update_theme() {
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- restart_close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons")));
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ restart_close_button->set_icon(get_editor_theme_icon(SNAME("Close")));
restart_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree")));
- restart_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
- restart_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ restart_icon->set_texture(get_editor_theme_icon(SNAME("StatusWarning")));
+ restart_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
type_box->clear();
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
@@ -546,7 +547,7 @@ void ProjectSettingsEditor::_update_theme() {
continue;
}
String type = Variant::get_type_name(Variant::Type(i));
- type_box->add_icon_item(get_theme_icon(type, SNAME("EditorIcons")), type, i);
+ type_box->add_icon_item(get_editor_theme_icon(type), type, i);
}
}
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 737f81c157..5228db03b9 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -125,44 +125,44 @@ void PropertySelector::_update_search() {
bool found = false;
Ref<Texture2D> type_icons[] = {
- search_options->get_theme_icon(SNAME("Variant"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("String"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector2i"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Rect2"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Rect2i"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector3i"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Transform2D"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Vector4i"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Plane"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Quaternion"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("AABB"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Projection"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("RID"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Signal"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Dictionary"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedVector3Array"), SNAME("EditorIcons")),
- search_options->get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons"))
+ search_options->get_editor_theme_icon(SNAME("Variant")),
+ search_options->get_editor_theme_icon(SNAME("bool")),
+ search_options->get_editor_theme_icon(SNAME("int")),
+ search_options->get_editor_theme_icon(SNAME("float")),
+ search_options->get_editor_theme_icon(SNAME("String")),
+ search_options->get_editor_theme_icon(SNAME("Vector2")),
+ search_options->get_editor_theme_icon(SNAME("Vector2i")),
+ search_options->get_editor_theme_icon(SNAME("Rect2")),
+ search_options->get_editor_theme_icon(SNAME("Rect2i")),
+ search_options->get_editor_theme_icon(SNAME("Vector3")),
+ search_options->get_editor_theme_icon(SNAME("Vector3i")),
+ search_options->get_editor_theme_icon(SNAME("Transform2D")),
+ search_options->get_editor_theme_icon(SNAME("Vector4")),
+ search_options->get_editor_theme_icon(SNAME("Vector4i")),
+ search_options->get_editor_theme_icon(SNAME("Plane")),
+ search_options->get_editor_theme_icon(SNAME("Quaternion")),
+ search_options->get_editor_theme_icon(SNAME("AABB")),
+ search_options->get_editor_theme_icon(SNAME("Basis")),
+ search_options->get_editor_theme_icon(SNAME("Transform3D")),
+ search_options->get_editor_theme_icon(SNAME("Projection")),
+ search_options->get_editor_theme_icon(SNAME("Color")),
+ search_options->get_editor_theme_icon(SNAME("StringName")),
+ search_options->get_editor_theme_icon(SNAME("NodePath")),
+ search_options->get_editor_theme_icon(SNAME("RID")),
+ search_options->get_editor_theme_icon(SNAME("MiniObject")),
+ search_options->get_editor_theme_icon(SNAME("Callable")),
+ search_options->get_editor_theme_icon(SNAME("Signal")),
+ search_options->get_editor_theme_icon(SNAME("Dictionary")),
+ search_options->get_editor_theme_icon(SNAME("Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedByteArray")),
+ search_options->get_editor_theme_icon(SNAME("PackedInt32Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedInt64Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedFloat32Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedFloat64Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedStringArray")),
+ search_options->get_editor_theme_icon(SNAME("PackedVector2Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedVector3Array")),
+ search_options->get_editor_theme_icon(SNAME("PackedColorArray"))
};
static_assert((sizeof(type_icons) / sizeof(type_icons[0])) == Variant::VARIANT_MAX, "Number of type icons doesn't match the number of Variant types.");
@@ -177,7 +177,7 @@ void PropertySelector::_update_search() {
Ref<Texture2D> icon;
if (E.name == "Script Variables") {
- icon = search_options->get_theme_icon(SNAME("Script"), SNAME("EditorIcons"));
+ icon = search_options->get_editor_theme_icon(SNAME("Script"));
} else {
icon = EditorNode::get_singleton()->get_class_icon(E.name);
}
@@ -257,7 +257,7 @@ void PropertySelector::_update_search() {
script_methods = false;
String rep = mi.name.replace("*", "");
if (mi.name == "*Script Methods") {
- icon = search_options->get_theme_icon(SNAME("Script"), SNAME("EditorIcons"));
+ icon = search_options->get_editor_theme_icon(SNAME("Script"));
script_methods = true;
} else {
icon = EditorNode::get_singleton()->get_class_icon(rep);
diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp
index 849a6cc097..a636d8c1f2 100644
--- a/editor/register_editor_types.cpp
+++ b/editor/register_editor_types.cpp
@@ -41,6 +41,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_script.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_translation_parser.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export_platform.h"
@@ -133,6 +134,8 @@ void register_editor_types() {
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
+ EditorStringNames::create();
+
GDREGISTER_CLASS(EditorPaths);
GDREGISTER_CLASS(EditorPlugin);
GDREGISTER_CLASS(EditorTranslationParserPlugin);
@@ -289,6 +292,7 @@ void unregister_editor_types() {
if (EditorPaths::get_singleton()) {
EditorPaths::free();
}
+ EditorStringNames::free();
OS::get_singleton()->benchmark_end_measure("unregister_editor_types");
}
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 9d3cb4f2ae..9eeea0ac54 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -37,10 +37,11 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_themes.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/script_editor_plugin.h"
#include "modules/regex/regex.h"
-#include "plugins/script_editor_plugin.h"
#include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
#include "scene/gui/control.h"
@@ -396,11 +397,11 @@ void RenameDialog::_update_preview(String new_text) {
if (new_name == preview_node->get_name()) {
// New name is identical to the old one. Don't color it as much to avoid distracting the user.
- const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("default_color"), SNAME("RichTextLabel"));
lbl_preview->add_theme_color_override("font_color", accent_color.lerp(text_color, 0.5));
} else {
- lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
}
}
@@ -486,7 +487,7 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *
self->has_errors = true;
self->lbl_preview_title->set_text(TTR("Regular Expression Error:"));
- self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str));
}
diff --git a/editor/scene_create_dialog.cpp b/editor/scene_create_dialog.cpp
index aac9ca3739..d6cb36013f 100644
--- a/editor/scene_create_dialog.cpp
+++ b/editor/scene_create_dialog.cpp
@@ -34,6 +34,7 @@
#include "editor/create_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_validation_panel.h"
#include "scene/2d/node_2d.h"
#include "scene/3d/node_3d.h"
@@ -48,11 +49,11 @@ void SceneCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- select_node_button->set_icon(get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons")));
- node_type_2d->set_icon(get_theme_icon(SNAME("Node2D"), SNAME("EditorIcons")));
- node_type_3d->set_icon(get_theme_icon(SNAME("Node3D"), SNAME("EditorIcons")));
- node_type_gui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
- node_type_other->add_theme_icon_override(SNAME("icon"), get_theme_icon(SNAME("Node"), SNAME("EditorIcons")));
+ select_node_button->set_icon(get_editor_theme_icon(SNAME("ClassList")));
+ node_type_2d->set_icon(get_editor_theme_icon(SNAME("Node2D")));
+ node_type_3d->set_icon(get_editor_theme_icon(SNAME("Node3D")));
+ node_type_gui->set_icon(get_editor_theme_icon(SNAME("Control")));
+ node_type_other->add_theme_icon_override(SNAME("icon"), get_editor_theme_icon(SNAME("Node")));
} break;
}
}
@@ -103,6 +104,8 @@ void SceneCreateDialog::update_dialog() {
if (validation_panel->is_valid() && !scene_name.is_valid_filename()) {
validation_panel->set_message(MSG_ID_PATH, TTR("File name invalid."), EditorValidationPanel::MSG_ERROR);
+ } else if (validation_panel->is_valid() && scene_name[0] == '.') {
+ validation_panel->set_message(MSG_ID_PATH, TTR("File name begins with a dot."), EditorValidationPanel::MSG_ERROR);
}
if (validation_panel->is_valid()) {
@@ -114,8 +117,8 @@ void SceneCreateDialog::update_dialog() {
}
const StringName root_type_name = StringName(other_type_display->get_text());
- if (has_theme_icon(root_type_name, SNAME("EditorIcons"))) {
- node_type_other->set_icon(get_theme_icon(root_type_name, SNAME("EditorIcons")));
+ if (has_theme_icon(root_type_name, EditorStringName(EditorIcons))) {
+ node_type_other->set_icon(get_editor_theme_icon(root_type_name));
} else {
node_type_other->set_icon(nullptr);
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index b1e30d369f..161598b50f 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -43,6 +43,7 @@
#include "editor/editor_quick_open.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/inspector_dock.h"
@@ -1319,7 +1320,7 @@ void SceneTreeDock::_notification(int p_what) {
node_shortcuts_toggle = memnew(Button);
node_shortcuts_toggle->set_flat(true);
- node_shortcuts_toggle->set_icon(get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
+ node_shortcuts_toggle->set_icon(get_editor_theme_icon(SNAME("Favorites")));
node_shortcuts_toggle->set_toggle_mode(true);
node_shortcuts_toggle->set_tooltip_text(TTR("Switch to Favorite Nodes"));
node_shortcuts_toggle->set_pressed(EDITOR_GET("_use_favorites_root_selection"));
@@ -1344,19 +1345,19 @@ void SceneTreeDock::_notification(int p_what) {
button_2d = memnew(Button);
beginner_node_shortcuts->add_child(button_2d);
button_2d->set_text(TTR("2D Scene"));
- button_2d->set_icon(get_theme_icon(SNAME("Node2D"), SNAME("EditorIcons")));
+ button_2d->set_icon(get_editor_theme_icon(SNAME("Node2D")));
button_2d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_2D_SCENE, false));
button_3d = memnew(Button);
beginner_node_shortcuts->add_child(button_3d);
button_3d->set_text(TTR("3D Scene"));
- button_3d->set_icon(get_theme_icon(SNAME("Node3D"), SNAME("EditorIcons")));
+ button_3d->set_icon(get_editor_theme_icon(SNAME("Node3D")));
button_3d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_3D_SCENE, false));
button_ui = memnew(Button);
beginner_node_shortcuts->add_child(button_ui);
button_ui->set_text(TTR("User Interface"));
- button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
+ button_ui->set_icon(get_editor_theme_icon(SNAME("Control")));
button_ui->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_USER_INTERFACE, false));
favorite_node_shortcuts = memnew(VBoxContainer);
@@ -1365,13 +1366,13 @@ void SceneTreeDock::_notification(int p_what) {
button_custom = memnew(Button);
node_shortcuts->add_child(button_custom);
button_custom->set_text(TTR("Other Node"));
- button_custom->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_custom->set_icon(get_editor_theme_icon(SNAME("Add")));
button_custom->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_NEW, false));
button_clipboard = memnew(Button);
node_shortcuts->add_child(button_clipboard);
button_clipboard->set_text(TTR("Paste From Clipboard"));
- button_clipboard->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")));
+ button_clipboard->set_icon(get_editor_theme_icon(SNAME("ActionPaste")));
button_clipboard->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_PASTE, false));
_update_create_root_dialog();
@@ -1391,37 +1392,37 @@ void SceneTreeDock::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- button_instance->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
- button_create_script->set_icon(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")));
- button_detach_script->set_icon(get_theme_icon(SNAME("ScriptRemove"), SNAME("EditorIcons")));
- button_tree_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ button_add->set_icon(get_editor_theme_icon(SNAME("Add")));
+ button_instance->set_icon(get_editor_theme_icon(SNAME("Instance")));
+ button_create_script->set_icon(get_editor_theme_icon(SNAME("ScriptCreate")));
+ button_detach_script->set_icon(get_editor_theme_icon(SNAME("ScriptRemove")));
+ button_tree_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
- filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+ filter->set_right_icon(get_editor_theme_icon(SNAME("Search")));
PopupMenu *filter_menu = filter->get_menu();
- filter_menu->set_item_icon(filter_menu->get_item_idx_from_text(TTR("Filters")), get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filter_menu->set_item_icon(filter_menu->get_item_index(FILTER_BY_TYPE), get_theme_icon(SNAME("Node"), SNAME("EditorIcons")));
- filter_menu->set_item_icon(filter_menu->get_item_index(FILTER_BY_GROUP), get_theme_icon(SNAME("Groups"), SNAME("EditorIcons")));
+ filter_menu->set_item_icon(filter_menu->get_item_idx_from_text(TTR("Filters")), get_editor_theme_icon(SNAME("Search")));
+ filter_menu->set_item_icon(filter_menu->get_item_index(FILTER_BY_TYPE), get_editor_theme_icon(SNAME("Node")));
+ filter_menu->set_item_icon(filter_menu->get_item_index(FILTER_BY_GROUP), get_editor_theme_icon(SNAME("Groups")));
// These buttons are created on READY, because reasons...
if (button_2d) {
- button_2d->set_icon(get_theme_icon(SNAME("Node2D"), SNAME("EditorIcons")));
+ button_2d->set_icon(get_editor_theme_icon(SNAME("Node2D")));
}
if (button_3d) {
- button_3d->set_icon(get_theme_icon(SNAME("Node3D"), SNAME("EditorIcons")));
+ button_3d->set_icon(get_editor_theme_icon(SNAME("Node3D")));
}
if (button_ui) {
- button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
+ button_ui->set_icon(get_editor_theme_icon(SNAME("Control")));
}
if (button_custom) {
- button_custom->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_custom->set_icon(get_editor_theme_icon(SNAME("Add")));
}
if (button_clipboard) {
- button_clipboard->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")));
+ button_clipboard->set_icon(get_editor_theme_icon(SNAME("ActionPaste")));
}
- menu_subresources->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), SNAME("Editor")));
+ menu_subresources->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
} break;
case NOTIFICATION_PROCESS: {
@@ -2925,8 +2926,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (!EditorNode::get_singleton()->get_edited_scene()) {
menu->clear();
if (profile_allow_editing) {
- menu->add_icon_shortcut(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
- menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Add")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Instance")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE);
}
menu->reset_size();
@@ -2958,10 +2959,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
}
- menu->add_icon_shortcut(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
- menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Add")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Instance")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE);
}
- menu->add_icon_shortcut(get_theme_icon(SNAME("Collapse"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Collapse")), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE);
menu->add_separator();
existing_script = selected->get_script();
@@ -2972,11 +2973,11 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
if (profile_allow_editing) {
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCut"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/cut_node"), TOOL_CUT);
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node"), TOOL_COPY);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionCut")), ED_GET_SHORTCUT("scene_tree/cut_node"), TOOL_CUT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionCopy")), ED_GET_SHORTCUT("scene_tree/copy_node"), TOOL_COPY);
if (selection.size() == 1 && !node_clipboard.is_empty()) {
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE);
- menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/paste_node_as_sibling"), TOOL_PASTE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionPaste")), ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionPaste")), ED_GET_SHORTCUT("scene_tree/paste_node_as_sibling"), TOOL_PASTE);
}
menu->add_separator();
}
@@ -2986,14 +2987,14 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (full_selection.size() == 1) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ScriptCreate")), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
if (existing_script.is_valid()) {
- menu->add_icon_shortcut(get_theme_icon(SNAME("ScriptExtend"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_EXTEND_SCRIPT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ScriptExtend")), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_EXTEND_SCRIPT);
}
}
if (existing_script.is_valid() && existing_script_removable) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon(SNAME("ScriptRemove"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ScriptRemove")), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
} else if (full_selection.size() > 1) {
bool script_exists = false;
for (Node *E : full_selection) {
@@ -3005,7 +3006,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (script_exists) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon(SNAME("ScriptRemove"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ScriptRemove")), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
}
}
@@ -3019,7 +3020,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (full_selection.size() == 1) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Rename")), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
bool can_replace = true;
@@ -3032,32 +3033,32 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (can_replace) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Reload")), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
}
if (scene_tree->get_selected() != edited_scene) {
if (add_separator) {
menu->add_separator();
}
- menu->add_icon_shortcut(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
- menu->add_icon_shortcut(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
- menu->add_icon_shortcut(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
- menu->add_icon_shortcut(get_theme_icon(SNAME("Reparent"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
- menu->add_icon_shortcut(get_theme_icon(SNAME("ReparentToNewNode"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("MoveUp")), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("MoveDown")), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Duplicate")), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Reparent")), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ReparentToNewNode")), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE);
if (selection.size() == 1) {
- menu->add_icon_shortcut(get_theme_icon(SNAME("NewRoot"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("NewRoot")), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
}
}
}
if (selection.size() == 1) {
if (profile_allow_editing) {
menu->add_separator();
- menu->add_icon_shortcut(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("CreateNewSceneFrom")), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
}
if (full_selection.size() == 1) {
menu->add_separator();
- menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("CopyNodePath")), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
}
}
@@ -3076,7 +3077,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
}
Node *node = full_selection[0];
- menu->add_icon_shortcut(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/toggle_unique_name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("SceneUniqueName")), ED_GET_SHORTCUT("scene_tree/toggle_unique_name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME);
menu->set_item_text(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), node->is_unique_name_in_owner() ? TTR("Revoke Unique Name") : TTR("Access as Unique Name"));
}
}
@@ -3091,7 +3092,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (profile_allow_editing) {
menu->add_item(TTR("Clear Inheritance"), TOOL_SCENE_CLEAR_INHERITANCE);
}
- menu->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open in Editor"), TOOL_SCENE_OPEN_INHERITED);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open in Editor"), TOOL_SCENE_OPEN_INHERITED);
} else if (!is_top_level) {
menu->add_separator();
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(selection[0]);
@@ -3101,7 +3102,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_check_item(TTR("Load As Placeholder"), TOOL_SCENE_USE_PLACEHOLDER);
menu->add_item(TTR("Make Local"), TOOL_SCENE_MAKE_LOCAL);
}
- menu->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open in Editor"), TOOL_SCENE_OPEN);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open in Editor"), TOOL_SCENE_OPEN);
if (profile_allow_editing) {
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Editable Children")), editable);
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
@@ -3114,15 +3115,15 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (profile_allow_editing && selection.size() > 1) {
//this is not a commonly used action, it makes no sense for it to be where it was nor always present.
menu->add_separator();
- menu->add_icon_shortcut(get_theme_icon(SNAME("Rename"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/batch_rename"), TOOL_BATCH_RENAME);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Rename")), ED_GET_SHORTCUT("scene_tree/batch_rename"), TOOL_BATCH_RENAME);
}
#endif // MODULE_REGEX_ENABLED
menu->add_separator();
- menu->add_icon_item(get_theme_icon(SNAME("Help"), SNAME("EditorIcons")), TTR("Open Documentation"), TOOL_OPEN_DOCUMENTATION);
+ menu->add_icon_item(get_editor_theme_icon(SNAME("Help")), TTR("Open Documentation"), TOOL_OPEN_DOCUMENTATION);
if (profile_allow_editing) {
menu->add_separator();
- menu->add_icon_shortcut(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), Key::KEY_DELETE), TOOL_ERASE);
+ menu->add_icon_shortcut(get_editor_theme_icon(SNAME("Remove")), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), Key::KEY_DELETE), TOOL_ERASE);
}
menu->reset_size();
menu->set_position(p_menu_pos);
@@ -3152,7 +3153,7 @@ void SceneTreeDock::_filter_changed(const String &p_filter) {
String warning = scene_tree->get_filter_term_warning();
if (!warning.is_empty()) {
- filter->add_theme_icon_override(SNAME("clear"), get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
+ filter->add_theme_icon_override(SNAME("clear"), get_editor_theme_icon(SNAME("NodeWarning")));
filter->set_tooltip_text(warning);
} else {
filter->remove_theme_icon_override(SNAME("clear"));
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index daac755529..b668ccf031 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/gui/editor_validation_panel.h"
@@ -111,7 +112,7 @@ void ScriptCreateDialog::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- Ref<Texture2D> language_icon = get_theme_icon(ScriptServer::get_language(i)->get_type(), SNAME("EditorIcons"));
+ Ref<Texture2D> language_icon = get_editor_theme_icon(ScriptServer::get_language(i)->get_type());
if (language_icon.is_valid()) {
language_menu->set_item_icon(i, language_icon);
}
@@ -134,9 +135,9 @@ void ScriptCreateDialog::_notification(int p_what) {
use_templates->set_pressed(is_using_templates);
}
- path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
- parent_browse_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
- parent_search_button->set_icon(get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons")));
+ path_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
+ parent_browse_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
+ parent_search_button->set_icon(get_editor_theme_icon(SNAME("ClassList")));
} break;
}
}
@@ -243,6 +244,9 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
if (!p.get_file().get_basename().is_valid_filename()) {
return TTR("Filename is invalid.");
}
+ if (p.get_file().begins_with(".")) {
+ return TTR("Name begins with a dot.");
+ }
p = ProjectSettings::get_singleton()->localize_path(p);
if (!p.begins_with("res://")) {
@@ -390,6 +394,8 @@ void ScriptCreateDialog::_create_new() {
if (is_built_in) {
scr->set_name(internal_name->get_text());
+ // Make sure the script is compiled to make its type recognizable.
+ scr->reload();
} else {
String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text());
scr->set_path(lpath);
@@ -644,8 +650,8 @@ void ScriptCreateDialog::_update_template_menu() {
}
t.id = id;
template_list.push_back(t);
- String icon = has_theme_icon(t.inherit, SNAME("EditorIcons")) ? t.inherit : "Object";
- template_menu->set_item_icon(id, get_theme_icon(icon, SNAME("EditorIcons")));
+ String icon = has_theme_icon(t.inherit, EditorStringName(EditorIcons)) ? t.inherit : "Object";
+ template_menu->set_item_icon(id, get_editor_theme_icon(icon));
}
}
ancestor_level++;
diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp
index 9a7b9bc84d..53ec1180a3 100644
--- a/editor/shader_create_dialog.cpp
+++ b/editor/shader_create_dialog.cpp
@@ -74,22 +74,22 @@ void ShaderCreateDialog::_notification(int p_what) {
}
void ShaderCreateDialog::_update_theme() {
- Ref<Texture2D> shader_icon = gc->get_theme_icon(SNAME("Shader"), SNAME("EditorIcons"));
+ Ref<Texture2D> shader_icon = gc->get_editor_theme_icon(SNAME("Shader"));
if (shader_icon.is_valid()) {
type_menu->set_item_icon(0, shader_icon);
}
- Ref<Texture2D> visual_shader_icon = gc->get_theme_icon(SNAME("VisualShader"), SNAME("EditorIcons"));
+ Ref<Texture2D> visual_shader_icon = gc->get_editor_theme_icon(SNAME("VisualShader"));
if (visual_shader_icon.is_valid()) {
type_menu->set_item_icon(1, visual_shader_icon);
}
- Ref<Texture2D> include_icon = gc->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons"));
+ Ref<Texture2D> include_icon = gc->get_editor_theme_icon(SNAME("TextFile"));
if (include_icon.is_valid()) {
type_menu->set_item_icon(2, include_icon);
}
- path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ path_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
}
void ShaderCreateDialog::_update_language_info() {
diff --git a/editor/translations/editor/ar.po b/editor/translations/editor/ar.po
index 6c1ac285d4..493a30dc67 100644
--- a/editor/translations/editor/ar.po
+++ b/editor/translations/editor/ar.po
@@ -83,13 +83,14 @@
# Omran Alsaedi <Omran2222@outlook.sa>, 2023.
# Android Prime <abodinagdat16@gmail.com>, 2023.
# Ibraheem Asad <ibo.asad.97@gmail.com>, 2023.
+# Aya Ichrak <ayaichrack@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-17 11:10+0000\n"
-"Last-Translator: Ibraheem Asad <ibo.asad.97@gmail.com>\n"
+"PO-Revision-Date: 2023-08-24 14:55+0000\n"
+"Last-Translator: Aya Ichrak <ayaichrack@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/godot/"
"ar/>\n"
"Language: ar\n"
@@ -199,6 +200,9 @@ msgstr ""
msgid "Guide, Sony PS, Xbox Home"
msgstr "الدليل, Sony PS, زر الرئيسية على Xbox"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "البداية, زر الرئيسية على Xbox , زر + على Nintendo"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "الإتجاه الأيسر على عصا التحكم, زر L3 على Sony, زر L/LS على Xbox"
diff --git a/editor/translations/editor/ca.po b/editor/translations/editor/ca.po
index 11940fa1ee..e5654e9765 100644
--- a/editor/translations/editor/ca.po
+++ b/editor/translations/editor/ca.po
@@ -18,13 +18,14 @@
# DFC <damiafluixacanals28@gmail.com>, 2021.
# Roger VC <rogervilarasau@gmail.com>, 2022.
# Jordi Borràs <jborras@centrekepler.com>, 2023.
+# Marc GB <marc.giralt.butjosa@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-03-19 23:59+0000\n"
-"Last-Translator: Jordi Borràs <jborras@centrekepler.com>\n"
+"PO-Revision-Date: 2023-08-22 15:34+0000\n"
+"Last-Translator: Marc GB <marc.giralt.butjosa@gmail.com>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/"
"godot/ca/>\n"
"Language: ca\n"
@@ -32,7 +33,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.16.2-dev\n"
+"X-Generator: Weblate 5.0-dev\n"
msgid "Unset"
msgstr "Desactiva"
@@ -178,6 +179,9 @@ msgstr "Botó del Joypad %d"
msgid "Pressure:"
msgstr "Pressió:"
+msgid "canceled"
+msgstr "cancel·lat"
+
msgid "touched"
msgstr "tocat"
@@ -1018,6 +1022,15 @@ msgstr "Crea pistes RESET"
msgid "Animation Optimizer"
msgstr "Optimitzador d'Animació"
+msgid "Max Velocity Error:"
+msgstr "Error Màx. Velocitat:"
+
+msgid "Max Angular Error:"
+msgstr "Error Màx. Angular:"
+
+msgid "Max Precision Error:"
+msgstr "Error Màx Precisió.:"
+
msgid "Optimize"
msgstr "Optimitza"
@@ -1039,6 +1052,9 @@ msgstr "Poleix"
msgid "Scale Ratio:"
msgstr "Relació d'Escala:"
+msgid "Select Transition and Easing"
+msgstr "Selecciona la transició i el suavitzat"
+
msgid "Select Tracks to Copy"
msgstr "Seleccioneu les Pistes a Copiar"
@@ -1972,6 +1988,9 @@ msgstr "Propietats"
msgid "default:"
msgstr "predeterminat:"
+msgid "Operators"
+msgstr "Operadors"
+
msgid "Theme Properties"
msgstr "Propietats del tema"
diff --git a/editor/translations/editor/de.po b/editor/translations/editor/de.po
index f539d9a85e..6492a90aba 100644
--- a/editor/translations/editor/de.po
+++ b/editor/translations/editor/de.po
@@ -106,8 +106,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-07 09:44+0000\n"
-"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
+"PO-Revision-Date: 2023-09-08 02:18+0000\n"
+"Last-Translator: ‎ <artism90@googlemail.com>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/godot/"
"de/>\n"
"Language: de\n"
@@ -115,7 +115,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Nicht gesetzt"
@@ -213,6 +213,9 @@ msgstr "Zurück, Sony Select, Xbox Back, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Orientierung, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, Xbox-Menü, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Linker Steuerknüppel, Sony L3, Xbox L/LS"
@@ -1257,6 +1260,9 @@ msgstr "Zeilennummer:"
msgid "%d replaced."
msgstr "%d ersetzt."
+msgid "No match"
+msgstr "Keine Übereinstimmung"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d Übereinstimmung"
@@ -3120,6 +3126,9 @@ msgstr "Fehler beim Parsen der Datei ‚%s‘."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "Szenendatei ‚%s‘ scheint ungültig/fehlerhaft zu sein."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "Datei ‚%s‘ oder zugehörige Abhängigkeiten fehlen."
+
msgid "Error while loading file '%s'."
msgstr "Fehler beim Laden von Datei ‚%s‘."
@@ -12546,6 +12555,15 @@ msgstr "Metadaten der Versionsverwaltung:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr ""
+"Dieses Projekt wurde zuletzt mit einer anderen Godot-Version bearbeitet: "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr ""
+"Dieses Projekt verwendet Funktionen, die von dieser Godot-Version nicht "
+"unterstützt werden:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "Fehler: Projekt ist nicht im Dateisystem vorhanden."
@@ -12693,6 +12711,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Achtung: Dieses Projekt wurde zuletzt mit Godot %s bearbeitet. Öffnen des "
+"Projekts wird es zu Godot %s ändern.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12837,6 +12864,29 @@ msgstr "Ebenfalls Projektinhalte löschen (nicht rückgängig machbar!)"
msgid "Convert Full Project"
msgstr "Gesamtes Projekt konvertieren"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"Mit dieser Option wird eine vollständige Projektkonvertierung durchgeführt, "
+"bei der Szenen, Ressourcen und Skripte aus Godot 3 aktualisiert werden, um "
+"mit Godot 4 funktionieren.\n"
+"\n"
+"Es handelt sich hierbei lediglich um eine automatische Konvertierung, welche "
+"die Aktualisierung des Projekts erleichtert. Es kann weiterhin vorkommen, "
+"dass sich das Projekt danach nicht öffnen lässt und weitere manuelle "
+"Anpassungen erforderlich sind.\n"
+"\n"
+"WICHTIG: Bitte Projekt vor der Konvertierung unbedingt sichern, da dieser "
+"Vorgang eine Rückkehr in frühere Godot-Versionen unmöglich macht."
+
msgid "Can't run project"
msgstr "Projekt kann nicht ausgeführt werden"
@@ -13151,7 +13201,7 @@ msgid "Delete %d nodes?"
msgstr "%d Nodes löschen?"
msgid "Delete the root node \"%s\"?"
-msgstr "Das Wurzelnode „%s“ löschen?"
+msgstr "Den Wurzelnode „%s“ löschen?"
msgid "Delete node \"%s\" and its children?"
msgstr "Node „%s“ und seine Unterelemente löschen?"
@@ -13891,7 +13941,7 @@ msgid ""
msgstr ""
".NET-Laufzeitumgebung konnte nicht geladen werden. Es wurde keine kompatible "
"Version gefunden.\n"
-"Der Versuch ein Projekt zu erstellen oder zu bearbeiten wird fehlschlagen.\n"
+"Der Versuch, ein Projekt zu erstellen oder zu bearbeiten, wird fehlschlagen.\n"
"\n"
"Bitte .NET SDK 6.0 oder neuer aus https://dotnet.microsoft.com/en-us/download "
"installieren und Godot neustarten."
@@ -13907,7 +13957,7 @@ msgid ""
"us/download and restart Godot."
msgstr ""
".NET-Laufzeitumgebung konnte nicht geladen werden, insbesondere ›hostfxr‹.\n"
-"Der Versuch ein Projekt zu erstellen oder zu bearbeiten wird fehlschlagen.\n"
+"Der Versuch, ein Projekt zu erstellen oder zu bearbeiten, wird fehlschlagen.\n"
"\n"
"Bitte .NET SDK 6.0 oder neuer aus https://dotnet.microsoft.com/en-us/download "
"installieren und Godot neustarten."
@@ -14514,6 +14564,9 @@ msgid "Code signing failed, see editor log for details."
msgstr ""
"Code-Signierung fehlgeschlagen, bitte weitere Details im Editor-Log nachlesen."
+msgid "Xcode Build"
+msgstr "Xcode-Build"
+
msgid "Xcode project build failed, see editor log for details."
msgstr ""
"Xcode-Build fehlgeschlagen, bitte weitere Details im Editor-Log nachlesen."
@@ -16833,6 +16886,13 @@ msgstr "Der Instanzindex kann nicht negativ sein."
msgid "Allowed instance uniform indices must be within [0..%d] range."
msgstr "Erlaubte Instanz-Uniform-Indices müssen im Intervall [0..%d] liegen."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"‚hint_normal_roughness_texture‘ ist nur verfügbar wenn das Forward+-Backend "
+"verwendet wird."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "‚hint_normal_roughness_texture‘ wird nicht unterstützt in ‚%s‘-Shadern."
diff --git a/editor/translations/editor/es.po b/editor/translations/editor/es.po
index d74540c495..b98f8e305f 100644
--- a/editor/translations/editor/es.po
+++ b/editor/translations/editor/es.po
@@ -114,9 +114,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-06 10:12+0000\n"
-"Last-Translator: Braulio León Madrid Escobar <brauliomadrid.developer@gmail."
-"com>\n"
+"PO-Revision-Date: 2023-08-24 14:55+0000\n"
+"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -205,7 +204,7 @@ msgid "Joypad Motion on Axis %d (%s) with Value %.2f"
msgstr "Movimiento de joystick en el eje %d (%s) con valor %.2f"
msgid "Bottom Action, Sony Cross, Xbox A, Nintendo B"
-msgstr "Acción Inferior, Sony Equis, Xbox A, Nintendo B"
+msgstr "Acción Inferior, Sony Cruz, Xbox A, Nintendo B"
msgid "Right Action, Sony Circle, Xbox B, Nintendo A"
msgstr "Acción Derecha, Sony Círculo, Xbox B, Nintendo A"
@@ -222,6 +221,9 @@ msgstr "Atrás, Sony Select, Xbox Atrás, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Guía, Sony PS, Xbox Inicio"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, Menú Xbox, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Stick Izquierdo, Sony L3, Xbox L/LS"
@@ -1261,6 +1263,9 @@ msgstr "Número de Línea:"
msgid "%d replaced."
msgstr "%d reemplazado."
+msgid "No match"
+msgstr "Sin coincidencias"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d coincidencia"
@@ -3123,6 +3128,9 @@ msgstr "Error al analizar el archivo '%s'."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "El archivo de escena '%s' parece ser inválido/corrupto."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "Falta el archivo '%s' o una de sus dependencias."
+
msgid "Error while loading file '%s'."
msgstr "Error al cargar el archivo '%s'."
@@ -12557,6 +12565,14 @@ msgstr "Metadatos de Control de Versión:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr ""
+"Este proyecto fue editado por última vez en una versión diferente de Godot: "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr ""
+"Este proyecto utiliza características no compatibles con la versión actual:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "Error: Proyecto faltante en el sistema de archivos."
@@ -12702,6 +12718,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Advertencia: Este proyecto fue editado por última vez en Godot %s. Al abrirlo "
+"se actualizará a Godot %s.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12844,6 +12869,28 @@ msgstr "También eliminar el contenido del proyecto (¡no se puede deshacer!)"
msgid "Convert Full Project"
msgstr "Convertir Proyecto Completo"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"Esta opción realizará la conversión completa del proyecto, actualizando "
+"escenas, recursos y scripts de Godot 3.x para trabajar en Godot 4.0.\n"
+"\n"
+"Ten en cuenta que esta es la conversión mejor posible, es decir, facilita la "
+"actualización del proyecto, pero no se abrirá listo y aún requerirá ajustes "
+"manuales.\n"
+"\n"
+"IMPORTANTE: asegúrate de hacer una copia de seguridad de tu proyecto antes de "
+"la conversión ya que esta operación hace que sea imposible abrirlo en "
+"versiones anteriores de Godot."
+
msgid "Can't run project"
msgstr "No se puede ejecutar el proyecto"
@@ -16793,7 +16840,7 @@ msgid "Varyings cannot be used in '%s' shaders."
msgstr "Las variaciones no se pueden utilizar en los shaders '%s'."
msgid "Interpolation qualifiers are not supported for uniforms."
-msgstr "No se admiten calificadores de interpolación para uniforms."
+msgstr "Los parámetros de interpolación no son compatibles con los uniforms."
msgid "The '%s' data type is not supported for uniforms."
msgstr "El tipo de datos '%s' no es compatible con los uniforms."
@@ -16856,6 +16903,13 @@ msgstr ""
"Los índices permitidos para las instancias de uniforms deben estar dentro del "
"rango [0..%d]."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"'hint_normal_roughness_texture' solo está disponible cuando se usa el backend "
+"de Forward+."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "'hint_normal_roughness_texture' no está soportado en '%s' shaders."
diff --git a/editor/translations/editor/fa.po b/editor/translations/editor/fa.po
index f535233ce9..616bf279d7 100644
--- a/editor/translations/editor/fa.po
+++ b/editor/translations/editor/fa.po
@@ -40,13 +40,14 @@
# "Shahab Baradaran Dilmaghani (bdshahab)" <bdshahab@gmail.com>, 2023.
# محمد ایرانی <mohamadir10g01@gmail.com>, 2023.
# "P. A." <thekhanxp@gmail.com>, 2023.
+# MohammadSaleh Kamyab <mskf1383@envs.net>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-10 05:12+0000\n"
-"Last-Translator: \"LordProfo (Nima)\" <nimaentity30@gmail.com>\n"
+"PO-Revision-Date: 2023-08-27 17:53+0000\n"
+"Last-Translator: MohammadSaleh Kamyab <mskf1383@envs.net>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -54,7 +55,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "تنظیم نشده"
@@ -965,7 +966,7 @@ msgid "Instance:"
msgstr "نمونه:"
msgid "Updating assets on target device:"
-msgstr "به‌روزرسانی دارایی‌ها در دستگاه هدف:"
+msgstr "به‌روزرسانی دارایی‌ها در افزارهٔ هدف:"
msgid "ms"
msgstr "میلی ثانیه"
@@ -1233,28 +1234,28 @@ msgid "Licenses"
msgstr "گواهینامه"
msgid "Error opening asset file for \"%s\" (not in ZIP format)."
-msgstr "خطا در بازکردن فایل دارایی برای \"%s\" (فرمت ZIP نمی‌باشد)."
+msgstr "خطا در گشودن پروندهٔ دارایی برای «%s» (در قالب ZIP نمی‌باشد)."
msgid "%s (already exists)"
msgstr "\"%s\" (در حال حاضر موجود است)"
msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:"
-msgstr "محتوای دارایی \"%s\" - %d فایل(ها) با پروژه شما تضاد دارد:"
+msgstr "محتویات دارایی «%s»‏ - %d پرونده با پروژهٔ شما ناسازگار است:"
msgid "Contents of asset \"%s\" - No files conflict with your project:"
-msgstr "محتویات دارایی \"%s\" - هیچ فایلی با پروژه شما مغایرت ندارد:"
+msgstr "محتویات دارایی «%s» - هیچ پرونده‌ای با پروژهٔ شما ناسازگار نیست:"
msgid "Uncompressing Assets"
-msgstr "خارج کردن دارایی‌ها از حالت فشرده"
+msgstr "استخراج دارایی‌ها"
msgid "The following files failed extraction from asset \"%s\":"
-msgstr "فایل‌های زیر از دارایی \"%s\" استخراج نشدند:"
+msgstr "استخراج پرونده‌های زیر از دارایی «%s» شکست خورد:"
msgid "(and %s more files)"
msgstr "(و %s دیگر فایل ها)"
msgid "Asset \"%s\" installed successfully!"
-msgstr "دارایی \"%s\" با موفقیت نصب شد!"
+msgstr "دارایی «%s» با موفقیت نصب شد!"
msgid "Success!"
msgstr "موفقیت!"
@@ -1263,7 +1264,7 @@ msgid "Install"
msgstr "نصب کردن"
msgid "Asset Installer"
-msgstr "نصب کننده دارایی"
+msgstr "نصب‌کنندهٔ دارایی"
msgid "Speakers"
msgstr "بلندگوها"
@@ -1500,7 +1501,7 @@ msgid "Script Editor"
msgstr "ویرایشگر اسکریپت"
msgid "Asset Library"
-msgstr "کتابخانه دارایی"
+msgstr "کتابخانهٔ دارایی"
msgid "Scene Tree Editing"
msgstr "ویرایش درخت صحنه"
@@ -1521,7 +1522,7 @@ msgid "Allows to edit scripts using the integrated script editor."
msgstr "اجازهٔ ویرایش اسکریپت‌ها با استفاده از ویرایشگر اسکریپت داخلی را می‌دهد."
msgid "Provides built-in access to the Asset Library."
-msgstr "دسترسی داخلی به کتابخانهٔ دارایی را فراهم می‌کند."
+msgstr "دسترسی توکار به کتابخانهٔ دارایی را فراهم می‌کند."
msgid ""
"Allows to work with signals and groups of the node selected in the Scene dock."
@@ -1535,8 +1536,8 @@ msgid ""
"Allows to configure import settings for individual assets. Requires the "
"FileSystem dock to function."
msgstr ""
-"به پیکربندی تنظیمات Import برای دارایی های فردی اجازه می دهد. برای عملکرد به "
-"داک FileSystem نیاز دارد."
+"اجازهٔ پیکربندی درون‌ریزی تنظیمات دارایی‌های مستقل را می‌دهد. برای عملکرد به داک "
+"پرونده‌سامانه نیاز دارد."
msgid "(current)"
msgstr "(کنونی)"
@@ -1599,10 +1600,10 @@ msgid "Make Current"
msgstr "ساختن جریان"
msgid "Import"
-msgstr "وارد کردن"
+msgstr "درون‌ریزی"
msgid "Export"
-msgstr "خروجی"
+msgstr "برون‌ریزی"
msgid "Configure Selected Profile:"
msgstr "پیکربندی پروفایل انتخاب شده:"
@@ -1642,7 +1643,7 @@ msgstr ""
"کردن لغو شد"
msgid "(Re)Importing Assets"
-msgstr "(در حال) وارد کردن دوباره دارایی‌ها"
+msgstr "(باز)درون‌ریزی دارایی‌ها"
msgid "Import resources of type: %s"
msgstr "وارد کردن منابع از نوع: %s"
@@ -2216,7 +2217,7 @@ msgid "Open Script Editor"
msgstr "باز کردن ویرایشگر اسکریپت"
msgid "Open Asset Library"
-msgstr "گشودن کتابخانه دارایی"
+msgstr "گشودن کتابخانهٔ دارایی"
msgid "Open the next Editor"
msgstr "گشودن ویرایشگر متن"
@@ -2398,6 +2399,9 @@ msgstr "خطای اتصال"
msgid "Importing:"
msgstr "وارد کردن:"
+msgid "Uncompressing Android Build Sources"
+msgstr "استخراج منابع ساخت اندروید"
+
msgid "Current Version:"
msgstr "نسخه اخیر:"
@@ -2813,7 +2817,7 @@ msgstr "پیشرفته..."
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
-"هشدار: دارایی‌هایی وجود دارند که از این منبع استفاده می‌کنند، ممکن است بارگیری "
+"هشدار: دارایی‌هایی وجود دارند که از این منبع استفاده می‌کنند. ممکن است بار کردن "
"درست را متوقف کنند."
msgid "Mouse Buttons"
@@ -3146,7 +3150,7 @@ msgid "Search Templates, Projects, and Demos"
msgstr "جستجوی قالب‌ها، پروژه‌ها و دموها"
msgid "Search Assets (Excluding Templates, Projects, and Demos)"
-msgstr "جستجوی دارایی‌ها (به استثنای قالب‌ها، پروژه‌ها و دموها)"
+msgstr "جست‌وجوی دارایی‌ها (به استثنای قالب‌ها، پروژه‌ها و دموها)"
msgid "Import..."
msgstr "وارد کردن..."
@@ -3167,7 +3171,7 @@ msgid "Support"
msgstr "پشتیبانی"
msgid "Assets ZIP File"
-msgstr "فایل ZIP‌ دارایی‌های بازی"
+msgstr "پروندهٔ ZIP‌ دارایی‌ها"
msgid "Preview"
msgstr "پیش نمایش"
@@ -3404,7 +3408,7 @@ msgid "Sort"
msgstr "مرتب‌سازی"
msgid "File"
-msgstr "فایل"
+msgstr "پرونده"
msgid "Open..."
msgstr "بار کردن..."
@@ -3996,8 +4000,8 @@ msgid ""
"Can't run project: Assets need to be imported.\n"
"Please edit the project to trigger the initial import."
msgstr ""
-"پروژه اجرا نمی‌شود: دارایی ها باید وارد شوند.\n"
-"لطفاً پروژه را ویرایش کنید تا وارد کردن اولیه آغاز شود."
+"نمی‌توان پروژه را اجرا کرد: دارایی‌ها باید درون‌ریزی شوند.\n"
+"لطفاً پروژه را ویرایش کنید تا درون‌ریزی اولیه آغاز شود."
msgid "Are you sure to run %d projects at once?"
msgstr "آیا مطمئن هستید که %d پروژه را همزمان اجرا می‌کنید؟"
@@ -4066,8 +4070,8 @@ msgid ""
"You currently don't have any projects.\n"
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
-"شما درحال حاضر هیچ پروژه‌ای ندارید.\n"
-"آیا می خواهید پروژه‌های نمونه رسمی را در کتابخانه دارایی کاوش کنید؟"
+"شما هم‌اکنون هیچ پروژه‌ای ندارید.\n"
+"آیا می خواهید پروژه‌های نمونهٔ رسمی را در کتابخانهٔ دارایی کاوش کنید؟"
msgid "Manage Project Tags"
msgstr "مدیریت برچسب‌های پروژه"
diff --git a/editor/translations/editor/fr.po b/editor/translations/editor/fr.po
index 2069855c3e..200dc7241c 100644
--- a/editor/translations/editor/fr.po
+++ b/editor/translations/editor/fr.po
@@ -135,12 +135,14 @@
# John Donne <akheron@zaclys.net>, 2023.
# Chloe Lee-Hone <chloe.leehone@gmail.com>, 2023.
# Freyja <aerandil@gmail.com>, 2023.
+# Florian Charpentier <florian.charpentier67@gmail.com>, 2023.
+# Aya Ichrak <ayaichrack@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-17 11:10+0000\n"
+"PO-Revision-Date: 2023-09-06 09:23+0000\n"
"Last-Translator: Chloe Lee-Hone <chloe.leehone@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/godot/"
"fr/>\n"
@@ -149,7 +151,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Non défini"
@@ -247,6 +249,9 @@ msgstr "Retour, Select Sony, Back Xbox, - Nintendo"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Guide, PS Sony, Home Xbox"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, Menu Xbox, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Stick gauche, L3 Sony, L/LS Xbox"
@@ -1292,6 +1297,9 @@ msgstr "Numéro de ligne :"
msgid "%d replaced."
msgstr "%d remplacé."
+msgid "No match"
+msgstr "Aucune concordance"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d correspondance trouvée"
@@ -1552,6 +1560,9 @@ msgstr ""
msgid "Toggle Visibility"
msgstr "Basculer la visibilité"
+msgid "Syncing headers"
+msgstr "Préparation de l'environnement"
+
msgid "Getting remote file system"
msgstr "Obtenir le système de fichier distant"
@@ -1901,6 +1912,9 @@ msgstr "Possède"
msgid "Resources Without Explicit Ownership:"
msgstr "Ressources sans propriété explicite :"
+msgid "Folder name cannot be empty."
+msgstr "Un nom de métadonnée ne peut être vide."
+
msgid "Using slashes in folder names will create subfolders recursively."
msgstr ""
"Utiliser des barres obliques (slash) dans les noms de dossiers créera des "
@@ -1909,6 +1923,9 @@ msgstr ""
msgid "Could not create folder."
msgstr "Impossible de créer le dossier."
+msgid "Create new folder in %s:"
+msgstr "Créer un nouveau fichier dans %s :"
+
msgid "Create Folder"
msgstr "Créer un dossier"
@@ -4484,6 +4501,9 @@ msgstr "Ressources à exporter :"
msgid "Delete preset '%s'?"
msgstr "Supprimer le préréglage « %s » ?"
+msgid "(Inherited)"
+msgstr "(Hérité)"
+
msgid "%s Export"
msgstr "Export %s"
@@ -5237,6 +5257,9 @@ msgstr "Cliquez pour afficher le dock des signaux."
msgid "Open in Editor"
msgstr "Ouvrir dans l'éditeur"
+msgid "This script is a custom type."
+msgstr "Ce script est un type personnalisé."
+
msgid "Open Script:"
msgstr "Ouvrir le script :"
@@ -10463,6 +10486,9 @@ msgstr "Redimensionner une tuile"
msgid "Remove tile"
msgstr "Retirer la tuile"
+msgid "Create tile alternatives"
+msgstr "Créer des tuiles alternatives"
+
msgid "Create tiles in non-transparent texture regions"
msgstr "Créer des tuiles dans les régions de textures non transparentes"
@@ -10485,9 +10511,23 @@ msgstr "Sélectionner tuiles."
msgid "No tiles selected."
msgstr "Aucune tuiles sélectionnées."
+msgid "Create Tiles in Non-Transparent Texture Regions"
+msgstr "Créer des Tuiles dans les Régions de Textures Non Transparentes"
+
+msgid "Remove Tiles in Fully Transparent Texture Regions"
+msgstr "Retirer des Tuiles dans les Régions de Textures Non Transparentes"
+
+msgid "Create an Alternative Tile"
+msgstr "Créer une Tuile Alternative"
+
msgid "Create a Tile"
msgstr "Créer une Tuile"
+msgid "Auto Create Tiles in Non-Transparent Texture Regions?"
+msgstr ""
+"Création Automatique de tuiles dans les Régions de Textures Non "
+"Transparentes ?"
+
msgid ""
"The atlas's texture was modified.\n"
"Would you like to automatically create tiles in the atlas?"
@@ -10504,6 +10544,24 @@ msgstr "Non"
msgid "Add a new atlas source"
msgstr "Ajouter une nouvelle source d'atlas"
+msgid "Open Atlas Merging Tool"
+msgstr "Ouvrir l'outil de fusion d'Atlas"
+
+msgid ""
+"No TileSet source selected. Select or create a TileSet source.\n"
+"You can create a new source by using the Add button on the left or by "
+"dropping a tileset texture onto the source list."
+msgstr ""
+"Aucune source d'Ensemble de Tuiles sélectionnée. Sélectionnez ou créez une "
+"source d'Ensemble de Tuiles.\n"
+"Vous pouvez créer une nouvelle source en utilisant le bouton Créer sur la "
+"gauche ou en glissant une texture d'Ensemble de Tuiles sur la liste des "
+"sources."
+
+msgid "Add new patterns in the TileMap editing mode."
+msgstr ""
+"Ajouter des nouveaux motifs dans le mode édition de l'Ensemble de Tuiles."
+
msgid "Add a Scene Tile"
msgstr "Ajouter une tuile de scène"
@@ -10516,6 +10574,13 @@ msgstr "Filtrer les propriétés :"
msgid "TileSet"
msgstr "TileSet"
+msgid ""
+"No VCS plugins are available in the project. Install a VCS plugin to use VCS "
+"integration features."
+msgstr ""
+"Aucune extension VCS disponible pour le projet. Installez une extension VCS "
+"pour utiliser les fonctionnalités d'intégration VCS."
+
msgid "Error"
msgstr "Erreur"
@@ -10549,6 +10614,9 @@ msgstr "Voulez-vous retirer la branche %s ?"
msgid "Do you want to remove the %s remote?"
msgstr "Voulez-vous vraiment retirer le dépôt distant %s ?"
+msgid "Existing VCS metadata files will be overwritten."
+msgstr "Les fichiers de métadonnées VCS existants seront écrasés."
+
msgid "Apply"
msgstr "Appliquer"
@@ -10712,12 +10780,18 @@ msgstr "Supprimer le port d'entrée"
msgid "Remove Output Port"
msgstr "Supprimer le port de sortie"
+msgid "Set Comment Node Title"
+msgstr "Définir le Titre du Noeud Commentaire"
+
msgid "Set Input Default Port"
msgstr "Définir le port d'entrée par défaut"
msgid "Add Node to Visual Shader"
msgstr "Ajouter un nœud au Visual Shader"
+msgid "Remove Varying from Visual Shader: %s"
+msgstr "Retirer Varying du Visual Shader : %s"
+
msgid "Node(s) Moved"
msgstr "Nœud(s) déplacé(s)"
@@ -10748,6 +10822,9 @@ msgstr "Ajouter un nœud"
msgid "Create Shader Node"
msgstr "Créer un nœud Shader"
+msgid "Delete Shader Varying"
+msgstr "Supprimer Shader Varying"
+
msgid "Color function."
msgstr "Fonction de coloration."
@@ -10872,6 +10949,14 @@ msgstr "'%s' paramètre d'entrée pour le mode de shader light."
msgid "'%s' input parameter for vertex shader mode."
msgstr "'%s' paramètre d'entrée pour le mode de shader vertex."
+msgid ""
+"A node for help to multiply a position input vector by rotation using "
+"specific axis. Intended to work with emitters."
+msgstr ""
+"Un noeud pour aider à multiplier un vecteur d'entrée de position par une "
+"rotation utilisant un axe spécifique. Destiné à fonctionner avec des "
+"émetteurs."
+
msgid "Returns the absolute value of the parameter."
msgstr "Renvoie la valeur absolue du paramètre."
@@ -11032,6 +11117,12 @@ msgstr "Renvoie la tangente hyperbolique du paramètre."
msgid "Finds the truncated value of the parameter."
msgstr "Recherche la valeur tronquée du paramètre."
+msgid "Sums two floating-point scalars."
+msgstr "Somme de deux scalaires à virgule flottante."
+
+msgid "Sums two unsigned integer scalars."
+msgstr "Somme de deux scalaires entiers non signés."
+
msgid "Converts screen UV to a SDF."
msgstr "Convertir l'écran UV en SDF."
@@ -12239,6 +12330,13 @@ msgstr "Exporter la scène vers un fichier glTF 2.0"
msgid "Path to Blender installation is valid."
msgstr "Le chemin d'accès vers l'installation de Blender est valide."
+msgid ""
+"Disables Blender '.blend' files import for this project. Can be re-enabled in "
+"Project Settings."
+msgstr ""
+"Désactive l'importation de fichiers Blender '.blend' pour ce projet. Peut-"
+"être réactivé dans les préférences du projet."
+
msgid "Next Plane"
msgstr "Plan suivant"
@@ -12327,6 +12425,12 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Donnez une ressource MeshLibrary à cette GridMap pour utiliser ses maillages."
+msgid "Determining optimal atlas size"
+msgstr "Détermine la taille optimale de l'atlas"
+
+msgid "Optimizing acceleration structure"
+msgstr "Optimise la structure d'accélération"
+
msgid "Begin Bake"
msgstr "Commencer le précalcul"
@@ -12390,13 +12494,51 @@ msgstr "Compte"
msgid "Network Profiler"
msgstr "Profileur réseau"
+msgid "Select a replicator node in order to pick a property to add to it."
+msgstr ""
+"Choisir un noeud réplicateur afin de sélectionner une propriété à lui ajouter."
+
msgid "Not possible to add a new property to synchronize without a root."
msgstr ""
"Impossible d'ajouter une nouvelle propriété pour synchroniser sans racine."
+msgid "Property is already being synchronized."
+msgstr "Cette propriété est déjà en voie de synchronisation."
+
+msgid "Add property to synchronizer"
+msgstr "Ajouter propriété au synchroniseur"
+
+msgid "Pick a node to synchronize:"
+msgstr "Choisir un noeud à synchroniser :"
+
+msgid "Add property to sync..."
+msgstr "Ajouter une propriété pour synchroniser..."
+
+msgid "Spawn"
+msgstr "Point d'apparition"
+
+msgid ""
+"Add properties using the buttons above or\n"
+"drag them them from the inspector and drop them here."
+msgstr ""
+"Ajouter des propriétés utilisant les boutons ci-haut ou\n"
+"traînez-les de l'inspecteur et laissez-les tomber ici."
+
+msgid "The MultiplayerSynchronizer needs a root path."
+msgstr "Le MultiplayerSynchronizer nécessite un chemin racine."
+
+msgid ""
+"Each MultiplayerSynchronizer can have no more than 64 watched properties."
+msgstr ""
+"Chaque MultiplayerSynchronizer ne peut pas avoir plus de 64 propriétés "
+"surveillées."
+
msgid "Delete Property?"
msgstr "Supprimer la propriété ?"
+msgid "Property of this type not supported."
+msgstr "Ce type de propriété n'est pas supporté."
+
msgid "A NavigationMesh resource must be set or created for this node to work."
msgstr ""
"Une ressource de type NavigationMesh doit être définie ou créée pour que ce "
@@ -13458,6 +13600,14 @@ msgstr ""
"disponible lorsque cette scène fut chargée."
msgid ""
+"Data from the original node is kept as a placeholder until this type of node "
+"is available again. It can hence be safely re-saved without risk of data loss."
+msgstr ""
+"Les données du noeud original sont gardées en tant que remplacement jusqu'à "
+"ce que ce type de noeud soit à nouveau disponible. Elles peuvent alors être "
+"réenregistrées sans risque de pertes de données."
+
+msgid ""
"Setting node name '%s' to be unique within scene for '%s', but it's already "
"claimed by '%s'.\n"
"'%s' is no longer set as having a unique name."
@@ -13483,6 +13633,13 @@ msgstr ""
"suppression ou de changements majeurs dans les versions futures."
msgid ""
+"ShaderGlobalsOverride is not active because another node of the same type is "
+"in the scene."
+msgstr ""
+"ShaderGlobalOverride n'est pas actif, car autre noeud du même type est "
+"présent dans la scène."
+
+msgid ""
"Very low timer wait times (< 0.05 seconds) may behave in significantly "
"different ways depending on the rendered or physics frame rate.\n"
"Consider using a script's process loop instead of relying on a Timer for very "
@@ -13500,6 +13657,12 @@ msgstr ""
"La taille de la fenêtre d'affichage doit être supérieure ou égale à 2 pixels "
"dans les deux sens pour que le rendu soit possible."
+msgid "Version %d of BMFont is not supported (should be 3)."
+msgstr "Version %d de BMFont n'est pas supportée (devrait être 3)."
+
+msgid "Can't load font texture: %s."
+msgstr "Ne peut charger la texture de la police de caractère : %s."
+
msgid "Unsupported BMFont texture format."
msgstr "Format de texture BMFont non pris en charge."
@@ -13511,6 +13674,23 @@ msgstr ""
"paramètres.\n"
"Choisissez un autre nom."
+msgid "This parameter type does not support the '%s' qualifier."
+msgstr "Ce type de paramètre ne supporte pas le qualificatif '%s'."
+
+msgid ""
+"Global parameter '%s' does not exist.\n"
+"Create it in the Project Settings."
+msgstr ""
+"Paramètre global '%s' n'existe pas.\n"
+"Créez-le dans les réglages du projet."
+
+msgid ""
+"Global parameter '%s' has an incompatible type for this kind of node.\n"
+"Change it in the Project Settings."
+msgstr ""
+"Le paramètre global '%s' a un type incompatible pour cette sorte de noeud.\n"
+"Changez-le dans les réglages du projet."
+
msgid ""
"The sampler port is connected but not used. Consider changing the source to "
"'SamplerPort'."
@@ -13625,6 +13805,9 @@ msgstr "Méthode '%s' doit être du type de retour '%s'."
msgid "Expected a '{' to begin function."
msgstr "Attendait un '{' pour commencer une méthode."
+msgid "Expected at least one '%s' statement in a non-void function."
+msgstr "Attendait au moins une déclaration '%s' dans une méthode non void."
+
msgid "Expected a '%s'."
msgstr "Un '%s' est attendu."
diff --git a/editor/translations/editor/id.po b/editor/translations/editor/id.po
index 632913504d..6be4e32dc5 100644
--- a/editor/translations/editor/id.po
+++ b/editor/translations/editor/id.po
@@ -51,13 +51,14 @@
# Septian Ganendra Savero Kurniawan <septgsk@outlook.com>, 2023.
# Septian Ganendra Savero Kurniawan <mail@init.id>, 2023.
# GID <ghavind12345@gmail.com>, 2023.
+# Luqman Firmansyah <luqm4n.firm4n@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-08 13:52+0000\n"
-"Last-Translator: GID <ghavind12345@gmail.com>\n"
+"PO-Revision-Date: 2023-09-05 08:33+0000\n"
+"Last-Translator: EngageIndo <engageindo@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -65,7 +66,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Batal disetel"
@@ -163,6 +164,9 @@ msgstr "Kembali, Sony Select, Xbox Kembali, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Panduan, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Mulai, Xbox Menu, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Stik Kiri, Sony L3, Xbox L/LS"
@@ -1196,6 +1200,9 @@ msgstr "Nomor Baris:"
msgid "%d replaced."
msgstr "%d telah diganti."
+msgid "No match"
+msgstr "Tidak ada kecocokan"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d cocok"
@@ -3032,6 +3039,9 @@ msgstr "Kesalahan saat mem-parsing file '%s'."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "File adegan '%s' tampaknya tidak valid/rusak."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "File '%s' hilang atau salah satu dependensinya."
+
msgid "Error while loading file '%s'."
msgstr "Kesalahan saat memuat file '%s'."
@@ -3589,7 +3599,7 @@ msgid "Mobile"
msgstr "Mobile"
msgid "Compatibility"
-msgstr "Kompatibilitas"
+msgstr "Kecocokan"
msgid "Changing the renderer requires restarting the editor."
msgstr "Mengubah perender memerlukan restart ulang editor."
@@ -4110,7 +4120,7 @@ msgid "Cannot create file \"%s\"."
msgstr "Tidak dapat membuat file \"%s\"."
msgid "Failed to export project files."
-msgstr "Tidak dapat ekspor berkas proyek"
+msgstr "Tidak dapat ekspor berkas proyek."
msgid "Can't open file for writing at path \"%s\"."
msgstr "Tidak dapat membuka file untuk menulis di path \"%s\"."
@@ -9907,6 +9917,27 @@ msgstr ""
"Anda dapat menambahkan tipe kustom atau mengimpor tipe dengan itemnya dari "
"tema lain."
+msgid "Remove All Color Items"
+msgstr "Hapus Semua Warna Item"
+
+msgid "Rename Item"
+msgstr "Ganti Nama Item"
+
+msgid "Remove All Constant Items"
+msgstr "Hapus Semua Item Konstanta"
+
+msgid "Remove All Font Items"
+msgstr "Hapus Semua Item Font"
+
+msgid "Remove All Font Size Items"
+msgstr "Hapus Semua Item Ukuran Font"
+
+msgid "Remove All Icon Items"
+msgstr "Hapus Semua Item Ikon"
+
+msgid "Remove All StyleBox Items"
+msgstr "Hapus Semua Item StyleBox"
+
msgid ""
"This theme type is empty.\n"
"Add more items to it manually or by importing from another theme."
@@ -9915,6 +9946,30 @@ msgstr ""
"Tambahkan lebih banyak item ke dalamnya secara manual atau dengan mengimpor "
"dari tema lain."
+msgid "Remove Theme Item"
+msgstr "Hapus Item Tema"
+
+msgid "Add Theme Type"
+msgstr "Tambah Tipe Tema"
+
+msgid "Create Theme Item"
+msgstr "Buat Item Tema"
+
+msgid "Remove Theme Type"
+msgstr "Hapus Tipe Tema"
+
+msgid "Remove Data Type Items From Theme"
+msgstr "Hapus Item Tipe Data dari Tema"
+
+msgid "Remove Class Items From Theme"
+msgstr "Hapus Item Kelas dari Tema"
+
+msgid "Remove Custom Items From Theme"
+msgstr "Hapus Item Kustom dari Tema"
+
+msgid "Remove All Items From Theme"
+msgstr "Hapus Semua Item dari Tema"
+
msgid "Add Color Item"
msgstr "Tambah Item Warna"
@@ -9924,6 +9979,9 @@ msgstr "Tambah Item Konstan"
msgid "Add Font Item"
msgstr "Tambah Item Fonta"
+msgid "Add Font Size Item"
+msgstr "Tambah Item Ukuran Font"
+
msgid "Add Icon Item"
msgstr "Tambah Item Ikon"
@@ -9964,6 +10022,18 @@ msgstr ""
"Sematkan StyleBox ini sebagai gaya utama. Mengedit propertinya akan "
"memperbarui properti yang sama di semua StyleBox lain dari jenis ini."
+msgid "Override All Default Theme Items"
+msgstr "Timpa Semua Item Tema Bawaan"
+
+msgid "Set Font Size Item in Theme"
+msgstr "Set Ukuran Font di Tema"
+
+msgid "Set Icon Item in Theme"
+msgstr "Set Icon Item di Tema"
+
+msgid "Add a type from a list of available types or create a new one."
+msgstr "Tambahkan sebuah tipe dari daftar tipe yang ada atau buat yang baru."
+
msgid "Base Type"
msgstr "Tipe Dasar"
@@ -10011,7 +10081,7 @@ msgid "Named Separator"
msgstr "Pemisah yang diberi nama"
msgid "Submenu"
-msgstr "Submenu"
+msgstr "Menu Tambahan"
msgid "Subitem 1"
msgstr "Sub menu 1"
@@ -10053,6 +10123,42 @@ msgstr ""
msgid "Reload the scene to reflect its most actual state."
msgstr "Muat ulang skena untuk mencerminkan keadaannya yang paling aktual."
+msgid "Merge TileSetAtlasSource"
+msgstr "Menggabungkan TileSetAtlasSource"
+
+msgid "%s (ID: %d)"
+msgstr "%s (ID: %d)"
+
+msgid "Merge (Keep original Atlases)"
+msgstr "Menggabungkan (Simpan Atlas asli)"
+
+msgid "Next Line After Column"
+msgstr "Baris Berikutnya Setelah Kolom"
+
+msgid ""
+"Source: %d\n"
+"Atlas coordinates: %s\n"
+"Alternative: 0"
+msgstr ""
+"Sumber: %d\n"
+" Koordinat Atlas: %s\n"
+" Alternatif: 0"
+
+msgid ""
+"Source: %d\n"
+"Atlas coordinates: %s\n"
+"Alternative: %d"
+msgstr ""
+"Sumber: %d\n"
+" Koordinat Atlas: %s\n"
+" Alternatif: 0"
+
+msgid "No atlas source with a valid texture selected."
+msgstr "Tidak ada sumber atlas dengan tekstur valid yang dipilih."
+
+msgid "Edit points tool"
+msgstr "Edit point tool"
+
msgid "Rotate Right"
msgstr "Putar ke kanan"
@@ -10065,24 +10171,159 @@ msgstr "Balik secara Horizontal"
msgid "Flip Vertically"
msgstr "Balik secara Vertikal"
+msgid "No terrains"
+msgstr "Tidak ada lahan"
+
+msgid "No terrain"
+msgstr "Tidak ada lahan"
+
+msgid "No Texture Atlas Source (ID: %d)"
+msgstr "Sumber Atlas Tanpa Tekstur (ID: %d)"
+
+msgid "Scene Collection Source (ID: %d)"
+msgstr "Scene Sumber Koleksi (ID: %d)"
+
+msgid "Unknown Type Source (ID: %d)"
+msgstr "Sumber Jenis Tidak Diketahui (ID: %d)"
+
+msgid "Index: %d"
+msgstr "Indeks:%d"
+
+msgid "Tile with Invalid Scene"
+msgstr "Petak dengan Adegan tidak valid"
+
+msgid "Delete tiles"
+msgstr "Hapus Petak"
+
+msgid "Drawing Rect:"
+msgstr "Menggambar Persegi:"
+
+msgid "Change selection"
+msgstr "Ubah seleksi"
+
+msgid "Move tiles"
+msgstr "Geser Petak"
+
+msgid "Shift: Draw line."
+msgstr "Shift: Menggambar garis."
+
+msgid "Shift+Ctrl: Draw rectangle."
+msgstr "Shift+Ctrl: Menggambar Persegi."
+
+msgid "Bucket"
+msgstr "Keranjang"
+
+msgid "Eraser"
+msgstr "Penghapus"
+
msgid "Tiles"
-msgstr "Ubin"
+msgstr "Petak"
+
+msgid "Patterns"
+msgstr "Pola"
+
+msgid "Drag and drop or paste a TileMap selection here to store a pattern."
+msgstr ""
+"Seret dan lepas atau tempel pilihan TileMap ke sini untuk menyimpan pola."
+
+msgid "Matches Corners and Sides"
+msgstr "Cocokkan Sudut dan Sisi"
+
+msgid "Terrain Set %d (%s)"
+msgstr "Set Terrain %d (%s)"
+
+msgid "Terrains"
+msgstr "Lahan"
+
+msgid "Select Previous Tile Map Layer"
+msgstr "Pilih Layer Tile Map Sebelumnya"
+
+msgid "Highlight Selected TileMap Layer"
+msgstr "Sorot Layer TileMap Terpilih"
+
+msgid "Toggle grid visibility."
+msgstr "Tampilkan kisi."
+
+msgid "Delete All Invalid Tile Proxies"
+msgstr "Hapus Semua Proksi Petak yang Tidak Valid"
+
+msgid "Delete All Tile Proxies"
+msgstr "Hapus Semua Proksi Petak"
+
+msgid "Tile Proxies Management"
+msgstr "Manajemen Proksi Petak"
+
+msgid ""
+"Selected tile:\n"
+"Source: %d\n"
+"Atlas coordinates: %s\n"
+"Alternative: %d"
+msgstr ""
+"Petak terpilih:\n"
+"Sumber: %d\n"
+"Koordinat Atlas: %s\n"
+"Alternatif: %d"
msgid "Rendering"
-msgstr "Rendering"
+msgstr "Proses membuat gambar"
msgid "Modulate"
msgstr "Memodulasi"
+msgid "Create tiles in non-transparent texture regions"
+msgstr "Buat petak di region tekstur non-transparan"
+
+msgid "Remove tiles in fully transparent texture regions"
+msgstr "Hapus petak di region tekstur dengan transparansi penuh"
+
+msgid "Select tiles."
+msgstr "Pilih Petak."
+
+msgid "No tiles selected."
+msgstr "Tidak ada petak yang dipilih."
+
+msgid "Create Tiles in Non-Transparent Texture Regions"
+msgstr "Buat petak di region tekstur non-transparan"
+
+msgid "Remove Tiles in Fully Transparent Texture Regions"
+msgstr "Hapus petak di region tekstur dengan transparansi penuh"
+
+msgid "Auto Create Tiles in Non-Transparent Texture Regions?"
+msgstr "Buat Petak Otomatis di Region Tekstur Non-Transparan?"
+
msgid "Yes"
msgstr "Ya"
+msgid "Add a new atlas source"
+msgstr "Tambah sumber atlas baru"
+
+msgid "Open Atlas Merging Tool"
+msgstr "Buka Alat Penggabung Atlas"
+
+msgid ""
+"No TileSet source selected. Select or create a TileSet source.\n"
+"You can create a new source by using the Add button on the left or by "
+"dropping a tileset texture onto the source list."
+msgstr ""
+"Tidak ada sumber TileSet terpilih. Pilih atau buat sumber TileSet.\n"
+"Anda dapat membuat sebuah sumber baru menggunakan tombol Tambah pada sebelah "
+"kiri atau dengan melepas tekstur TileSet pada daftar sumber."
+
+msgid "Add new patterns in the TileMap editing mode."
+msgstr "Tambah pola baru di Mode Sunting TileMap."
+
msgid "TileSet"
msgstr "TileSet"
msgid "Error"
msgstr "Error"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+"Pengaturan remote kosong. Fitur VCS yang menggunakan jaringan mungkin akan "
+"tidak berfungsi."
+
msgid "Commit"
msgstr "Komit"
@@ -10092,6 +10333,9 @@ msgstr "Tanggal:"
msgid "Subtitle:"
msgstr "Subjudul:"
+msgid "Existing VCS metadata files will be overwritten."
+msgstr "Berkas metadata VCS yang sudah ada akan ditimpa."
+
msgid "Apply"
msgstr "Terapkan"
@@ -10116,6 +10360,10 @@ msgstr "Deteksi perubahan baru"
msgid "Discard all changes"
msgstr "Buang semua perubahan"
+msgid "This operation is IRREVERSIBLE. Your changes will be deleted FOREVER."
+msgstr ""
+"Operasi ini TIDAK DAPAT DIKEMBALIKAN. Perubahan anda akan hilang SELAMANYA."
+
msgid "Unstage all changes"
msgstr "Buang semua perubahan"
@@ -10158,6 +10406,12 @@ msgstr "Nama Remot"
msgid "Remote URL"
msgstr "URL Remot"
+msgid "Pull"
+msgstr "Pull"
+
+msgid "Push"
+msgstr "Push"
+
msgid "Modified"
msgstr "Dimodifikasi"
@@ -10170,6 +10424,9 @@ msgstr "Dihapus"
msgid "Typechange"
msgstr "Jenis perubahan"
+msgid "View file diffs before committing them to the latest version"
+msgstr "Tampilkan perbedaan file sebelum melakukan commit ke versi terbaru"
+
msgid "Split"
msgstr "Pisahkan"
@@ -10219,7 +10476,7 @@ msgid "Boolean"
msgstr "Boolean"
msgid "Sampler"
-msgstr "Sampler"
+msgstr "Contoh Acak"
msgid "[default]"
msgstr "[bawaan]"
@@ -10260,6 +10517,12 @@ msgstr "Cahaya"
msgid "Process"
msgstr "Proses"
+msgid "Sky"
+msgstr "Langit"
+
+msgid "Fog"
+msgstr "Kabut"
+
msgid "Add Node"
msgstr "Tambahkan Node"
@@ -11748,6 +12011,9 @@ msgstr "Tidak dapat menemukan contoh APK untuk ekspor: \"%s\""
msgid "Invalid Identifier:"
msgstr "Identifier tidak valid:"
+msgid "Xcode Build"
+msgstr "Membangun Xcode"
+
msgid "Identifier is missing."
msgstr "Kurang identifier."
diff --git a/editor/translations/editor/it.po b/editor/translations/editor/it.po
index ba3644e0c1..1f22b09fa3 100644
--- a/editor/translations/editor/it.po
+++ b/editor/translations/editor/it.po
@@ -87,13 +87,14 @@
# GumaD3v <matteo.gugliuzza08@gmail.com>, 2023.
# Adelina G <adelinadoncheva.georgieva@mail.polimi.it>, 2023.
# Francesco <martefrinbell@gmail.com>, 2023.
+# Edoardo Barolo <velteyn@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-20 08:03+0000\n"
-"Last-Translator: Francesco <martefrinbell@gmail.com>\n"
+"PO-Revision-Date: 2023-08-30 14:58+0000\n"
+"Last-Translator: Edoardo Barolo <velteyn@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -101,7 +102,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Non impostato"
@@ -199,6 +200,9 @@ msgstr "Indietro, Select Sony, Back Xbox, - Nintendo"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Guida, PS Sony, Home Xbox"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, MenuXbox , Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Levetta sinistra, L3 Sony, L/LS Xbox"
@@ -1053,6 +1057,9 @@ msgstr "Scala la selezione"
msgid "Scale From Cursor"
msgstr "Scala a partire dal cursore"
+msgid "Make Easing Selection"
+msgstr "Effettua selezione di facilitazione"
+
msgid "Duplicate Selection"
msgstr "Duplica la selezione"
@@ -1118,6 +1125,18 @@ msgid "Sine"
msgstr "Seno"
msgctxt "Transition Type"
+msgid "Quint"
+msgstr "Quintupletta"
+
+msgctxt "Transition Type"
+msgid "Quart"
+msgstr "Quartetto"
+
+msgctxt "Transition Type"
+msgid "Quad"
+msgstr "Quadrupla"
+
+msgctxt "Transition Type"
msgid "Elastic"
msgstr "Elastico"
@@ -2193,6 +2212,14 @@ msgstr ""
"Supporto alla tecnologia di font intelligente SIL Graphite (supportata solo "
"dal server di testo avanzato)."
+msgid ""
+"Multi-channel signed distance field font rendering support using msdfgen "
+"library (pre-rendered MSDF fonts can be used even if this option disabled)."
+msgstr ""
+"Supporto per il rendering di font multicanale con campo di distanza "
+"sottoscritto utilizzando la libreria msdfgen (i font MSDF pre-renderizzati "
+"possono essere utilizzati anche se questa opzione è disabilitata)."
+
msgid "General Features:"
msgstr "Funzionalità generali:"
@@ -2449,6 +2476,10 @@ msgstr "Importa risorse di tipo: %s"
msgid "No return value."
msgstr "Nessun valore di ritorno."
+msgid "This value is an integer composed as a bitmask of the following flags."
+msgstr ""
+"Questo valore è un intero composto da una maschera di bit dei seguenti flag."
+
msgid "Deprecated"
msgstr "Deprecato"
@@ -2718,6 +2749,20 @@ msgstr "Aggiungi elemento all'array di proprietà col prefisso %s."
msgid "Remove element %d from property array with prefix %s."
msgstr "Rimuovi elemento %d dall'array di proprietà col prefisso %s."
+msgid "Move element %d to position %d in property array with prefix %s."
+msgstr ""
+"Sposta l'elemento %d nella posizione %d dell'array di proprietà con prefisso "
+"%s."
+
+msgid "Clear property array with prefix %s."
+msgstr "Cancella l'array di proprietà con il prefisso %s."
+
+msgid "Resize property array with prefix %s."
+msgstr "Ridimensiona la proprietà array con il prefisso %s."
+
+msgid "Element %d: %s%d*"
+msgstr "Element0 %d: %s%d*"
+
msgid "Move Up"
msgstr "Sposta su"
@@ -3724,6 +3769,9 @@ msgstr "Modifica i nomi dei livelli"
msgid "<empty>"
msgstr "<vuoto>"
+msgid "Temporary Euler may be changed implicitly!"
+msgstr "L'Eulero temporaneo può essere modificato implicitamente!"
+
msgid ""
"Temporary Euler will not be stored in the object with the original value. "
"Instead, it will be stored as Quaternion with irreversible conversion.\n"
@@ -3959,6 +4007,9 @@ msgstr "Joystick 4 verso su"
msgid "Joystick 4 Down"
msgstr "Joystick 4 verso giù"
+msgid "Unicode"
+msgstr "Unicode"
+
msgid "Joypad Axis %d %s (%s)"
msgstr "Asse %d del joypad %s (%s)"
@@ -4449,6 +4500,20 @@ msgstr "Gestisci i modelli di esportazione"
msgid "Export With Debug"
msgstr "Esporta Con Debug"
+msgid ""
+"Canceling this dialog will disable the FBX importer.\n"
+"You can re-enable it in the Project Settings under Filesystem > Import > FBX "
+"> Enabled.\n"
+"\n"
+"The editor will restart as importers are registered when the editor starts."
+msgstr ""
+"Chiudendo questa finestra di dialogo si disattiva l'importatore FBX.\n"
+"È possibile riabilitarlo nelle Impostazioni progetto in Filesystem > "
+"Importazione > FBX > Abilitato.\n"
+"\n"
+"L'editor si riavvia perché gli importatori sono registrati all'avvio "
+"dell'editor."
+
msgid "Path to FBX2glTF executable is empty."
msgstr "Il percorso per FBX2glTF è vuoto."
@@ -4551,6 +4616,12 @@ msgstr ""
"I seguenti file o/e cartelle vanno in conflitto con i file o/e cartelle nel "
"percorso di destinazione '%s':"
+msgid "Do you wish to overwrite them or rename the copied files?"
+msgstr "Si desidera sovrascrivere o rinominare i file copiati?"
+
+msgid "Do you wish to overwrite them or rename the moved files?"
+msgstr "Si desidera sovrascrivere o rinominare i file spostati?"
+
msgid "Duplicating file:"
msgstr "Duplica file:"
@@ -4784,6 +4855,13 @@ msgstr "Impossibile salvare file con il nome vuoto."
msgid "Cannot save file with a name starting with a dot."
msgstr "Impossibile salvare file il cui nome inizia con un punto."
+msgid ""
+"File \"%s\" already exists.\n"
+"Do you want to overwrite it?"
+msgstr ""
+"Il file \"%s\" esiste già.\n"
+"Si desidera sovrascriverlo?"
+
msgid "Select This Folder"
msgstr "Seleziona questa cartella"
@@ -5116,6 +5194,16 @@ msgstr ""
"di battiti dall'anteprima) per assicurarsi che la ripetizione funzioni "
"correttamente."
+msgid "Bar Beats:"
+msgstr "Barra Battiti:"
+
+msgid ""
+"Configure the Beats Per Bar. This used for music-aware transitions between "
+"AudioStreams."
+msgstr ""
+"Configura i battiti per battuta. Si usa per le transizioni sensibili alla "
+"musica tra gli AudioStream."
+
msgid "Music Playback:"
msgstr "Riproduzione musicale:"
@@ -5227,6 +5315,9 @@ msgstr ""
msgid "Dynamically rendered TrueType/OpenType font"
msgstr "Font TrueType/OpenType renderizzato dinamicamente"
+msgid "Prerendered multichannel(+true) signed distance field"
+msgstr "Campo distanza sottoscritta(+true) multicanale prerenderizzata"
+
msgid "Can't load font texture:"
msgstr "Impossibile caricare texture del font:"
@@ -5346,6 +5437,9 @@ msgstr "Il file esistente con lo stesso nome verrà rimpiazzato."
msgid "Will create new file"
msgstr "Creerà un nuovo file"
+msgid "Already External"
+msgstr "Già esterno"
+
msgid ""
"This material already references an external file, no action will be taken.\n"
"Disable the external property for it to be extracted again."
@@ -6537,6 +6631,9 @@ msgstr "File ZIP dei contenuti"
msgid "Audio Preview Play/Pause"
msgstr "Riproduci/Pausa Anteprima Audio"
+msgid "Clear mappings in current group."
+msgstr "Pulisci le mappature nel gruppo corrente."
+
msgid "Preview"
msgstr "Anteprima"
@@ -6763,6 +6860,12 @@ msgstr "Clicca per cambiare il perno di rotazione dell'oggetto."
msgid "Pan Mode"
msgstr "Modalità di Pan"
+msgid ""
+"You can also use Pan View shortcut (Space by default) to pan in any mode."
+msgstr ""
+"È inoltre possibile utilizzare la Vista Pan (Spazio per impostazione "
+"predefinita) per eseguire una panoramica in qualsiasi modalità."
+
msgid "Ruler Mode"
msgstr "Modalità Righello"
@@ -7000,6 +7103,12 @@ msgstr "Questo nodo è il figlio di un Control normale."
msgid "Use anchors and the rectangle for positioning."
msgstr "Utilizza le ancore e il rettangolo per il posizionamento."
+msgid "Collapse positioning hint."
+msgstr "Suggerimento per il posizionamento dello strumento di compressione."
+
+msgid "Expand positioning hint."
+msgstr "Suggerimento per il posizionamento dello strumento di espansione."
+
msgid "Container Default"
msgstr "Container predefinito"
@@ -7057,6 +7166,33 @@ msgstr "Lato Destro"
msgid "Full Rect"
msgstr "Rettangolo Completo"
+msgid ""
+"Enable to also set the Expand flag.\n"
+"Disable to only set Shrink/Fill flags."
+msgstr ""
+"Attivare per impostare anche il flag Espandi.\n"
+"Disattivare per impostare solo i flag Restringimento/riempimento."
+
+msgid "Some parents of the selected nodes do not support the Expand flag."
+msgstr "Alcuni parenti dei nodi selezionati non supportano il flag Espandi."
+
+msgid "Align with Expand"
+msgstr "Allinea con l'espansione"
+
+msgid "Change Anchors, Offsets, Grow Direction"
+msgstr "Modificare le ancore, gli offset e la direzione di espansione"
+
+msgid "Change Anchors, Offsets (Keep Ratio)"
+msgstr "Cambiare le ancore, gli offset (Mantieni il Rapporto)"
+
+msgid "Adjust anchors and offsets to match the current rect size."
+msgstr ""
+"Regola le ancore e gli offset per adattarli alla dimensione corrente del "
+"rettangolo."
+
+msgid "Sizing settings for children of a Container node."
+msgstr "Impostazioni di dimensionamento per i figli di un nodo Contenitore."
+
msgid "Horizontal alignment"
msgstr "Allineamento orizzontale"
@@ -7240,6 +7376,9 @@ msgstr "Dimensione: %s"
msgid "Type: %s"
msgstr "Tipo: %s"
+msgid "Dimensions: %d × %d"
+msgstr "Dimensioni: %d × %d"
+
msgid "Overrides (%d)"
msgstr "Sovrascrive (%d)"
@@ -7476,6 +7615,9 @@ msgstr ""
msgid "No editor scene root found."
msgstr "Nessuna radice della scena dell'editor trovata."
+msgid "Lightmap data is not local to the scene."
+msgstr "I dati della Lightmap non sono locali alla scena."
+
msgid "Bake Lightmaps"
msgstr "Preprocessa Lightmaps"
diff --git a/editor/translations/editor/ko.po b/editor/translations/editor/ko.po
index c7e744d999..900c043d81 100644
--- a/editor/translations/editor/ko.po
+++ b/editor/translations/editor/ko.po
@@ -52,13 +52,14 @@
# asdfer-1234 <sh__lv@naver.com>, 2023.
# Overdue - <kaameo12@gmail.com>, 2023.
# 최시현 <hihyun1234@ajou.ac.kr>, 2023.
+# Zinccccc <velocity2772@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-31 18:39+0000\n"
-"Last-Translator: 이정희 <daemul72@gmail.com>\n"
+"PO-Revision-Date: 2023-09-05 08:33+0000\n"
+"Last-Translator: Zinccccc <velocity2772@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/godot/"
"ko/>\n"
"Language: ko\n"
@@ -66,7 +67,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "설정 해제"
@@ -164,6 +165,9 @@ msgstr "뒤로, 소니 셀렉트, 엑스박스 뒤로, 닌텐도 -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "가이드, 소니 PS, Xbox 홈"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "시작, Xbox 메뉴, 닌텐도 +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "왼쪽 스틱, 소니 L3, Xbox L/LS"
@@ -1193,6 +1197,9 @@ msgstr "행 번호:"
msgid "%d replaced."
msgstr "%d개를 찾아 바꿨습니다."
+msgid "No match"
+msgstr "일치하는 것 없음"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d개 일치"
@@ -3015,6 +3022,9 @@ msgstr "'%s' 구문 분석 중 오류가 발생했습니다."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "씬 파일 '%s'이(가) 잘못되었거나 손상된 것 같습니다."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "파일 '%s' 또는 이것의 종속 항목이 누락되어 있습니다."
+
msgid "Error while loading file '%s'."
msgstr "파일 '%s'을(를) 불러오는 중 오류가 발생했습니다."
@@ -11550,15 +11560,117 @@ msgid ""
"Returns the result of bitwise XOR (a ^ b) operation on the unsigned integer."
msgstr "부호 없는 정수에 대한 비트 단위 XOR (a ^ b) 연산의 결과값을 반환합니다."
+msgid "Divides two floating-point scalars."
+msgstr "두 부동소수점 스칼라를 나눕니다."
+
+msgid "Divides two integer scalars."
+msgstr "두 정수 스칼라를 나눕니다."
+
+msgid "Divides two unsigned integer scalars."
+msgstr "두 부호 없는 정수 스칼라를 나눕니다."
+
+msgid "Multiplies two floating-point scalars."
+msgstr "두 부동소수점 스칼라를 곱합니다."
+
+msgid "Multiplies two integer scalars."
+msgstr "두 정수 스칼라를 곱합니다."
+
+msgid "Multiplies two unsigned integer scalars."
+msgstr "부호 없는 두 스칼라를 곱합니다."
+
+msgid "Returns the remainder of the two floating-point scalars."
+msgstr "두 부동소수점 스칼라의 나머지를 반환합니다."
+
+msgid "Returns the remainder of the two integer scalars."
+msgstr "두 정수 스칼라의 나머지를 반환합니다."
+
+msgid "Returns the remainder of the two unsigned integer scalars."
+msgstr "두 부호 없는 정수 스칼라의 나머지를 반환합니다."
+
+msgid "Subtracts two floating-point scalars."
+msgstr "두 부동소수점 스칼라를 뺍니다."
+
+msgid "Subtracts two integer scalars."
+msgstr "두 정수 스칼라를 뺍니다."
+
+msgid "Subtracts two unsigned integer scalars."
+msgstr "두 부호 없는 정수 스칼라를 뺍니다."
+
+msgid "Scalar floating-point constant."
+msgstr "부동소수점 스칼라 상수."
+
+msgid "Scalar integer constant."
+msgstr "정수 스칼라 상수."
+
+msgid "Scalar unsigned integer constant."
+msgstr "부호 없는 정수 스칼라 상수."
+
+msgid "Scalar floating-point parameter."
+msgstr "부동소수점 스칼라 매개변수."
+
+msgid "Scalar integer parameter."
+msgstr "정수 스칼라 매개변수."
+
+msgid "Scalar unsigned integer parameter."
+msgstr "부호 없는 정수 스칼라 매개변수."
+
msgid "Converts screen UV to a SDF."
msgstr "스크린 UV를 SDF로 변환합니다."
+msgid "Casts a ray against the screen SDF and returns the distance travelled."
+msgstr "스크린 SDF에 광선을 발사하고 이동 거리를 반환합니다."
+
+msgid "Converts a SDF to screen UV."
+msgstr "SDF를 스크린 UV로 변환합니다."
+
+msgid "Performs a SDF texture lookup."
+msgstr "SDF 텍스처 룩업을 수행합니다."
+
+msgid "Performs a SDF normal texture lookup."
+msgstr "SDF 노멀 텍스처 룩업을 수행합니다."
+
+msgid "Function to be applied on texture coordinates."
+msgstr "텍스처 좌표에 적용할 함수입니다."
+
msgid "Perform the cubic texture lookup."
msgstr "세제곱 텍스처 룩업을 수행합니다."
+msgid "Perform the curve texture lookup."
+msgstr "커브 텍스처 룩업을 수행합니다."
+
+msgid "Perform the three components curve texture lookup."
+msgstr "세제곱 커브 텍스처 룩업을 수행합니다."
+
+msgid "Perform the 2D texture lookup."
+msgstr "2D 텍스처 룩업을 수행합니다."
+
+msgid "Perform the 2D-array texture lookup."
+msgstr "2D 배열 텍스처 룩업을 수행합니다."
+
+msgid "Perform the 3D texture lookup."
+msgstr "3D 텍스처 룩업을 수행합니다."
+
+msgid "Cubic texture parameter lookup."
+msgstr "세제곱 텍스처 매개변수 룩업."
+
+msgid "2D texture parameter lookup."
+msgstr "2D 텍스처 매개변수 룩업."
+
+msgid "2D texture parameter lookup with triplanar."
+msgstr "Triplanar가 적용된 2D 텍스처 매개변수 룩업 ."
+
+msgid "2D array of textures parameter lookup."
+msgstr "2D 텍스처 배열 매개변수 룩업."
+
+msgid "3D texture parameter lookup."
+msgstr "3D 텍스처 매개변수 룩업."
+
msgid "Transform function."
msgstr "변형 함수."
+msgid "Transform operator."
+msgstr "변형 연산자."
+
msgid ""
"Calculate the outer product of a pair of vectors.\n"
"\n"
@@ -11593,6 +11705,12 @@ msgstr "변형의 전치를 계산합니다."
msgid "Sums two transforms."
msgstr "두 개의 Transform을 더합니다."
+msgid "Divides two transforms."
+msgstr "두 변형을 나눕니다."
+
+msgid "Multiplies two transforms."
+msgstr "두 변형을 곱합니다."
+
msgid "Subtracts two transforms."
msgstr "두 Transform을 뺍니다."
@@ -11602,12 +11720,39 @@ msgstr "변형에 벡터를 곱합니다."
msgid "Transform constant."
msgstr "변형 상수."
+msgid "Transform parameter."
+msgstr "변형 매개변수."
+
msgid "Vector function."
msgstr "벡터 함수."
msgid "Vector operator."
msgstr "벡터 연산자."
+msgid "Composes vector from scalars."
+msgstr "스칼라로 벡터를 합성합니다."
+
+msgid "Decomposes vector to scalars."
+msgstr "벡터를 스칼라로 분해합니다."
+
+msgid "Composes 2D vector from two scalars."
+msgstr "두 개의 스칼라로 2D 벡터를 합성합니다."
+
+msgid "Decomposes 2D vector to two scalars."
+msgstr "2D 벡터를 두 개의 스칼라로 분해합니다."
+
+msgid "Composes 3D vector from three scalars."
+msgstr "세 개의 스칼라로 3D 벡터를 합성합니다."
+
+msgid "Decomposes 3D vector to three scalars."
+msgstr "3D 벡터를 세 개의 스칼라로 분해합니다."
+
+msgid "Composes 4D vector from four scalars."
+msgstr "네 개의 스칼라로 4D 벡터를 합성합니다."
+
+msgid "Decomposes 4D vector to four scalars."
+msgstr "4D 벡터를 네 개의 스칼라로 분해합니다."
+
msgid "Calculates the cross product of two vectors."
msgstr "두 벡터의 벡터곱 값을 계산합니다."
@@ -11718,6 +11863,69 @@ msgid ""
"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."
msgstr "(프래그먼트/라이트 모드만 가능) (벡터) 'x'와 'y'의 절대 미분 값의 합."
+msgid "Adds 2D vector to 2D vector."
+msgstr "2D 벡터에 2D 벡터를 더합니다."
+
+msgid "Adds 3D vector to 3D vector."
+msgstr "3D 벡터에 3D 벡터를 더합니다."
+
+msgid "Adds 4D vector to 4D vector."
+msgstr "4D 벡터에 4D 벡터를 더합니다."
+
+msgid "Divides 2D vector by 2D vector."
+msgstr "2D 벡터를 2D 벡터로 나눕니다."
+
+msgid "Divides 3D vector by 3D vector."
+msgstr "3D 벡터를 3D 벡터로 나눕니다."
+
+msgid "Divides 4D vector by 4D vector."
+msgstr "4D 벡터를 4D 벡터로 나눕니다."
+
+msgid "Multiplies 2D vector by 2D vector."
+msgstr "2D 벡터를 2D 벡터로 곱합니다."
+
+msgid "Multiplies 3D vector by 3D vector."
+msgstr "3D 벡터를 3D 벡터로 곱합니다."
+
+msgid "Multiplies 4D vector by 4D vector."
+msgstr "4D 벡터를 4D 벡터로 곱합니다."
+
+msgid "Returns the remainder of the two 2D vectors."
+msgstr "두 2D 벡터의 나머지를 반환합니다."
+
+msgid "Returns the remainder of the two 3D vectors."
+msgstr "두 3D 벡터의 나머지를 반환합니다."
+
+msgid "Returns the remainder of the two 4D vectors."
+msgstr "두 4D 벡터의 나머지를 반환합니다."
+
+msgid "Subtracts 2D vector from 2D vector."
+msgstr "2D 벡터에서 2D 벡터를 뺍니다."
+
+msgid "Subtracts 3D vector from 3D vector."
+msgstr "3D 벡터에서 3D 벡터를 뺍니다."
+
+msgid "Subtracts 4D vector from 4D vector."
+msgstr "4D 벡터에서 4D 벡터를 뺍니다."
+
+msgid "2D vector constant."
+msgstr "2D 벡터 상수."
+
+msgid "2D vector parameter."
+msgstr "2D 벡터 매개변수."
+
+msgid "3D vector constant."
+msgstr "3D 벡터 상수."
+
+msgid "3D vector parameter."
+msgstr "3D 벡터 매개변수."
+
+msgid "4D vector constant."
+msgstr "4D 벡터 상수."
+
+msgid "4D vector parameter."
+msgstr "4D 벡터 매개변수."
+
msgid ""
"A rectangular area with a description string for better graph organization."
msgstr ""
@@ -11950,6 +12158,9 @@ msgstr "버전 컨트롤 메타데이터:"
msgid "Git"
msgstr "Git"
+msgid "This project uses features unsupported by the current build:"
+msgstr "이 프로젝트는 현재 빌드에서는 지원하지 않는 기능을 사용합니다:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "오류: 프로젝트가 파일시스템에서 누락되었습니다."
@@ -12090,6 +12301,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"경고: 이 프로젝트는 Godot %s에서 최종 편집되었습니다.\n"
+"프로젝트를 열면 Godot %s로 변경됩니다.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12230,6 +12450,27 @@ msgstr "프로젝트 콘텐츠도 삭제 (되돌릴 수 없습니다!)"
msgid "Convert Full Project"
msgstr "프로젝트 전체 변환"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"이것은 씬이나 리소스, 스크립트를 포함한 프로젝트 전체를 Godot 3에서 Godot 4에 "
+"맞게 변환합니다.\n"
+"\n"
+"이것은 가장 힘이 덜 드는 선택지이지만, 그렇다고 해도 프로젝트가 아무 문제 없"
+"이 작동하지는 않을 것이며 여전히 여러 것들을 수동으로 조정해주어야 할 것입니"
+"다.\n"
+"\n"
+"중요: 반드시 변환하기 전에 프로젝트를 어딘가에 백업해 두세요. 변환을 수행하면 "
+"이전 버전의 Godot에서 프로젝트를 열지 못하게 됩니다."
+
msgid "Can't run project"
msgstr "프로젝트를 실행할 수 없습니다"
@@ -13571,6 +13812,11 @@ msgstr ""
"\"최소 SDK\"는 \"Gradle 빌드 사용\"가 활성화된 경우에만 오버라이드할 수 있습니"
"다."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Gradle Build\" is enabled."
+msgstr ""
+"\"대상 SDK\"는 \"Use Gradle Build\"가 활성화된 경우에만 재정의할 수 있습니다."
+
msgid "Select device from the list"
msgstr "목록에서 기기 선택"
@@ -13872,33 +14118,111 @@ msgstr "프로젝트 시작 중..."
msgid "Can't get filesystem access."
msgstr "파일시스템 접근 권한을 얻지 못했습니다."
+msgid "Invalid Info.plist, no exe name."
+msgstr "잘못된 Info.plist. exe 이름이 없습니다."
+
+msgid "Invalid Info.plist, can't load."
+msgstr "잘못된 Info.plist. 로드할 수 없습니다."
+
msgid "Failed to create \"%s\" subfolder."
msgstr "서브폴더 \"%s\"을(를) 만들 수 없습니다."
+msgid "Invalid binary format."
+msgstr "잘못된 바이너리 포맷."
+
+msgid "Failed to process nested resources."
+msgstr "중첩된 리소스를 처리하지 못했습니다."
+
+msgid "Failed to get CodeResources hash."
+msgstr "CodeResources 해시를 가져오지 못했습니다."
+
+msgid "Invalid entitlements file."
+msgstr "잘못된 자격 파일."
+
+msgid "Invalid executable file."
+msgstr "잘못된 실행 파일."
+
msgid "Invalid bundle identifier:"
msgstr "잘못된 bundle 식별자:"
+msgid "Apple Team ID is required for notarization."
+msgstr "공증을 위해서 Apple Team ID가 필요합니다."
+
+msgid "Installer signing identity is required for App Store distribution."
+msgstr "App Store 배포를 위해 설치 프로그램 서명 ID가 필요합니다."
+
+msgid "Code signing is required for App Store distribution."
+msgstr "App Store 배포를 위해 코드 서명이 필요합니다."
+
+msgid "Code signing is required for notarization."
+msgstr "공증을 위해서 코드 서명이 필요합니다."
+
+msgid "Apple ID password not specified."
+msgstr "Apple ID 비밀번호가 지정되지 않았습니다."
+
+msgid "App Store Connect issuer ID name not specified."
+msgstr "App Store Connect 발급자 ID 이름이 지정되지 않았습니다."
+
+msgid "Icon Creation"
+msgstr "아이콘 생성"
+
msgid "Could not open icon file \"%s\"."
msgstr "아이콘 파일 \"%s\"를 열 수 없습니다."
+msgid "Notarization"
+msgstr "공증"
+
+msgid "Could not start rcodesign executable."
+msgstr "rcodesign 실행 파일을 시작할 수 없습니다."
+
msgid "Could not start xcrun executable."
msgstr "xcrun 실행 파일을 시작하지 못했습니다."
msgid "Cannot sign file %s."
msgstr "파일 %s를 서명할 수 없습니다."
+msgid "PKG Creation"
+msgstr "PKG 생성"
+
+msgid "Could not start productbuild executable."
+msgstr "productbuild 실행 파일을 시작할 수 없었습니다."
+
+msgid "DMG Creation"
+msgstr "DMG 생성"
+
msgid "Could not start hdiutil executable."
msgstr "hdiutil 실행 파일을 시작할 수 없었습니다."
+msgid "Creating app bundle"
+msgstr "앱 번들 생성"
+
msgid "Could not find template app to export: \"%s\"."
msgstr "내보낼 템플릿 앱을 찾을 수 없음: \"%s\"."
msgid "Invalid export format."
msgstr "잘못된 내보내기 템플릿입니다."
+msgid "Could not create directory: \"%s\"."
+msgstr "디렉토리를 만들 수 없음: \"%s\"."
+
+msgid "Could not create directory \"%s\"."
+msgstr "디렉토리를 만들 수 없음: \"%s\"."
+
msgid "Could not created symlink \"%s\" -> \"%s\"."
msgstr "바로가기 파일 \"%s\" -> \"%s\"를 만들 수 없습니다."
+msgid "Could not open \"%s\"."
+msgstr "\"%s\"를 열 수 없습니다."
+
+msgid "Entitlements Modified"
+msgstr "수정된 자격"
+
+msgid "Could not create entitlements file."
+msgstr "자격 파일을 만들 수 없습니다."
+
+msgid "Could not create helper entitlements file."
+msgstr "도우미 자격 파일을 생성할 수 없습니다."
+
msgid "Invalid package short name."
msgstr "잘못된 패키지 단축 이름."
@@ -14625,6 +14949,13 @@ msgstr ""
"서 지원될 예정입니다."
msgid ""
+"The \"Remote Path\" property must point to a valid Node3D or Node3D-derived "
+"node to work."
+msgstr ""
+"\"원격 경로(Remote Path)\" 속성이 작동하려면 유효한 Node3D 또는 Node3D 파생 노"
+"드를 가리켜야 합니다."
+
+msgid ""
"This node cannot interact with other objects unless a Shape3D is assigned."
msgstr ""
"이 노드는 Shape3D를 할당하지 않는 이상 다른 오브젝트와 상호작용하지 못합니다."
@@ -14677,10 +15008,34 @@ msgstr ""
"를 구워서 GI를 활성화하세요."
msgid ""
+"To have any visible effect, WorldEnvironment requires its \"Environment\" "
+"property to contain an Environment, its \"Camera Attributes\" property to "
+"contain a CameraAttributes resource, or both."
+msgstr ""
+"가시적인 효과를 가지려면 WorldEnvironment에는 환경을 포함하는 \"Environment\" "
+"속성, CameraAttributes 리소스를 포함하는 \"Camera Attributes\" 속성, 또는 두 "
+"가지 모두가 필요합니다."
+
+msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instantiated "
"scenes)."
msgstr "씬(또는 인스턴스된 씬들마다) 당 WorldEnvironment는 하나만 허용됩니다."
+msgid "XRCamera3D must have an XROrigin3D node as its parent."
+msgstr "XRCamera3D의 부모 노드는 반드시 XROrigin3D이어야 합니다."
+
+msgid "XRController3D must have an XROrigin3D node as its parent."
+msgstr "XRController3D의 부모 노드는 반드시 XROrigin3D 노드여야 합니다."
+
+msgid "No tracker name is set."
+msgstr "트래커 이름이 설정되지 않았습니다."
+
+msgid "No pose is set."
+msgstr "설정된 포즈가 없습니다."
+
+msgid "XROrigin3D requires an XRCamera3D child node."
+msgstr "XROrigin3D는 자식으로 XRCamera3D 노드가 필요합니다."
+
msgid "On BlendTree node '%s', animation not found: '%s'"
msgstr "BlendTree 노드 '%s'에서, 애니메이션을 찾을 수 없음: '%s'"
@@ -14990,6 +15345,9 @@ msgstr "미리보기에 잘못된 소스."
msgid "Invalid source for shader."
msgstr "셰이더에 잘못된 소스."
+msgid "Invalid operator for that type."
+msgstr "해당 타입에 잘못된 연산자."
+
msgid "Default Color"
msgstr "기본 색"
@@ -15002,6 +15360,18 @@ msgstr "반복"
msgid "Invalid comparison function for that type."
msgstr "해당 타입에 잘못된 비교 함수."
+msgid "2D Mode"
+msgstr "2D 모드"
+
+msgid "Use All Surfaces"
+msgstr "모든 서피스 사용"
+
+msgid "Surface Index"
+msgstr "서피스 인덱스"
+
+msgid "Varyings cannot be passed for the '%s' parameter."
+msgstr "Varying은 '%s' 매개변수로 전달될 수 없습니다."
+
msgid "Invalid arguments for the built-in function: \"%s(%s)\"."
msgstr "내장 함수에 잘못된 인수가 들어감: \"%s(%s)\"."
@@ -15014,6 +15384,18 @@ msgstr "상수 표현식이 와야 합니다."
msgid "Varying may not be assigned in the '%s' function."
msgstr "Varying은 '%s' 함수에서 할당되지 않을 수 있습니다."
+msgid ""
+"Varying with '%s' data type may only be assigned in the 'fragment' function."
+msgstr ""
+"'%s' 데이터 타입으로 변경하는 것은 'fragment' 함수에서만 할당될 수 있습니다."
+
+msgid ""
+"Varyings which assigned in 'vertex' function may not be reassigned in "
+"'fragment' or 'light'."
+msgstr ""
+"'vertex' 함수에서 할당된 Varying은 'fragment' 또는 'light'에서 재할당되지 않"
+"을 수 있습니다."
+
msgid "Assignment to function."
msgstr "함수에 대입할 수 없습니다."
@@ -15365,6 +15747,13 @@ msgstr "인스턴스 인덱스는 음수일 수 없습니다."
msgid "Allowed instance uniform indices must be within [0..%d] range."
msgstr "허용되는 인스턴스 균일 인덱스는 [0..%d] 범위 내에 있어야 합니다."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"'hint_normal_roughness_texture'은 Forward+ 백엔드를 사용할 때만 사용할 수 있습"
+"니다."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "'hint_normal_roughness_texture'는 '%s' 셰이더에서 지원되지 않습니다."
diff --git a/editor/translations/editor/pl.po b/editor/translations/editor/pl.po
index 83a7530456..b8613617b9 100644
--- a/editor/translations/editor/pl.po
+++ b/editor/translations/editor/pl.po
@@ -85,7 +85,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-17 11:10+0000\n"
+"PO-Revision-Date: 2023-08-24 14:56+0000\n"
"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/godot/"
"pl/>\n"
@@ -193,6 +193,9 @@ msgstr "Powrót, Sony wybór, Xbox powrót, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Przewodnik, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, Xbox Menu, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Lewy drążek, Sony L3, Xbox L/LS"
@@ -1231,6 +1234,9 @@ msgstr "Numer linii:"
msgid "%d replaced."
msgstr "%d zamieniono."
+msgid "No match"
+msgstr "Brak dopasowania"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d dopasowanie"
@@ -3067,6 +3073,9 @@ msgstr "Błąd podczas analizy pliku \"%s\"."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "Plik sceny \"%s\" wydaje się być nieprawidłowy/uszkodzony."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "Brakuje pliku \"%s\" lub jednej z jego zależności."
+
msgid "Error while loading file '%s'."
msgstr "Błąd podczas wczytywania pliku \"%s\"."
@@ -4010,7 +4019,7 @@ msgid "Shortcuts"
msgstr "Skróty"
msgid "Binding"
-msgstr "Wiązanie"
+msgstr "Przypisanie"
msgid "Left Stick Left, Joystick 0 Left"
msgstr "Lewa gałka w lewo, Joystick 0 w lewo"
@@ -12406,6 +12415,14 @@ msgstr "Metadane kontroli wersji:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr "Ten projekt był ostatnio edytowany w innej wersji Godota: "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr ""
+"Ten projekt używa funkcjonalności niewspieranych przez aktualnie używaną "
+"wersję:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "Błąd: Projekt nieobecny w systemie plików."
@@ -12549,6 +12566,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Ostrzeżenie: Ten projekt był ostatnio edytowany w wersji Godota %s. Otwarcie "
+"zmieni go do wersji do Godota %s.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12690,6 +12716,28 @@ msgstr "Usuń także projekt (nie można cofnąć!)"
msgid "Convert Full Project"
msgstr "Przekonwertuj cały projekt"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"Ta opcja spowoduje pełną konwersję projektu, aktualizację scen, zasobów i "
+"skryptów z Godota 3 do Godota 4.\n"
+"\n"
+"Miej na uwadze, że konwersja zostanie przeprowadzona w najlepszy możliwy "
+"sposób, dzięki czemu aktualizacja będzie łatwiejsza, ale nadal będą wymagane "
+"ręczne poprawki.\n"
+"\n"
+"WAŻNE: Upewnij się, że przed konwersją zrobiłeś kopię zapasową swojego "
+"projektu, ponieważ przeprowadzenie konwersji uniemożliwi jego otwarcie w "
+"starszych wersjach Godota."
+
msgid "Can't run project"
msgstr "Nie można uruchomić projektu"
@@ -16625,6 +16673,13 @@ msgstr "Indeks instancji nie może być ujemny."
msgid "Allowed instance uniform indices must be within [0..%d] range."
msgstr "Dozwolone indeksy uniformów instancji muszą być w zakresie [0..%d]."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"'hint_normal_roughness_texture' jest dostępne tylko, gdy użyty jest backend "
+"Przedni+."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "'hint_normal_roughness_texture' nie jest obsługiwany w shaderach '%s'."
diff --git a/editor/translations/editor/pt_BR.po b/editor/translations/editor/pt_BR.po
index fc30a9cd98..f572a053bc 100644
--- a/editor/translations/editor/pt_BR.po
+++ b/editor/translations/editor/pt_BR.po
@@ -167,13 +167,15 @@
# Daniel Mucciolo <danielviannapsi@gmail.com>, 2023.
# Guilherme <gui.rugai.freire@gmail.com>, 2023.
# Glayson Olivieri <glayson.murollo75@gmail.com>, 2023.
+# Jose Delvani <del.cidrak@gmail.com>, 2023.
+# Romildo Franco <rtfranco@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2023-07-27 22:43+0000\n"
-"Last-Translator: Joel Gomes da Silva <joelgomes1994@hotmail.com>\n"
+"PO-Revision-Date: 2023-09-08 06:21+0000\n"
+"Last-Translator: Romildo Franco <rtfranco@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/godot-"
"engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -181,7 +183,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Restaurar"
@@ -279,6 +281,9 @@ msgstr "Voltar, Sony Select, Xbox Back, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Menu, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Iniciar, Menu Xbox, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Alavanca Esquerda, Sony L3, Xbox L/LS"
@@ -1283,6 +1288,9 @@ msgstr "Gerar Animação"
msgid "3D Pos/Rot/Scl Track:"
msgstr "Faixa de Pos/Rot/Esc 3D:"
+msgid "Blendshape Track:"
+msgstr "Trilha Blendshape:"
+
msgid "Value Track:"
msgstr "Faixa de valor:"
@@ -1313,6 +1321,9 @@ msgstr "Número da Linha:"
msgid "%d replaced."
msgstr "%d substituído."
+msgid "No match"
+msgstr "Sem correspondência"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d correspondência"
@@ -1572,6 +1583,15 @@ msgstr ""
msgid "Toggle Visibility"
msgstr "Alternar Visibilidade"
+msgid "Updating assets on target device:"
+msgstr "Atualizando recursos no dispositivo alvo:"
+
+msgid "Syncing headers"
+msgstr "Sincronizando cabeçalhos"
+
+msgid "Getting remote file system"
+msgstr "Obtendo o sistema de arquivos remoto"
+
msgid "Decompressing remote file system"
msgstr "Descompactando o sistema de arquivos remoto"
@@ -3143,6 +3163,9 @@ msgstr "Erro ao processar o arquivo '%s'."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "O arquivo de cena '%s' parece ser inválido/corrompido."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "Arquivo '%s' ausente ou uma de suas dependências."
+
msgid "Error while loading file '%s'."
msgstr "Erro ao carregar o arquivo '%s'."
@@ -3378,9 +3401,7 @@ msgstr ""
"falhou."
msgid "Unable to find script field for addon plugin at: '%s'."
-msgstr ""
-"Não foi possível encontrar o campo de script para o plugin em: 'res://addons/"
-"%s'."
+msgstr "Não foi possível encontrar o campo script para o plugin em: '%s'."
msgid "Unable to load addon script from path: '%s'."
msgstr ""
@@ -3430,6 +3451,9 @@ msgstr "Limpar Cenas Recentes"
msgid "There is no defined scene to run."
msgstr "Não há cena definida para rodar."
+msgid "%s - Godot Engine"
+msgstr "%s - Godot Engine"
+
msgid ""
"No main scene has ever been defined, select one?\n"
"You can change it later in \"Project Settings\" under the 'application' "
@@ -3995,6 +4019,9 @@ msgstr "Traduções da String (quantidade: %d)"
msgid "Add Translation"
msgstr "Adicionar Tradução"
+msgid "Lock/Unlock Component Ratio"
+msgstr "Relação de componente de bloqueio/desbloqueio"
+
msgid ""
"The selected resource (%s) does not match any type expected for this property "
"(%s)."
@@ -4060,6 +4087,12 @@ msgstr ""
"Não foi possível executar o script do editor, você esqueceu de substituir o "
"método '_run'?"
+msgid "Undo: %s"
+msgstr "Desfazer: %s"
+
+msgid "Redo: %s"
+msgstr "Refazer: %s"
+
msgid "Edit Built-in Action"
msgstr "Editar Ação Integrada"
@@ -4147,6 +4180,12 @@ msgstr "Joystick 4 Acima"
msgid "Joystick 4 Down"
msgstr "Joystick 4 Abaixo"
+msgid "or"
+msgstr "Ou"
+
+msgid "Unicode"
+msgstr "Padrão Unicode"
+
msgid "Joypad Axis %d %s (%s)"
msgstr "Eixo do Joypad %d %s (%s)"
@@ -4485,6 +4524,9 @@ msgstr "Recursos para exportar:"
msgid "Delete preset '%s'?"
msgstr "Apagar predefinição '%s'?"
+msgid "(Inherited)"
+msgstr "(Herdado)"
+
msgid "%s Export"
msgstr "Exportar %s"
@@ -4820,6 +4862,12 @@ msgstr "Expandir Pasta"
msgid "Expand Hierarchy"
msgstr "Expandir Hierarquia"
+msgid "Collapse Hierarchy"
+msgstr "Recolher hierarquia"
+
+msgid "Move/Duplicate To..."
+msgstr "Mover/Duplicar para..."
+
msgid "Add to Favorites"
msgstr "Adicionar aos Favoritos"
@@ -7426,12 +7474,27 @@ msgstr "Criar Pontos de Emissão a Partir do Nó"
msgid "Load Curve Preset"
msgstr "Carregar Definição de Curva"
+msgid "Add Curve Point"
+msgstr "Adicionar ponto de curva"
+
msgid "Remove Curve Point"
msgstr "Remover Ponto da Curva"
msgid "Modify Curve Point"
msgstr "Modificar Ponto da Curva"
+msgid "Modify Curve Point's Tangents"
+msgstr "Modifique as tangentes do ponto da curva"
+
+msgid "Modify Curve Point's Left Tangent"
+msgstr "Modifique a tangente esquerda do ponto da curva"
+
+msgid "Modify Curve Point's Right Tangent"
+msgstr "Modificar a tangente direita do ponto da curva"
+
+msgid "Toggle Linear Curve Point's Tangent"
+msgstr "Alternar a tangente do ponto da curva linear"
+
msgid "Hold Shift to edit tangents individually"
msgstr "Segure Shift para editar tangentes individualmente"
@@ -7516,6 +7579,16 @@ msgstr ""
"Quando esta opção está ativa, malhas e polígonos de navegação serão visíveis "
"durante o projeto em execução."
+msgid "Visible Avoidance"
+msgstr "Evitação Visível"
+
+msgid ""
+"When this option is enabled, avoidance objects shapes, radius and velocities "
+"will be visible in the running project."
+msgstr ""
+"Quando esta opção estiver habilitada, as formas, raios e velocidades dos "
+"objetos evitados ficarão visíveis no projeto em execução."
+
msgid "Synchronize Scene Changes"
msgstr "Sincronizar Mudanças de Cena"
@@ -7569,6 +7642,9 @@ msgstr "Tamanho: %s"
msgid "Type: %s"
msgstr "Tipo: %s"
+msgid "Dimensions: %d × %d"
+msgstr "Dimensões: %d × %d"
+
msgid "Overrides (%d)"
msgstr "Sobrescreveu (%d)"
@@ -7774,6 +7850,9 @@ msgstr "Gradiente Editado"
msgid "Reverse/mirror gradient."
msgstr "Gradiente reverso/espelhado."
+msgid "Move GradientTexture2D Fill Point"
+msgstr "Mover ponto de preenchimento GradientTexture2D"
+
msgid "Swap GradientTexture2D Fill Points"
msgstr "Trocar Pontos de Preenchimento do GradientTexture2D"
@@ -8119,6 +8198,9 @@ msgstr "Definir start_position"
msgid "Set end_position"
msgstr "Definir end_position"
+msgid "Set NavigationObstacle3D Vertices"
+msgstr "Definir Vértices do NavigationObstacle3D"
+
msgid "Edit Vertices"
msgstr "Editar Vértices"
@@ -8224,6 +8306,9 @@ msgstr "Tamanho: %s (%.1fMP)\n"
msgid "Objects: %d\n"
msgstr "Objetos: %d\n"
+msgid "Primitives: %d\n"
+msgstr "Primitivos: %d\n"
+
msgid "Draw Calls: %d"
msgstr "Chamadas de Desenho: %d"
@@ -9222,6 +9307,9 @@ msgstr "Ir para o documento editado anteriormente."
msgid "Go to next edited document."
msgstr "Ir para o próximo documento editado."
+msgid "Make the script editor floating."
+msgstr "Torne o editor de script flutuante."
+
msgid "Discard"
msgstr "Descartar"
@@ -9337,6 +9425,9 @@ msgstr "Mostrar Todas as Linhas"
msgid "Evaluate Selection"
msgstr "Avaliar Seleção"
+msgid "Toggle Word Wrap"
+msgstr "Alternar Quebra de Linha"
+
msgid "Trim Trailing Whitespace"
msgstr "Apagar Espaços em Branco"
@@ -9412,6 +9503,9 @@ msgstr "Abrir Arquivo no Inspetor"
msgid "Close File"
msgstr "Fechar Arquivo"
+msgid "Make the shader editor floating."
+msgstr "Torne o editor de shader flutuante."
+
msgid "No valid shader stages found."
msgstr "Não foi encontrado estágio válido de Shader."
@@ -9639,6 +9733,9 @@ msgstr "Filtrar Animações"
msgid "Delete Animation"
msgstr "Excluir Animação"
+msgid "This resource does not have any animations."
+msgstr "Este recurso não possui animações."
+
msgid "Animation Frames:"
msgstr "Quadros da Animação:"
@@ -9678,6 +9775,9 @@ msgstr "Selecionar Quadros"
msgid "Frame Order"
msgstr "Ordem do Quadro"
+msgid "As Selected"
+msgstr "Conforme selecionado"
+
msgid "By Row"
msgstr "Por Linha"
@@ -9696,6 +9796,24 @@ msgstr "Direita para Esquerda, Baixo para Cima"
msgid "By Column"
msgstr "Por Coluna"
+msgid "Top to Bottom, Left to Right"
+msgstr "De cima para baixo, da esquerda para a direita"
+
+msgid "Top to Bottom, Right to Left"
+msgstr "De cima para baixo, da direita para a esquerda"
+
+msgid "Bottom to Top, Left to Right"
+msgstr "De baixo para cima, da esquerda para a direita"
+
+msgid "Bottom to Top, Right to Left"
+msgstr "De baixo para cima, da direita para a esquerda"
+
+msgid "Select None"
+msgstr "Selecionar nenhum"
+
+msgid "Toggle Settings Panel"
+msgstr "Alternar painel de configurações"
+
msgid "Horizontal"
msgstr "Horizontal"
@@ -10407,6 +10525,12 @@ msgstr "Inverter Horizontalmente"
msgid "Flip Vertically"
msgstr "Inverter Verticalmente"
+msgid "Disable Snap"
+msgstr "Desativar Snap"
+
+msgid "Half-Pixel Snap"
+msgstr "Snap de meio pixel"
+
msgid "Painting Tiles Property"
msgstr "Propriedade Pintar Tiles"
@@ -10452,6 +10576,9 @@ msgstr "Tile com Cena Inválida"
msgid "Delete tiles"
msgstr "Excluir tiles"
+msgid "Drawing Rect:"
+msgstr "Desenho Reto:"
+
msgid "Change selection"
msgstr "Mudar Seleção"
@@ -10512,6 +10639,13 @@ msgstr "Espalhamento:"
msgid "Tiles"
msgstr "Tiles"
+msgid ""
+"This TileMap's TileSet has no source configured. Go to the TileSet bottom tab "
+"to add one."
+msgstr ""
+"O TileSet deste TileMap não tem fonte configurada. Vá para a guia inferior "
+"TileSet para adicionar um."
+
msgid "Sort sources"
msgstr "Classificar fontes"
@@ -10587,6 +10721,13 @@ msgstr "Alterna visibilidade da grade."
msgid "Automatically Replace Tiles with Proxies"
msgstr "Automaticamente Substitui Tiles com Proxies"
+msgid ""
+"The edited TileMap node has no TileSet resource.\n"
+"Create or load a TileSet resource in the Tile Set property in the inspector."
+msgstr ""
+"O nó TileMap editado não possui recurso TileSet.\n"
+"Crie ou carregue um recurso TileSet na propriedade Tile Set no inspetor."
+
msgid "Remove Tile Proxies"
msgstr "Remover Proxies de Tile"
@@ -10804,6 +10945,15 @@ msgstr "Abrir Ferramenta de Mesclagem do Atlas"
msgid "Manage Tile Proxies"
msgstr "Gerenciar Proxies Tile"
+msgid ""
+"No TileSet source selected. Select or create a TileSet source.\n"
+"You can create a new source by using the Add button on the left or by "
+"dropping a tileset texture onto the source list."
+msgstr ""
+"Nenhuma fonte TileSet selecionada. Selecione ou crie uma fonte TileSet.\n"
+"Você pode criar uma nova fonte usando o botão Adicionar à esquerda ou "
+"soltando uma textura de mosaico na lista de fontes."
+
msgid "Add new patterns in the TileMap editing mode."
msgstr "Adicione novos padrões no modo de edição TileMap."
@@ -12371,6 +12521,13 @@ msgstr "Controle de Versão:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr ""
+"Este projeto foi editado pela última vez em uma versão diferente do Godot: "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr "Este projeto usa recursos não suportados pela compilação atual:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "Erro: Projeto não encontrado no sistema de arquivos."
@@ -12512,6 +12669,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Aviso: Este projeto foi editado pela última vez em Godot %s. A abertura o "
+"mudará para Godot %s.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12546,6 +12712,18 @@ msgstr ""
msgid "Are you sure to run %d projects at once?"
msgstr "Tem certeza de que deseja executar %d projetos de modo simultâneo?"
+msgid "Tag name can't be empty."
+msgstr "O nome da tag não pode estar vazio."
+
+msgid "Tag name can't contain spaces."
+msgstr "O nome da tag não pode conter espaços."
+
+msgid "These characters are not allowed in tags: %s."
+msgstr "Estes caracteres não são permitidos em tags: %s."
+
+msgid "Tag name must be lowercase."
+msgstr "O nome da tag deve estar em letras minúsculas."
+
msgid "Remove %d projects from the list?"
msgstr "Remover %d projetos da lista?"
@@ -12597,6 +12775,9 @@ msgstr "Carregando, por favor aguarde..."
msgid "Last Edited"
msgstr "Última Modificação"
+msgid "Tags"
+msgstr "Tags"
+
msgid "New Project"
msgstr "Novo Projeto"
@@ -12612,6 +12793,9 @@ msgstr "Escanear Projetos"
msgid "Edit Project"
msgstr "Editar Projeto"
+msgid "Manage Tags"
+msgstr "Gerenciar tags"
+
msgid "Remove Project"
msgstr "Remover Projeto"
@@ -12636,6 +12820,27 @@ msgstr "Também deletar os conteúdos do projeto (não pode ser desfeito!)"
msgid "Convert Full Project"
msgstr "Converter Projeto Completo"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"Esta opção realizará a conversão completa do projeto, atualizando cenas, "
+"recursos e scripts do Godot 3 para funcionar no Godot 4.\n"
+"\n"
+"Observe que esta é uma conversão de melhor esforço, ou seja, facilita a "
+"atualização do projeto, mas não será aberta imediatamente e ainda exigirá "
+"ajustes manuais.\n"
+"\n"
+"IMPORTANTE: Certifique-se de fazer backup do seu projeto antes de converter, "
+"pois esta operação impossibilita a abertura em versões mais antigas do Godot."
+
msgid "Can't run project"
msgstr "Não é possível executar o projeto"
@@ -12646,9 +12851,27 @@ msgstr ""
"Você não tem nenhum projeto no momento.\n"
"Gostaria de explorar projetos de exemplos oficiais na Biblioteca de Recursos?"
+msgid "Manage Project Tags"
+msgstr "Gerenciar tags de projeto"
+
+msgid "Project Tags"
+msgstr "Tags de Projeto"
+
+msgid "Click tag to remove it from the project."
+msgstr "Clique na tag para removê-la do projeto."
+
+msgid "All Tags"
+msgstr "Todas as Tags"
+
+msgid "Click tag to add it to the project."
+msgstr "Clique na tag para adicioná-la ao projeto."
+
msgid "Create New Tag"
msgstr "Criar Nova Tag"
+msgid "Tags are capitalized automatically when displayed."
+msgstr "As tags são capitalizadas automaticamente quando exibidas."
+
msgid "Add Project Setting"
msgstr "Adicionar Configuração ao Projeto"
@@ -12838,6 +13061,9 @@ msgstr "Nome de arquivo inválido."
msgid "File already exists."
msgstr "O arquivo já existe."
+msgid "Root node valid."
+msgstr "Nó raiz válido."
+
msgid "Invalid root node name."
msgstr "Nome de nó raiz inválido."
@@ -12934,6 +13160,9 @@ msgstr "Excluir nó \"%s\" e seus filhos?"
msgid "Delete node \"%s\"?"
msgstr "Excluir o nó \"%s\"?"
+msgid "Some nodes are referenced by animation tracks."
+msgstr "Alguns nós são referenciados por faixas de animação."
+
msgid "Saving the branch as a scene requires having a scene open in the editor."
msgstr ""
"Para salvar o ramo como cena é necessário ter uma cena aberta no editor."
@@ -13093,6 +13322,9 @@ msgstr "Carregar como Substituto"
msgid "Auto Expand to Selected"
msgstr "Auto Expandir Selecionados"
+msgid "All Scene Sub-Resources"
+msgstr "Todos os sub-recursos de cena"
+
msgid "Filters"
msgstr "Filtros"
@@ -13130,6 +13362,9 @@ msgstr "Colar Nó(s)"
msgid "<Unnamed> at %s"
msgstr "<Sem nome> em %s"
+msgid "(used %d times)"
+msgstr "(usado %d vezes)"
+
msgid "Add Child Node"
msgstr "Adicionar Nó Filho"
@@ -13182,6 +13417,9 @@ msgstr ""
"toda vez que atualizar.\n"
"Volte para o painel da árvore de cena Local para melhorar o desempenho."
+msgid "Delete Related Animation Tracks"
+msgstr "Excluir faixas de animação relacionadas"
+
msgid "Clear Inheritance? (No Undo!)"
msgstr "Limpar Herança? (Irreversível!)"
@@ -13360,6 +13598,16 @@ msgstr "O nome '%s' é uma palavra-chave reservada da linguagem de shader."
msgid "Add Shader Global Parameter"
msgstr "Adicionar Parâmetro Global Shader"
+msgid "Make this panel floating in the screen %d."
+msgstr "Faça este painel flutuar na tela %d."
+
+msgid ""
+"Make this panel floating.\n"
+"Right click to open the screen selector."
+msgstr ""
+"Torne este painel flutuante.\n"
+"Clique com o botão direito para abrir o seletor de tela."
+
msgid "Select Screen"
msgstr "Selecionar tela"
@@ -13735,18 +13983,29 @@ msgstr "Por favor, selecione um MultiplayerSynchronizer primeiro."
msgid "The MultiplayerSynchronizer needs a root path."
msgstr "O MultiplayerSynchronizer precisa de um caminho raiz."
+msgid ""
+"Each MultiplayerSynchronizer can have no more than 64 watched properties."
+msgstr ""
+"Cada MultiplayerSynchronizer não pode ter mais de 64 propriedades monitoradas."
+
msgid "Set spawn property"
msgstr "Definir propriedade de geração"
msgid "Set sync property"
msgstr "Definir propriedade de sincronização"
+msgid "Set watch property"
+msgstr "Definir propriedade do relógio"
+
msgid "Delete Property?"
msgstr "Excluir Propriedade?"
msgid "Remove Property"
msgstr "Remover Propriedade"
+msgid "Property of this type not supported."
+msgstr "Propriedade deste tipo não é suportada."
+
msgid ""
"A valid NodePath must be set in the \"Spawn Path\" property in order for "
"MultiplayerSpawner to be able to spawn Nodes."
@@ -13999,6 +14258,20 @@ msgid "Could not execute on device."
msgstr "Não foi possível executar no dispositivo."
msgid ""
+"Exporting to Android is currently not supported in Godot 4 when using C#/."
+"NET. Use Godot 3 to target Android with C#/Mono instead."
+msgstr ""
+"Atualmente, a exportação para Android não é suportada no Godot 4 ao usar C#/."
+"NET. Em vez disso, use o Godot 3 para direcionar o Android com C#/Mono."
+
+msgid ""
+"If this project does not use C#, use a non-C# editor build to export the "
+"project."
+msgstr ""
+"Se este projeto não usar C#, use uma compilação de editor não C# para "
+"exportar o projeto."
+
+msgid ""
"Android build template not installed in the project. Install it from the "
"Project menu."
msgstr ""
@@ -14212,6 +14485,9 @@ msgstr "Alinhando APK..."
msgid "Could not unzip temporary unaligned APK."
msgstr "Não foi possível descompactar o APK temporário não alinhado."
+msgid "App Store Team ID not specified."
+msgstr "ID da equipe da App Store não especificada."
+
msgid "Invalid Identifier:"
msgstr "Identificador Inválido:"
@@ -14247,6 +14523,13 @@ msgstr ""
".ipa só pode ser criado no macOS. Saindo do projeto Xcode sem compilar o "
"pacote."
+msgid ""
+"Exporting to iOS is currently not supported in Godot 4 when using C#/.NET. "
+"Use Godot 3 to target iOS with C#/Mono instead."
+msgstr ""
+"A exportação para iOS atualmente não é suportada no Godot 4 ao usar C#/.NET. "
+"Em vez disso, use o Godot 3 para direcionar o iOS com C#/Mono."
+
msgid "Identifier is missing."
msgstr "Identificador está ausente."
@@ -14259,6 +14542,12 @@ msgstr "Exportar Script de Depuração"
msgid "Could not open file \"%s\"."
msgstr "Não foi possível abrir o arquivo \"%s\"."
+msgid "Debug Console Export"
+msgstr "Exportação do console de depuração"
+
+msgid "Could not create console wrapper."
+msgstr "Não foi possível criar o wrapper do console."
+
msgid "Failed to open executable file \"%s\"."
msgstr "Falha ao abrir o arquivo executável \"%s\"."
@@ -14361,6 +14650,37 @@ msgstr "Tipo de objeto desconhecido."
msgid "Invalid bundle identifier:"
msgstr "Identificador de pacote inválido:"
+msgid "App Store distribution with ad-hoc code signing is not supported."
+msgstr ""
+"A distribuição da App Store com assinatura de código ad-hoc não é suportada."
+
+msgid "Notarization with an ad-hoc signature is not supported."
+msgstr "Notarização com uma assinatura ad-hoc não é suportada."
+
+msgid "Apple Team ID is required for App Store distribution."
+msgstr "O Apple Team ID é necessário para distribuição na App Store."
+
+msgid "Apple Team ID is required for notarization."
+msgstr "O Apple Team ID é necessário para reconhecimento de firma."
+
+msgid "Provisioning profile is required for App Store distribution."
+msgstr ""
+"O perfil de provisionamento é necessário para distribuição na App Store."
+
+msgid "Installer signing identity is required for App Store distribution."
+msgstr ""
+"A identidade de assinatura do instalador é necessária para distribuição na "
+"App Store."
+
+msgid "App sandbox is required for App Store distribution."
+msgstr "A sandbox do aplicativo é necessária para distribuição na App Store."
+
+msgid "Code signing is required for App Store distribution."
+msgstr "A assinatura do código é necessária para distribuição na App Store."
+
+msgid "Code signing is required for notarization."
+msgstr "A assinatura do código é necessária para reconhecimento de firma."
+
msgid ""
"Neither Apple ID name nor App Store Connect issuer ID name not specified."
msgstr ""
@@ -14383,6 +14703,36 @@ msgstr "App Store Connect API key ID não foi especificado."
msgid "App Store Connect issuer ID name not specified."
msgstr "O nome do App Store Connect issuer ID não foi especificado."
+msgid "Microphone access is enabled, but usage description is not specified."
+msgstr ""
+"O acesso ao microfone está ativado, mas a descrição de uso não é especificada."
+
+msgid "Camera access is enabled, but usage description is not specified."
+msgstr ""
+"O acesso à câmera está ativado, mas a descrição de uso não é especificada."
+
+msgid ""
+"Location information access is enabled, but usage description is not "
+"specified."
+msgstr ""
+"O acesso às informações de localização está ativado, mas a descrição de uso "
+"não está especificada."
+
+msgid "Address book access is enabled, but usage description is not specified."
+msgstr ""
+"O acesso ao catálogo de endereços está ativado, mas a descrição de uso não "
+"está especificada."
+
+msgid "Calendar access is enabled, but usage description is not specified."
+msgstr ""
+"O acesso ao calendário está ativado, mas a descrição de uso não está "
+"especificada."
+
+msgid "Photo library access is enabled, but usage description is not specified."
+msgstr ""
+"O acesso à biblioteca de fotos está ativado, mas a descrição de uso não é "
+"especificada."
+
msgid "Icon Creation"
msgstr "Criação de Ícone"
@@ -14466,6 +14816,15 @@ msgstr ""
"Links simbólicos relativos não são suportados, \"%s\" exportado pode estar "
"quebrado!"
+msgid "PKG Creation"
+msgstr "Criação PKG"
+
+msgid "Could not start productbuild executable."
+msgstr "Não foi possível iniciar o executável do productbuild."
+
+msgid "`productbuild` failed."
+msgstr "`productbuild` falhou."
+
msgid "DMG Creation"
msgstr "Criação de DMG"
@@ -14542,6 +14901,9 @@ msgstr "Criando DMG"
msgid "Code signing DMG"
msgstr "Assinatura de código DMG"
+msgid "Making PKG installer"
+msgstr "Criando o instalador do PKG"
+
msgid "Making ZIP"
msgstr "Criando ZIP"
@@ -14659,6 +15021,13 @@ msgstr "Não foi possível ler o arquivo: \"%s\"."
msgid "PWA"
msgstr "PWA"
+msgid ""
+"Exporting to Web is currently not supported in Godot 4 when using C#/.NET. "
+"Use Godot 3 to target Web with C#/Mono instead."
+msgstr ""
+"Atualmente, a exportação para a Web não é suportada no Godot 4 ao usar C#/."
+"NET. Em vez disso, use Godot 3 para direcionar a Web com C#/Mono."
+
msgid "Could not read HTML shell: \"%s\"."
msgstr "Não foi possível ler o shell HTML: \"%s\"."
@@ -14820,6 +15189,13 @@ msgstr ""
"de 'Segmentos'."
msgid ""
+"The One Way Collision property will be ignored when the collision object is "
+"an Area2D."
+msgstr ""
+"A propriedade One Way Collision será ignorada quando o objeto de colisão for "
+"um Area2D."
+
+msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape."
@@ -14870,6 +15246,13 @@ msgstr ""
"As trilhas de partículas estão disponíveis apenas ao usar o módulo de "
"renderização Avançado+ ou Mobile."
+msgid ""
+"Particle sub-emitters are not available when using the GL Compatibility "
+"rendering backend."
+msgstr ""
+"Os subemissores de partículas não estão disponíveis ao usar o back-end de "
+"renderização de compatibilidade com GL."
+
msgid "Node A and Node B must be PhysicsBody2Ds"
msgstr "O Nó A e o Nó B devem ser PhysicsBody2Ds"
@@ -15204,6 +15587,13 @@ msgstr ""
"definidos para renderização de trilhas."
msgid ""
+"Particle sub-emitters are only available when using the Forward+ or Mobile "
+"rendering backends."
+msgstr ""
+"Os subemissores de partículas estão disponíveis apenas ao usar os back-ends "
+"de renderização Forward+ ou Mobile."
+
+msgid ""
"The Bake Mask has no bits enabled, which means baking will not produce any "
"collision for this GPUParticlesCollisionSDF3D.\n"
"To resolve this, enable at least one bit in the Bake Mask property."
@@ -15557,6 +15947,10 @@ msgstr ""
msgid "Copy this constructor in a script."
msgstr "Copiar este construtor em um script."
+msgid "Enter a hex code (\"#ff0000\") or named color (\"red\")."
+msgstr ""
+"Insira um código hexadecimal (\"#ff0000\") ou uma cor nomeada (\"vermelho\")."
+
msgid ""
"Color: #%s\n"
"LMB: Apply color\n"
@@ -15573,6 +15967,9 @@ msgstr ""
"Cor: #%s\n"
"LMB: Aplica cor"
+msgid "Pick a color from the screen."
+msgstr "Escolha uma cor na tela."
+
msgid "Pick a color from the application window."
msgstr "Escolha uma cor na janela do aplicativo."
@@ -15585,6 +15982,9 @@ msgstr "Selecione o modo do seletor."
msgid "Switch between hexadecimal and code values."
msgstr "Alterne entre valores hexadecimais e de código."
+msgid "Hex code or named color"
+msgstr "Código hexadecimal ou cor nomeada"
+
msgid "Add current color as a preset."
msgstr "Adicionar cor atual como uma predefinição."
@@ -15782,6 +16182,13 @@ msgstr ""
"grandes alterações em versões futuras."
msgid ""
+"Default Environment as specified in the project setting \"rendering/"
+"environment/defaults/default_environment\" could not be loaded."
+msgstr ""
+"O ambiente padrão conforme especificado na configuração do projeto "
+"\"rendering/environment/defaults/default_environment\" não pôde ser carregado."
+
+msgid ""
"ShaderGlobalsOverride is not active because another node of the same type is "
"in the scene."
msgstr ""
@@ -15829,6 +16236,15 @@ msgid "Invalid BMFont block type."
msgstr "Tipo de bloco BMFont inválido."
msgid ""
+"An incoming node's name clashes with %s already in the scene (presumably, "
+"from a more nested instance).\n"
+"The less nested node will be renamed. Please fix and re-save the scene."
+msgstr ""
+"O nome de um nó entrante conflita com %s já na cena (presumivelmente, de uma "
+"instância mais aninhada).\n"
+"O nó menos aninhado será renomeado. Corrija e salve novamente a cena."
+
+msgid ""
"Shader keywords cannot be used as parameter names.\n"
"Choose another name."
msgstr ""
@@ -16367,6 +16783,13 @@ msgstr ""
"Índices uniformes de instância permitidos devem estar dentro do intervalo [0.."
"%d]."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"'hint_normal_roughness_texture' só está disponível ao usar o back-end "
+"Forward+."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "'hint_normal_roughness_texture' não é suportado em shaders '%s'."
diff --git a/editor/translations/editor/ru.po b/editor/translations/editor/ru.po
index bcbd4b97fe..29e3575814 100644
--- a/editor/translations/editor/ru.po
+++ b/editor/translations/editor/ru.po
@@ -101,7 +101,7 @@
# mrvladus <mrvladus@yandex.ru>, 2021.
# DΞLTΛ <craftercrafter43@gmail.com>, 2021.
# AngryPhilomel <an.aries@icloud.com>, 2021.
-# Russkikh Michail <summersay415@gmail.com>, 2022.
+# Russkikh Michail <summersay415@gmail.com>, 2022, 2023.
# Alex_Faction <creeponedead@gmail.com>, 2022.
# Максим Легостаев <dstu1914346@gmail.com>, 2022.
# dickus <dickie.dickus@yahoo.com>, 2022.
@@ -151,13 +151,15 @@
# Artem Yaroshenko <zero.maiami@gmail.com>, 2023.
# Толя Богомолов <tolya.bogomolov2004@gmail.com>, 2023.
# Quartin <fihpoile+weblateorg@yandex.ru>, 2023.
+# 0eoc <0eoc@users.noreply.hosted.weblate.org>, 2023.
+# 0que <0que@users.noreply.hosted.weblate.org>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-16 20:54+0000\n"
-"Last-Translator: Quartin <fihpoile+weblateorg@yandex.ru>\n"
+"PO-Revision-Date: 2023-09-07 02:32+0000\n"
+"Last-Translator: Russkikh Michail <summersay415@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -166,7 +168,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Не задано"
@@ -264,6 +266,9 @@ msgstr "Назад, Sony Select, Xbox Back, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Руководство, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Старт, Xbox Меню, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Левый стик, Sony L3, Xbox L/LS"
@@ -289,7 +294,7 @@ msgid "D-pad Right"
msgstr "D-pad вправо"
msgid "Xbox Share, PS5 Microphone, Nintendo Capture"
-msgstr "Xbox Share, PS5 Microphone, Nintendo Capture"
+msgstr "Xbox Share, Микрофон PS5, Nintendo Capture"
msgid "Xbox Paddle 1"
msgstr "Xbox крестовина 1"
@@ -1237,6 +1242,10 @@ msgid "Spring"
msgstr "Пружина"
msgctxt "Ease Type"
+msgid "In"
+msgstr "Вход"
+
+msgctxt "Ease Type"
msgid "Out"
msgstr "Выход"
@@ -1296,6 +1305,9 @@ msgstr "Номер строки:"
msgid "%d replaced."
msgstr "%d заменено."
+msgid "No match"
+msgstr "Не совпадает"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d совпадает"
@@ -3141,6 +3153,9 @@ msgstr "Ошибка при разборе файла '%s'."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "Файл сцены '%s' является недействительным/повреждённым."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "Не найден файл '%s' или одна из его зависимостей."
+
msgid "Error while loading file '%s'."
msgstr "Ошибка при загрузке файла '%s'."
@@ -4906,6 +4921,9 @@ msgstr ""
msgid "Overwrite"
msgstr "Перезаписать"
+msgid "Keep Both"
+msgstr "Оставить оба"
+
msgid "Create Script"
msgstr "Создать скрипт"
@@ -5202,7 +5220,7 @@ msgid ""
"Hold Shift for more precise changes."
msgstr ""
"Зажмите %s, чтобы округлить до целых.\n"
-" Зажмите Shift для более точных изменений."
+"Зажмите Shift для более точных изменений."
msgid "No notifications."
msgstr "Нет уведомлений."
@@ -7441,6 +7459,9 @@ msgstr "Изменить точку кривой"
msgid "Modify Curve Point's Tangents"
msgstr "Изменить касательные точки кривой"
+msgid "Toggle Linear Curve Point's Tangent"
+msgstr "Переключить Тангенс точки линейной кривой"
+
msgid "Hold Shift to edit tangents individually"
msgstr "Удерживайте Shift, чтобы изменить касательные индивидуально"
@@ -7524,6 +7545,9 @@ msgstr ""
"Когда эта опция включена, навигационные меши и полигоны будут видны в "
"запущенном проекте."
+msgid "Visible Avoidance"
+msgstr "Избегание видимости"
+
msgid "Synchronize Scene Changes"
msgstr "Синхронизация изменений в сценах"
@@ -7783,6 +7807,9 @@ msgstr "Градиент отредактирован"
msgid "Reverse/mirror gradient."
msgstr "Развернуть/отразить градиент."
+msgid "Move GradientTexture2D Fill Point"
+msgstr "Переместить точку заливки GradientTexture2D"
+
msgid "Swap GradientTexture2D Fill Points"
msgstr "Поменять местами точки заливки GradientTexture2D"
@@ -8542,6 +8569,15 @@ msgstr ""
"Если к сцене добавляется узел DirectionalLight3D, предварительный просмотр "
"солнечного света отключается."
+msgid ""
+"Toggle preview environment.\n"
+"If a WorldEnvironment node is added to the scene, preview environment is "
+"disabled."
+msgstr ""
+"Включить предварительный просмотр окружения.\n"
+"Если в сцену добавлен узел WorldEnvironment, предварительный просмотр "
+"окружения отключается."
+
msgid "Edit Sun and Environment settings."
msgstr "Изменить настройки солнца и окружения."
@@ -8758,6 +8794,21 @@ msgstr ""
"Удерживайте Shift при нажатии, чтобы также добавить предпросмотр солнца к "
"текущей сцене."
+msgid ""
+"No meshes to bake.\n"
+"Make sure there is at least one MeshInstance3D node in the scene whose visual "
+"layers are part of the OccluderInstance3D's Bake Mask property."
+msgstr ""
+"Нет сеток для запекания.\n"
+"Убедитесь, что в сцене есть хотя бы один узел MeshInstance3D, визуальные слои "
+"которого являются частью свойства Bake Mask OccluderInstance3D."
+
+msgid "Could not save the new occluder at the specified path:"
+msgstr "Не удалось сохранить новый окклюдер по указанному пути:"
+
+msgid "Bake Occluders"
+msgstr "Запечь окклюдеры"
+
msgid "Remove Point from Curve"
msgstr "Удалить точку с кривой"
@@ -9042,7 +9093,7 @@ msgid "Error while saving theme."
msgstr "Ошибка при сохранении темы."
msgid "Error Saving"
-msgstr "Ошибка сохранения"
+msgstr "Ошибка Сохранения"
msgid "Error importing theme."
msgstr "Ошибка импортирования темы."
@@ -11681,6 +11732,9 @@ msgstr ""
msgid "Version Control Metadata:"
msgstr "Метаданные контроля версий:"
+msgid "This project was last edited in a different Godot version: "
+msgstr "В последний раз проект был изменён в другой версии Godot: "
+
msgid "Error: Project is missing on the filesystem."
msgstr "Ошибка: Проект отсутствует в файловой системе."
@@ -11825,6 +11879,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Внимание: Проект был создан в Godot %s. Открытие приведет к изменению на "
+"Godot %s.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -14294,6 +14357,39 @@ msgstr ""
"установлен в \"Particle Billboard\"."
msgid ""
+"Using Trail meshes with a skin causes Skin to override Trail poses. Suggest "
+"removing the Skin."
+msgstr ""
+"Использование Trail сетки со скином заставляет Skin переопределить позы "
+"Trail. Предлагаем удалить Skin."
+
+msgid "Trails active, but neither Trail meshes or a Skin were found."
+msgstr "Trails активны, но ни сетки Trail, ни Skin не обнаружены."
+
+msgid ""
+"Only one Trail mesh is supported. If you want to use more than a single mesh, "
+"a Skin is needed (see documentation)."
+msgstr ""
+"Поддерживается только одна сетка Trail. Если вы хотите использовать более "
+"одной сетки, необходимо установить Skin (см. документацию)."
+
+msgid ""
+"Trails enabled, but one or more mesh materials are either missing or not set "
+"for trails rendering."
+msgstr ""
+"Trails включен, но один или несколько материалов сетки либо отсутствуют, либо "
+"не настроены для рендеринга Trails."
+
+msgid ""
+"The Bake Mask has no bits enabled, which means baking will not produce any "
+"collision for this GPUParticlesCollisionSDF3D.\n"
+"To resolve this, enable at least one bit in the Bake Mask property."
+msgstr ""
+"В свойстве Bake Mask не включено ни одного бита, что означает, что запекание "
+"не приведет к столкновениям для данного GPUParticlesCollisionSDF3D.\n"
+"Чтобы решить эту проблему, включите хотя бы один бит в свойстве Bake Mask."
+
+msgid ""
"Shadows are not supported when using the GL Compatibility backend yet. "
"Support will be added in a future release."
msgstr ""
@@ -14306,9 +14402,19 @@ msgstr "Масштабирование света не влияет на раз
msgid "Projector texture only works with shadows active."
msgstr "Текстура проекции работает только с включенными тенями."
+msgid ""
+"Projector textures are not supported when using the GL Compatibility backend "
+"yet. Support will be added in a future release."
+msgstr ""
+"Текстуры проекторов пока не поддерживаются при использовании бэкенда GL "
+"Compatibility. Поддержка будет добавлена в одном из следующих выпусков."
+
msgid "Creating probes"
msgstr "Создание проб"
+msgid "Creating probes from mesh %d/%d"
+msgstr "Создание зондов из сетки %d/%d"
+
msgid "Generating Probe Volumes"
msgstr "Генерация объёмов проб"
@@ -14316,6 +14422,13 @@ msgid "Generating Probe Acceleration Structures"
msgstr "Создание ускоряющих структур зонда"
msgid ""
+"LightmapGI nodes are not supported when using the GL Compatibility backend "
+"yet. Support will be added in a future release."
+msgstr ""
+"Узлы LightmapGI пока не поддерживаются при использовании бэкенда GL "
+"Compatibility. Поддержка будет добавлена в одном из будущих выпусков."
+
+msgid ""
"NavigationLink3D start position should be different than the end position to "
"be useful."
msgstr ""
@@ -14475,6 +14588,34 @@ msgid "(Other)"
msgstr "(Другие)"
msgid ""
+"This node was saved as class type '%s', which was no longer available when "
+"this scene was loaded."
+msgstr ""
+"Этот узел был сохранён с типом класса \"%s\", более недоступного после "
+"загрузки этой сцены."
+
+msgid ""
+"This node is marked as deprecated and will be removed in future versions.\n"
+"Please check the Godot documentation for information about migration."
+msgstr ""
+"Этот узел является устаревшим и будет удалён в следующих версиях.\n"
+"Для получения информации о миграции, ознакомьтесь с документацией Godot."
+
+msgid ""
+"This node is marked as experimental and may be subject to removal or major "
+"changes in future versions."
+msgstr ""
+"Этот узел является экспериментальным и может быть удалён или значительно "
+"изменён в следующих версиях."
+
+msgid ""
+"ShaderGlobalsOverride is not active because another node of the same type is "
+"in the scene."
+msgstr ""
+"ShaderGlobalsOverride неактивен, т.к. другой узел с таким же типом "
+"присутствует в сцене."
+
+msgid ""
"Very low timer wait times (< 0.05 seconds) may behave in significantly "
"different ways depending on the rendered or physics frame rate.\n"
"Consider using a script's process loop instead of relying on a Timer for very "
@@ -14582,15 +14723,61 @@ msgstr ""
"Недопустимое количество аргументов при вызове функции стадии '%s', которая "
"ожидает %d аргументов."
+msgid ""
+"Invalid argument type when calling stage function '%s', type expected is '%s'."
+msgstr ""
+"Неверный тип аргумента при вызове функции этапа \"%s\". Ожидаемый тип: \"%s\"."
+
+msgid "Expected integer constant within [%d..%d] range."
+msgstr "Ожидалась целочисленная константа в диапазоне [%d..%d]."
+
+msgid "Argument %d of function '%s' is not a variable, array, or member."
+msgstr "Аргумент %d функции \"%s\" не является переменной, массивом или членом."
+
msgid "Varyings cannot be passed for the '%s' parameter."
msgstr "Для параметра '%s' не могут быть переданы вариации."
+msgid "A constant value cannot be passed for the '%s' parameter."
+msgstr "Константа не может быть передана для параметра \"%s\"."
+
+msgid ""
+"Argument %d of function '%s' can only take a local variable, array, or member."
+msgstr ""
+"Аргумент %d функции \"%s\" может принимать только локальные переменные, "
+"массивы или члены."
+
+msgid "Built-in function \"%s(%s)\" is only supported on high-end platforms."
+msgstr ""
+"Встроенная функция \"%s(%s)\" поддерживается только на современных/"
+"производительных платформах."
+
msgid "Invalid arguments for the built-in function: \"%s(%s)\"."
msgstr "Недопустимые аргументы для встроенной функции: \"%s(%s)\"."
msgid "Recursion is not allowed."
msgstr "Рекурсия запрещена."
+msgid "Function '%s' can't be called from source code."
+msgstr "Функция \"%s\" не может быть вызвана из исходного кода."
+
+msgid ""
+"Invalid argument for \"%s(%s)\" function: argument %d should be %s but is %s."
+msgstr ""
+"Неправильный аргумент для функции \"%s(%s)\": аргумент %d должен быть %s, не "
+"%s."
+
+msgid ""
+"Too few arguments for \"%s(%s)\" call. Expected at least %d but received %d."
+msgstr ""
+"Слишком мало аргументов для вызова \"%s(%s)\". Ожидалось хотя бы %d, получено "
+"%d."
+
+msgid ""
+"Too many arguments for \"%s(%s)\" call. Expected at most %d but received %d."
+msgstr ""
+"Слишком много аргументов для вызова \"%s(%s)\". Ожидалось не более %d, "
+"получено %d."
+
msgid "Invalid assignment of '%s' to '%s'."
msgstr "Недопустимое присвоение '%s' в '%s'."
@@ -14618,6 +14805,15 @@ msgstr "Назначить форму."
msgid "Constants cannot be modified."
msgstr "Константы не могут быть изменены."
+msgid "Array size is already defined."
+msgstr "Размер массива уже определён."
+
+msgid "Unknown array size is forbidden in that context."
+msgstr "Неизвестный размер массива невозможен в этом контексте."
+
+msgid "Array size expressions are not supported."
+msgstr "Выражения размера массива не поддерживаются."
+
msgid "Expected a positive integer constant."
msgstr "Ожидалась целая положительная константа."
@@ -14660,6 +14856,12 @@ msgid "Varying '%s' cannot be passed for the '%s' parameter in that context."
msgstr ""
"Varying '%s' не может быть передано для параметра '%s' в данном контексте."
+msgid "A constant value cannot be passed for '%s' parameter."
+msgstr "Значение константы не может передано параметру \"%s\"."
+
+msgid "Unknown identifier in expression: '%s'."
+msgstr "Неизвестный идентификатор в выражении: \"%s\"."
+
msgid "Varying with '%s' data type may only be used in the 'fragment' function."
msgstr ""
"Varying с типом данных '%s' может быть использовано только в 'fragment' "
@@ -14668,12 +14870,21 @@ msgstr ""
msgid "Varying '%s' must be assigned in the 'fragment' function first."
msgstr "Varying '%s' должны быть сначала назначены в 'fragment' функции."
+msgid "Can't use function as identifier: '%s'."
+msgstr "Невозможно использовать функцию в качестве идентификатора: \"%s\"."
+
+msgid "Only integer expressions are allowed for indexing."
+msgstr "Только целочисленные выражения могут быть индексированы."
+
msgid "Expected expression, found: '%s'."
msgstr "Ожидаемое выражение, найдено: '%s'."
msgid "Invalid member for '%s' expression: '.%s'."
msgstr "Недопустимый член для '%s': выражения '.%s'."
+msgid "An object of type '%s' can't be indexed."
+msgstr "Объекты типа \"%s\" не могут быть индексированы."
+
msgid "Unexpected end of expression."
msgstr "Неожиданный конец выражения."
@@ -14689,9 +14900,30 @@ msgstr "Недопустимые аргументы для оператора '%
msgid "Invalid variable type (samplers are not allowed)."
msgstr "Недопустимый тип переменной (сэмплеры не разрешены)."
+msgid "Expected initialization of constant."
+msgstr "Ожидалась инициализация константы."
+
+msgid "Expected a boolean expression."
+msgstr "Ожидалось логическое выражение."
+
+msgid "Expected an integer expression."
+msgstr "Ожидалось целочисленное выражение."
+
+msgid "Cases must be defined before default case."
+msgstr "Варианты должны быть указаны перед вариантом по умолчанию."
+
+msgid "Default case must be defined only once."
+msgstr "Вариант по умолчанию должен быть указан единожды."
+
msgid "Duplicated case label: %d."
msgstr "Дублируется метка варианта: %d."
+msgid "'%s' must be placed within a '%s' block."
+msgstr "\"%s\" должен быть размещён внутри блока \"%s\"."
+
+msgid "Expected an integer constant."
+msgstr "Ожидалась целочисленная константа."
+
msgid "Use of '%s' is not allowed here."
msgstr "Использование '%s' здесь недопустимо."
@@ -14770,6 +15002,9 @@ msgstr "Переопределение '%s'."
msgid "Invalid argument name."
msgstr "Недопустимое имя аргумента."
+msgid "Unmatched elif."
+msgstr "Несовпадающий elif."
+
msgid "Missing condition."
msgstr "Пропущено условие."
diff --git a/editor/translations/editor/sv.po b/editor/translations/editor/sv.po
index a81e4b179d..37e3880163 100644
--- a/editor/translations/editor/sv.po
+++ b/editor/translations/editor/sv.po
@@ -35,7 +35,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-08 18:02+0000\n"
+"PO-Revision-Date: 2023-09-02 10:51+0000\n"
"Last-Translator: Henrik Nilsson <nsmoooose@gmail.com>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
@@ -44,7 +44,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Nollställ"
@@ -142,6 +142,9 @@ msgstr "Tillbaka, Sony Select, XBox Back, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Guide, Sony PS, Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Start, Xbox meny, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Vänster Spak, Sony L3, XBox L/LS"
@@ -1117,6 +1120,9 @@ msgstr "Radnummer:"
msgid "%d replaced."
msgstr "%d ersatt."
+msgid "No match"
+msgstr "Ingen träff"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d matcha"
@@ -2267,6 +2273,13 @@ msgstr ""
msgid "Error codes returned:"
msgstr "Returnerade felkoder:"
+msgid ""
+"There is currently no description for this %s. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+"Det finns för närvarande ingen beskrivning för denna %s. Snälla hjälp oss "
+"genom att [color=$color][url=$url]bidra med en[/url][/color]!"
+
msgid "Top"
msgstr "Topp"
@@ -3182,6 +3195,9 @@ msgstr "Redigera Text:"
msgid "On"
msgstr "På"
+msgid "Renaming layer %d:"
+msgstr "Byter namn på lager %d:"
+
msgid "No name provided."
msgstr "Inget namn har angetts."
@@ -3191,6 +3207,9 @@ msgstr "Namnet innehåller ogiltiga tecken."
msgid "Rename"
msgstr "Byt namn"
+msgid "Layer %d"
+msgstr "Lager %d"
+
msgid "Assign..."
msgstr "Tilldela..."
@@ -3257,6 +3276,9 @@ msgstr "Kunde inte öppna filen för läsning från sökväg \"%s\"."
msgid "Packing"
msgstr "Packar"
+msgid "Cannot create file \"%s\"."
+msgstr "Kunde inte skapa fil \"%s\"."
+
msgid "Failed to export project files."
msgstr "Misslyckades att exportera projektets filer."
@@ -3290,6 +3312,9 @@ msgstr "PCK Inbäddning"
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr "Den inbäddade PCK får inte vara större än 4 GiB på 32 bitars exporter."
+msgid "There are no mirrors available."
+msgstr "Det finns inga tillgängliga speglar."
+
msgid "Connecting to the mirror..."
msgstr "Ansluter till spegeln..."
@@ -3401,6 +3426,9 @@ msgstr "Körbar"
msgid "(Inherited)"
msgstr "(Ärvd)"
+msgid "%s Export"
+msgstr "%s Exportera"
+
msgid "Release"
msgstr "Släpp"
@@ -3455,6 +3483,9 @@ msgstr "Misslyckades att spara resurs till %s: %s"
msgid "Failed to load resource at %s: %s"
msgstr "Misslyckades att ladda resurs från %s: %s"
+msgid "Unable to update dependencies:"
+msgstr "Kunde inte uppdatera beroenden:"
+
msgid "A file or folder with this name already exists."
msgstr "En fil eller mapp med detta namn finns redan."
@@ -3464,6 +3495,9 @@ msgstr "Duplicerar fil:"
msgid "New Inherited Scene"
msgstr "Ny Ärvd Scen"
+msgid "Create New"
+msgstr "Skapa ny"
+
msgid "Add to Favorites"
msgstr "Lägg till i Favoriter"
@@ -3501,6 +3535,9 @@ msgstr "Skriv över"
msgid "Create Script"
msgstr "Skapa Skript"
+msgid "Find in Files"
+msgstr "Sök i filer"
+
msgid "Find:"
msgstr "Hitta:"
@@ -3744,6 +3781,9 @@ msgstr "2D"
msgid "<Unnamed Material>"
msgstr "<Onamnat material>"
+msgid "Import ID: %s"
+msgstr "Importera ID: %s"
+
msgid "Error opening scene"
msgstr "Fel vid öppning av scen"
@@ -3857,9 +3897,15 @@ msgstr "Kopiera Resurs"
msgid "Open documentation for this object."
msgstr "Öppna dokumentationen för detta objektet."
+msgid "Add %d Translations"
+msgstr "Lägg till %d översättningar"
+
msgid "Remove Translation"
msgstr "Ta bort Översättning"
+msgid "%s cannot be found."
+msgstr "%s kan ej hittas."
+
msgid "Translations"
msgstr "Översättningar"
@@ -3872,6 +3918,9 @@ msgstr "Resurser:"
msgid "Set %s on %d nodes"
msgstr "Sätt %s på %d noder"
+msgid "%s (%d Selected)"
+msgstr "%s (%d valda)"
+
msgid "Update"
msgstr "Uppdatera"
@@ -3944,15 +3993,27 @@ msgstr "Lägg Till Node..."
msgid "Animation name can't be empty."
msgstr "Animationsnamnet kan inte vara tomt."
+msgid "Animation with the same name already exists."
+msgstr "En animation med samma namn existerar redan."
+
msgid "Load Animation"
msgstr "Ladda Animation"
+msgid "Make Animation Unique: %s"
+msgstr "Gör animation unik: %s"
+
msgid "Invalid AnimationLibrary file."
msgstr "Ogiltig AnimationLibrary-fil."
msgid "Invalid Animation file."
msgstr "Ogiltig animationsfil."
+msgid "Save Animation to File: %s"
+msgstr "Spara animation till fil: %s"
+
+msgid "Rename Animation: %s"
+msgstr "Byt namn på animation: %s"
+
msgid "Pasted Animation"
msgstr "Inklistrad Animation"
@@ -3980,9 +4041,15 @@ msgstr "Byt namn på Animation"
msgid "Change Animation Name:"
msgstr "Ändra Animationsnamn:"
+msgid "Delete Animation '%s'?"
+msgstr "Ta bort animation '%s'?"
+
msgid "Remove Animation"
msgstr "Ta bort Animation"
+msgid "Animation '%s' already exists!"
+msgstr "Animation '%s' finns redan!"
+
msgid "Duplicate Animation"
msgstr "Duplicera Animation"
@@ -4360,9 +4427,24 @@ msgid_plural "Run %d Instances"
msgstr[0] "Kör %d instans"
msgstr[1] "Kör %d instanser"
+msgid "Size: %s"
+msgstr "Storlek: %s"
+
+msgid "Type: %s"
+msgstr "Typ: %s"
+
+msgid "Add Feature"
+msgstr "Lägg till funktion"
+
msgid " - Variation"
msgstr " - Variation"
+msgid "Change Box Shape Size"
+msgstr "Ändra boxformsstorlek"
+
+msgid "Change Probe Size"
+msgstr "Ändra sondstorlek"
+
msgid "Volume"
msgstr "Volym"
@@ -4487,6 +4569,9 @@ msgstr "Z-Axel Transformering."
msgid "Objects: %d\n"
msgstr "Objekt: %d\n"
+msgid "FPS: %d"
+msgstr "FPS: %d"
+
msgid "Top View."
msgstr "Vy Ovanifrån."
@@ -4508,6 +4593,9 @@ msgstr "Vy Bakifrån."
msgid "Rotating %s degrees."
msgstr "Roterar %s grader."
+msgid "Scene Luminance"
+msgstr "Scen luminans"
+
msgid "Display Advanced..."
msgstr "Visa avancerad..."
@@ -4577,6 +4665,12 @@ msgstr "Inställningar..."
msgid "Viewport Settings"
msgstr "Vyinställningar"
+msgid "Sun Color"
+msgstr "Solens färg"
+
+msgid "Sky Color"
+msgstr "Himmelns färg"
+
msgid "Ctrl: Rotate"
msgstr "Ctrl: Rotera"
@@ -4699,6 +4793,9 @@ msgstr "Konvertera gemener/versaler"
msgid "Delete Line"
msgstr "Ta bort rad"
+msgid "Convert Indent to Tabs"
+msgstr "Konvertera indentering till tabbar"
+
msgid "Auto Indent"
msgstr "Automatisk Indentering"
@@ -4711,6 +4808,21 @@ msgstr "Gå till Rad..."
msgid "Save File As"
msgstr "Spara fil som"
+msgid "ShaderFile"
+msgstr "Shaderfil"
+
+msgid "Create MeshInstance2D"
+msgstr "Skapa MeshInstance2D"
+
+msgid "Convert to MeshInstance2D"
+msgstr "Konvertera till MeshInstance2D"
+
+msgid "Convert to Polygon2D"
+msgstr "Konvertera till Polygon2D"
+
+msgid "Simplification:"
+msgstr "Simplifiering:"
+
msgid "Settings:"
msgstr "Inställningar:"
@@ -4732,6 +4844,12 @@ msgstr "Ta bort animation"
msgid "Size"
msgstr "Storlek"
+msgid "Separation"
+msgstr "Separation"
+
+msgid "Memory: %s"
+msgstr "Minne: %s"
+
msgid "1 color"
msgid_plural "{num} colors"
msgstr[0] "1 färg"
@@ -4808,6 +4926,9 @@ msgstr "Välj en annan temaresurs:"
msgid "Type name is empty!"
msgstr "Typnamn är tomt!"
+msgid "Set Base Type"
+msgstr "Sätt bastyp"
+
msgid "Override All"
msgstr "Åsidosätt Alla"
@@ -4817,6 +4938,12 @@ msgstr "Tema:"
msgid "Select UI Scene:"
msgstr "Välj UI-scen:"
+msgid "Painting:"
+msgstr "Målning:"
+
+msgid "Index: %d"
+msgstr "Index: %d"
+
msgid "Shift+Ctrl: Draw rectangle."
msgstr "Skift+Ctrl: Rita rektangel."
@@ -4838,6 +4965,12 @@ msgstr "Teränger"
msgid "No Layers"
msgstr "Inga lager"
+msgid "Physics Layer %d"
+msgstr "Fysiklager %d"
+
+msgid "Paint Properties:"
+msgstr "Målningsegenskaper:"
+
msgid "Yes"
msgstr "Ja"
@@ -4916,6 +5049,9 @@ msgstr "Lägg till Utgångsport"
msgid "Node(s) Moved"
msgstr "Nod(er) Flyttade"
+msgid "Set Constant: %s"
+msgstr "Sätt konstant: %s"
+
msgid "Add Node"
msgstr "Lägg Till Node"
@@ -5012,6 +5148,9 @@ msgstr "Nytt Spelprojekt"
msgid "It would be a good idea to name your project."
msgstr "Det vore en bra idé att namnge ditt projekt."
+msgid "Couldn't save project at '%s' (error %d)."
+msgstr "Kunde inte spara projekt vid '%s' (error %d)."
+
msgid "Error opening package file, not in ZIP format."
msgstr "Fel vid öppning av paketfil, är inte ZIP-format."
@@ -5081,6 +5220,9 @@ msgstr "Ta bort Alla"
msgid "Can't run project"
msgstr "Kan inte köra projektet"
+msgid "Create New Tag"
+msgstr "Skapa ny tag"
+
msgid "Add Project Setting"
msgstr "Lägg till projektinställning"
@@ -5312,6 +5454,9 @@ msgstr "Fel - Kunde inte skapa Skript i filsystemet."
msgid "Error loading script from %s"
msgstr "Fel vid laddning av Skript från %s"
+msgid "Inherit %s"
+msgstr "Ärver %s"
+
msgid "Script path/name is valid."
msgstr "Skript väg/namn är ogiltigt."
@@ -5395,6 +5540,9 @@ msgstr ""
msgid "Delete Property?"
msgstr "Radera egenskap?"
+msgid "Error saving file %s: %s"
+msgstr "Fel vid sparande av fil %s: %s"
+
msgid "Error loading %s: %s."
msgstr "Fel vid laddning %s: %s."
@@ -5438,6 +5586,9 @@ msgstr "Paket hittades ej: \"%s\"."
msgid "Could not find template APK to export: \"%s\"."
msgstr "Kunde inte hitta APK-mall för export: \"%s\"."
+msgid "Adding files..."
+msgstr "Lägger till filer..."
+
msgid "Could not export project files."
msgstr "Kunde inte exportera projektfiler."
@@ -5523,7 +5674,7 @@ msgid "No identity found."
msgstr "Ingen identitet funnen."
msgid "Invalid identity type."
-msgstr "Ogiltig identifierartyp:"
+msgstr "Ogiltig identitetstyp."
msgid "Failed to remove temporary file \"%s\"."
msgstr "Kan inte ta bort temporär fil \"%s\"."
@@ -5649,8 +5800,45 @@ msgstr "Omdefiniering av '%s'."
msgid "Shader include file does not exist:"
msgstr "Shader inkluderingsfil saknas:"
+msgid "Invalid pragma directive."
+msgstr "Ogiltigt pragmadirektiv."
+
+msgid "Macro expansion limit exceeded."
+msgstr "Makroexpansionsgräns överskriden."
+
+msgid "Invalid macro argument list."
+msgstr "Ogiltig makroargumentslista."
+
msgid "Invalid macro argument."
msgstr "Ogiltigt makroargument."
msgid "Invalid macro argument count."
msgstr "Ogiltigt antal makroargument."
+
+msgid "Invalid symbols placed before directive."
+msgstr "Ogiltiga symboler placerade före direktivet."
+
+msgid "The const '%s' is declared but never used."
+msgstr "Konstanten '%s' är deklarerad men aldrig använd."
+
+msgid "The function '%s' is declared but never used."
+msgstr "Funktionen '%s' är deklarerad men aldrig använd."
+
+msgid "The struct '%s' is declared but never used."
+msgstr "Strukten '%s' är deklarerad men aldrig använd."
+
+msgid "The uniform '%s' is declared but never used."
+msgstr "Uniform '%s' är deklarerad men aldrig använd."
+
+msgid "The varying '%s' is declared but never used."
+msgstr "Varying '%s' är deklarerad men aldrig använd."
+
+msgid "The local variable '%s' is declared but never used."
+msgstr "Den lokala variabeln '%s' är deklarerad men aldrig använd."
+
+msgid ""
+"The total size of the %s for this shader on this device has been exceeded (%d/"
+"%d). The shader may not work correctly."
+msgstr ""
+"Den totala storleken %s för denna shader på denna enhet har överskridit (%d/"
+"%d). Shadern kanske inte fungerar korrekt."
diff --git a/editor/translations/editor/tr.po b/editor/translations/editor/tr.po
index 557ec0ce1b..39bdb5f99c 100644
--- a/editor/translations/editor/tr.po
+++ b/editor/translations/editor/tr.po
@@ -109,7 +109,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-13 22:46+0000\n"
+"PO-Revision-Date: 2023-08-30 14:58+0000\n"
"Last-Translator: Yılmaz Durmaz <yilmaz_durmaz@hotmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
@@ -118,7 +118,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "Ayarı Kaldır"
@@ -216,6 +216,9 @@ msgstr "Geri, Sony Select, Xbox Back, Nintendo -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "Rehber, Sony PS, Xbox Ana Sayfası"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "Başlat, Xbox Menüsü, Nintendo +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "Sol Kol, Sony L3, Xbox L/LS"
@@ -1249,6 +1252,9 @@ msgstr "Satır Numarası:"
msgid "%d replaced."
msgstr "%d değiştirildi."
+msgid "No match"
+msgstr "Eşleşme yok"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d eşleşme"
@@ -1532,7 +1538,7 @@ msgid "ms"
msgstr "ms"
msgid "Monitors"
-msgstr "İleyiciler"
+msgstr "İzleyiciler"
msgid "Monitor"
msgstr "İzleyici"
@@ -1671,16 +1677,16 @@ msgid "C++ Source"
msgstr "C++ Kaynağı"
msgid "Video RAM"
-msgstr "Görüntü Belleği"
+msgstr "Video Belleği"
msgid "Skip Breakpoints"
msgstr "Kesme Noktalarını Atla"
msgid "Step Into"
-msgstr "İçine gir"
+msgstr "İçine Gir"
msgid "Step Over"
-msgstr "Üstünden geç"
+msgstr "Üstünden Geç"
msgid "Break"
msgstr "Duraklat"
@@ -1728,7 +1734,7 @@ msgid "Format"
msgstr "Biçim"
msgid "Usage"
-msgstr "Kullanım"
+msgstr "Kullanımı"
msgid "Misc"
msgstr "Çeşitli"
@@ -3099,6 +3105,9 @@ msgstr "'%s' dosyası ayrıştırılırken hata oluştu."
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "'%s' sahne dosyası geçersiz/bozuk görünüyor."
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "'%s' dosyası veya bağımlılıklarından biri eksik."
+
msgid "Error while loading file '%s'."
msgstr "'%s' dosyası yüklenirken bir hata oluştu."
@@ -3467,7 +3476,7 @@ msgstr ""
"'%s' dosyasına yazılamıyor; dosya kullanımda, kilitli veya izinler eksik."
msgid "Pan View"
-msgstr "Kaydırma Görünümü"
+msgstr "Görünümü Kaydır"
msgid "Dock Position"
msgstr "Yuva Konumu"
@@ -5028,7 +5037,7 @@ msgid "Favorited folder does not exist anymore and will be removed."
msgstr "Sık kullanılan klasör artık mevcut değil, ve kaldırılacak."
msgid "Go Back"
-msgstr "Geri Dön"
+msgstr "Geri Git"
msgid "Go Forward"
msgstr "İleri Git"
@@ -5920,7 +5929,7 @@ msgid "Remaps by Locale:"
msgstr "Yerele Göre Yeniden Haritalamalar:"
msgid "Locale"
-msgstr "Yerel"
+msgstr "Yerel kodu"
msgid "POT Generation"
msgstr "POT Üretimi"
@@ -8433,7 +8442,7 @@ msgid "Freelook Down"
msgstr "Aşağı Serbest Bakış"
msgid "Freelook Speed Modifier"
-msgstr "Serbest Bakış Hızı Değiştirici"
+msgstr "Serbest Bakış Hızlı Değiştirici"
msgid "Freelook Slow Modifier"
msgstr "Serbest Bakış Yavaş Değiştirici"
@@ -9151,7 +9160,7 @@ msgid "%s Class Reference"
msgstr "%s Sınıf Başvurusu"
msgid "Find Next"
-msgstr "Sonraki Bul"
+msgstr "Sonrakini Bul"
msgid "Find Previous"
msgstr "Öncekini Bul"
@@ -9317,7 +9326,7 @@ msgid "Lowercase"
msgstr "Küçük harf"
msgid "Capitalize"
-msgstr "Büyük harfe çevir"
+msgstr "İlk harfi büyük yap"
msgid "Convert Case"
msgstr "Büyük/Küçük Harf Dönüştür"
@@ -9341,7 +9350,7 @@ msgid "Toggle Comment"
msgstr "Yorumu Aç/Kapat"
msgid "Fold/Unfold Line"
-msgstr "Satırı Daralt/Aç"
+msgstr "Satırı Katla/Aç"
msgid "Fold All Lines"
msgstr "Tüm Satırları Daralt"
@@ -9377,13 +9386,13 @@ msgid "Contextual Help"
msgstr "Bağlamsal Yardım"
msgid "Toggle Bookmark"
-msgstr "Yer imleri Aç / Kapat"
+msgstr "Yer imlerini Aç / Kapat"
msgid "Go to Next Bookmark"
-msgstr "Sonraki Yerimine Git"
+msgstr "Sonraki Yer İmine Git"
msgid "Go to Previous Bookmark"
-msgstr "Önceki Yerimine Git"
+msgstr "Önceki Yer İmine Git"
msgid "Remove All Bookmarks"
msgstr "Bütün Yer imlerini Kaldır"
@@ -11122,7 +11131,7 @@ msgid "Add Output"
msgstr "Çıkış Ekle"
msgid "Float"
-msgstr "Ondalıklı (Float)"
+msgstr "Float"
msgid "Int"
msgstr "Int (Tamsayı)"
@@ -12457,6 +12466,14 @@ msgstr "Sürüm Denetimi Metaverileri:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr ""
+"Bu projenin en son düzenlenmesi, Godot'nun farklı bir sürümüyle yapılmış. "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr ""
+"Bu proje, mevcut derleme tarafından desteklenmeyen özellikler kullanıyor:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "Hata: Proje, dosya sisteminde mevcut değil."
@@ -12601,6 +12618,15 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"Uyarı: Bu projenin en son düzenlenmesi, Godot %s ile yaplımıştır. Açmaya "
+"devam etmek, projeyi Godot %s 'e değiştirecektir.\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12743,6 +12769,28 @@ msgstr "Ayrıca proje içeriğini de sil (geri alınamaz!)"
msgid "Convert Full Project"
msgstr "Projeyi Tam Dönüştür"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"Bu seçenek, Godot 4 'te çalışmak üzere, Godot 3 ile oluşturulmuş sahneleri, "
+"kaynakları ve betikleri güncelleyerek, tam proje dönüşümü "
+"gerçekleştirecektir.\n"
+"\n"
+"Bunun en-iyi-çabalama dönüştürmesi olduğunu unutmayın, yani projeyi "
+"yükseltmeyi kolaylaştırır, ancak kutudan-yeni-çıkmış gibi açılmayacak ve yine "
+"de elle ayarlamalar gerektirecektir.\n"
+"\n"
+"ÖNEMLİ: Dönüştürmeden önce projenizi yedeklediğinizden emin olun, çünkü bu "
+"işlem Godot'un eski sürümleriyle açılmasını imkansız hale getirir."
+
msgid "Can't run project"
msgstr "Proje çalıştırılamıyor"
@@ -12839,7 +12887,7 @@ msgid "Select Virtual Method"
msgstr "Sanal Yöntem Seç"
msgid "Batch Rename"
-msgstr "Toplu Yeniden Adlandır"
+msgstr "Toplu Yeniden İsimlendir"
msgid "Prefix:"
msgstr "Ön Ek:"
@@ -13268,7 +13316,7 @@ msgid "(used %d times)"
msgstr "( %d kez kullanıldı)"
msgid "Add Child Node"
-msgstr "Alt-Düğüm Ekle"
+msgstr "Alt-öğe Düğümü Ekle"
msgid "Expand/Collapse Branch"
msgstr "Dalı Genişlet/Daralt"
@@ -13837,7 +13885,7 @@ msgid "Count"
msgstr "Sayım"
msgid "Network Profiler"
-msgstr "Ağ Profilcisi"
+msgstr "Ağ Profil Çıkarıcısı"
msgid "Replication"
msgstr "Çoğaltma"
@@ -16736,6 +16784,13 @@ msgstr "Örneğin indeksi negatif olamaz."
msgid "Allowed instance uniform indices must be within [0..%d] range."
msgstr "İzin verilen örnek düzenli dizinleri [0..%d] aralığında olmalıdır."
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr ""
+"'hint_normal_roughness_texture' seçeneği sadece İleri+ arka-uç kullanırken "
+"kullanılabilir olur."
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "'hint_normal_roughness_texture', '%s' gölgelendiricilerde desteklenmez."
diff --git a/editor/translations/editor/vi.po b/editor/translations/editor/vi.po
index b0f4d201c8..12e36a9f47 100644
--- a/editor/translations/editor/vi.po
+++ b/editor/translations/editor/vi.po
@@ -30,13 +30,14 @@
# Schuetzer <minhtuvn@gmail.com>, 2023.
# Phạm Minh Tấn <phamtiens289@gmail.com>, 2023.
# Long Phan <phangg255@gmail.com>, 2023.
+# duong cfa <duongcfa1@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor interface\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-17 11:10+0000\n"
-"Last-Translator: Long Phan <phangg255@gmail.com>\n"
+"PO-Revision-Date: 2023-08-22 15:34+0000\n"
+"Last-Translator: duong cfa <duongcfa1@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
"Language: vi\n"
@@ -249,6 +250,18 @@ msgstr "Nhân đôi các khoá đã chọn"
msgid "Delete Selected Key(s)"
msgstr "Xoá các khoá được chọn"
+msgid "Make Handles Balanced"
+msgstr "Làm cho tay cầm cân bằng"
+
+msgid "Make Handles Mirrored"
+msgstr "Làm cho tay cầm phản chiếu"
+
+msgid "Make Handles Balanced (Auto Tangent)"
+msgstr "Làm cho tay cầm cân bằng (tiếp tục tự động)"
+
+msgid "Make Handles Mirrored (Auto Tangent)"
+msgstr "Làm cho tay cầm phản chiếu (tiếp tục tự động)"
+
msgid "Add Bezier Point"
msgstr "Thêm điểm Bezier"
@@ -4595,6 +4608,18 @@ msgstr "Xóa mục Lớp"
msgid "Remove All Items"
msgstr "Xóa tất cả các mục"
+msgid "Override All Default Theme Items"
+msgstr "Ghi đè tất cả các mục chủ đề mặc định"
+
+msgid "Set Font Size Item in Theme"
+msgstr "Đặt kích thước phông chữ trong chủ đề"
+
+msgid "Set Font Item in Theme"
+msgstr "Đặt mục phông chữ trong chủ đề"
+
+msgid "Set Icon Item in Theme"
+msgstr "Đặt mục biểu tượng trong chủ đề"
+
msgid "Base Type"
msgstr "loại cơ sở"
diff --git a/editor/translations/editor/zh_CN.po b/editor/translations/editor/zh_CN.po
index cc68d7121a..70ac3821ad 100644
--- a/editor/translations/editor/zh_CN.po
+++ b/editor/translations/editor/zh_CN.po
@@ -91,12 +91,13 @@
# WangYi13 <wyi13@outlook.com>, 2023.
# matrixant <yuan545@hotmail.com>, 2023.
# GarliCat <phoenixkaze@live.com>, 2023.
+# GT-610 <myddz1005@163.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2023-07-29 03:10+0000\n"
+"PO-Revision-Date: 2023-09-05 13:09+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -105,7 +106,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Unset"
msgstr "未设置"
@@ -203,6 +204,9 @@ msgstr "返回、索尼 Select、Xbox Back、任天堂 -"
msgid "Guide, Sony PS, Xbox Home"
msgstr "指南、索尼 PS、Xbox Home"
+msgid "Start, Xbox Menu, Nintendo +"
+msgstr "开始、Xbox 菜单、任天堂 +"
+
msgid "Left Stick, Sony L3, Xbox L/LS"
msgstr "左摇杆、索尼 L3、Xbox L/LS"
@@ -1222,6 +1226,9 @@ msgstr "行号:"
msgid "%d replaced."
msgstr "已替换 %d 处。"
+msgid "No match"
+msgstr "无匹配"
+
msgid "%d match"
msgid_plural "%d matches"
msgstr[0] "%d 个匹配"
@@ -2551,7 +2558,7 @@ msgstr ""
"这个 %s 目前没有描述。请帮我们[color=$color][url=$url]贡献一个[/url][/color]!"
msgid "Top"
-msgstr "顶"
+msgstr "顶部"
msgid "Class:"
msgstr "类:"
@@ -3014,6 +3021,9 @@ msgstr "解析文件“%s”时出错。"
msgid "Scene file '%s' appears to be invalid/corrupt."
msgstr "场景文件“%s”似乎无效/已损坏。"
+msgid "Missing file '%s' or one of its dependencies."
+msgstr "缺失文件“%s”或其依赖项。"
+
msgid "Error while loading file '%s'."
msgstr "加载文件“%s”时出错。"
@@ -6758,7 +6768,7 @@ msgstr "平移模式"
msgid ""
"You can also use Pan View shortcut (Space by default) to pan in any mode."
-msgstr "您还可以使用平移视图快捷键(默认为空格)在任何模式下平移。"
+msgstr "你还可以使用平移视图快捷键(默认为空格)在任何模式下平移。"
msgid "Ruler Mode"
msgstr "标尺模式"
@@ -10654,7 +10664,7 @@ msgid "Discard all changes"
msgstr "丢弃所有修改"
msgid "This operation is IRREVERSIBLE. Your changes will be deleted FOREVER."
-msgstr "此操作是不可逆的。您的更改将被永久删除。"
+msgstr "此操作是不可逆的。你的更改将被永久删除。"
msgid "Permanentally delete my changes"
msgstr "永久删除我的更改"
@@ -11814,8 +11824,8 @@ msgid ""
"it later in the Expressions. You can also declare varyings, parameters and "
"constants."
msgstr ""
-"自定义的 Godot 着色器语言表达式,会被放到最终的着色器开头。您可以在其中放置各"
-"种函数定义,然后在表达式中调用。您还可以声明 varying、参数和常量。"
+"自定义的 Godot 着色器语言表达式,会被放到最终的着色器开头。你可以在其中放置各"
+"种函数定义,然后在表达式中调用。你还可以声明 varying、参数和常量。"
msgid "A reference to an existing parameter."
msgstr "对现有参数的引用。"
@@ -12017,6 +12027,12 @@ msgstr "版本控制元数据:"
msgid "Git"
msgstr "Git"
+msgid "This project was last edited in a different Godot version: "
+msgstr "该项目的最近一次编辑使用了不同的 Godot 版本: "
+
+msgid "This project uses features unsupported by the current build:"
+msgstr "该项目使用了当前 Godot 构建不支持的功能:"
+
msgid "Error: Project is missing on the filesystem."
msgstr "错误:文件系统上缺失项目。"
@@ -12149,6 +12165,14 @@ msgstr ""
"\n"
msgid ""
+"Warning: This project was last edited in Godot %s. Opening will change it to "
+"Godot %s.\n"
+"\n"
+msgstr ""
+"警告:该项目的最近一次编辑使用的是 Godot %s。打开后将修改为 Godot %s。\n"
+"\n"
+
+msgid ""
"Warning: This project uses the following features not supported by this build "
"of Godot:\n"
"\n"
@@ -12286,6 +12310,26 @@ msgstr "同时删除项目内容(无法撤销!)"
msgid "Convert Full Project"
msgstr "转换完整项目"
+msgid ""
+"This option will perform full project conversion, updating scenes, resources "
+"and scripts from Godot 3 to work in Godot 4.\n"
+"\n"
+"Note that this is a best-effort conversion, i.e. it makes upgrading the "
+"project easier, but it will not open out-of-the-box and will still require "
+"manual adjustments.\n"
+"\n"
+"IMPORTANT: Make sure to backup your project before converting, as this "
+"operation makes it impossible to open it in older versions of Godot."
+msgstr ""
+"该选项将执行完整的项目转换,更新 Godot 3 的场景、资源和脚本,以便在 Godot 4 中"
+"运行。\n"
+"\n"
+"注意,转换是尽力而为的,也就是说,它可以让项目的升级更容易,但无法做到开箱即"
+"用,仍然需要手动调整。\n"
+"\n"
+"重要:转换前请一定要备份你的项目,因为本操作会使它无法在旧版本的 Godot 中打"
+"开。"
+
msgid "Can't run project"
msgstr "无法运行项目"
@@ -15177,7 +15221,7 @@ msgid ""
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
"除非脚本配置其子节点放置行为,否则容器本身没有任何作用。\n"
-"如果您不想添加脚本,请改用普通的 Control 节点。"
+"如果你不想添加脚本,请改用普通的 Control 节点。"
msgid ""
"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
@@ -15906,6 +15950,11 @@ msgstr "实例索引不能为负。"
msgid "Allowed instance uniform indices must be within [0..%d] range."
msgstr "实例 uniform 索引必须在 [0...%d] 范围内。"
+msgid ""
+"'hint_normal_roughness_texture' is only available when using the Forward+ "
+"backend."
+msgstr "“hint_normal_roughness_texture”仅在使用 Forward+ 后端时可用。"
+
msgid "'hint_normal_roughness_texture' is not supported in '%s' shaders."
msgstr "“%s”着色器尚未支持“hint_normal_roughness_texture”。"
diff --git a/editor/translations/properties/de.po b/editor/translations/properties/de.po
index ec7bb852b0..190d386f8d 100644
--- a/editor/translations/properties/de.po
+++ b/editor/translations/properties/de.po
@@ -100,7 +100,7 @@ msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-07 16:32+0000\n"
+"PO-Revision-Date: 2023-09-08 02:18+0000\n"
"Last-Translator: ‎ <artism90@googlemail.com>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/godot-"
"properties/de/>\n"
@@ -109,7 +109,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Anwendung"
@@ -322,7 +322,7 @@ msgid "Occlusion Culling"
msgstr "Occlusion Culling"
msgid "BVH Build Quality"
-msgstr "BVH Build Qualität"
+msgstr "BVH Build-Qualität"
msgid "Memory"
msgstr "Speicher"
@@ -2559,6 +2559,9 @@ msgstr "Angepasster Vordergrund 432 x 432"
msgid "Adaptive Background 432 X 432"
msgstr "Angepasster Hintergrund 432 x 432"
+msgid "Use Gradle Build"
+msgstr "Einen Gradle Build verwenden"
+
msgid "Export Format"
msgstr "Exportformat"
@@ -2886,15 +2889,24 @@ msgstr "Mindest-macOS-Version"
msgid "High Res"
msgstr "Hohe Auflösung"
+msgid "Platform Build"
+msgstr "Plattform-Build"
+
msgid "SDK Version"
msgstr "SDK-Version"
+msgid "SDK Build"
+msgstr "SDK Build"
+
msgid "SDK Name"
msgstr "SDK-Name"
msgid "Xcode Version"
msgstr "Xcode-Version"
+msgid "Xcode Build"
+msgstr "Xcode-Build"
+
msgid "Codesign"
msgstr "Code-Signierung"
@@ -3723,6 +3735,9 @@ msgstr "Vermeidungsmaske"
msgid "Avoidance Priority"
msgstr "Vermeidungspriorität"
+msgid "Use Custom"
+msgstr "Benutzerdefiniert"
+
msgid "Path Custom Point Size"
msgstr "Pfad Benutzerdefinierte Punktgröße"
@@ -5976,6 +5991,9 @@ msgstr "Vorschau"
msgid "Transform Format"
msgstr "Transformformat"
+msgid "Use Custom Data"
+msgstr "Eigene Daten verwenden"
+
msgid "Instance Count"
msgstr "Instanzanzahl"
@@ -6558,6 +6576,9 @@ msgstr "Upscale-Modus"
msgid "Buffer Size"
msgstr "Puffergröße"
+msgid "Cluster Builder"
+msgstr "Cluster Builder"
+
msgid "Max Lights per Object"
msgstr "Max Lichtinstanzen pro Objekt"
diff --git a/editor/translations/properties/fr.po b/editor/translations/properties/fr.po
index 58b1a15ac3..dce8c08c15 100644
--- a/editor/translations/properties/fr.po
+++ b/editor/translations/properties/fr.po
@@ -114,13 +114,14 @@
# "Dimitri A." <dimitripilot3@gmail.com>, 2023.
# Varthore <moutcho57@gmail.com>, 2023.
# Chloe Lee-Hone <chloe.leehone@gmail.com>, 2023.
+# François de la Taste <francois.delataste@wildwits.games>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-13 09:01+0000\n"
-"Last-Translator: Chloe Lee-Hone <chloe.leehone@gmail.com>\n"
+"PO-Revision-Date: 2023-08-30 14:58+0000\n"
+"Last-Translator: François de la Taste <francois.delataste@wildwits.games>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/godot-"
"properties/fr/>\n"
"Language: fr\n"
@@ -128,7 +129,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Application"
@@ -2765,7 +2766,7 @@ msgid "Animations"
msgstr "Animations"
msgid "Blender"
-msgstr "Mélangeur"
+msgstr "Blender"
msgid "RPC Port"
msgstr "Port RPC"
diff --git a/editor/translations/properties/id.po b/editor/translations/properties/id.po
index d5408f8f7c..62cb3acab4 100644
--- a/editor/translations/properties/id.po
+++ b/editor/translations/properties/id.po
@@ -47,13 +47,14 @@
# Septian Kurniawan <septgsk@outlook.com>, 2023.
# Septian Ganendra Savero Kurniawan <septgsk@outlook.com>, 2023.
# GID <ghavind12345@gmail.com>, 2023.
+# Luqman Firmansyah <luqm4n.firm4n@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-08 13:52+0000\n"
-"Last-Translator: GID <ghavind12345@gmail.com>\n"
+"PO-Revision-Date: 2023-09-08 02:18+0000\n"
+"Last-Translator: EngageIndo <engageindo@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot-properties/id/>\n"
"Language: id\n"
@@ -61,7 +62,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Aplikasi"
@@ -180,6 +181,9 @@ msgstr "Tata Letak Bus Default"
msgid "General"
msgstr "Umum"
+msgid "Text to Speech"
+msgstr "Teks to Speech"
+
msgid "2D Panning Strength"
msgstr "Kekuatan Panning 2D"
@@ -253,7 +257,7 @@ msgid "Window Log Size"
msgstr "Ukuran Jendela Log"
msgid "Zlib"
-msgstr "Zlib"
+msgstr "Software Zlib"
msgid "Gzip"
msgstr "Gzip"
@@ -265,7 +269,7 @@ msgid "Message"
msgstr "Pesan"
msgid "Rendering"
-msgstr "Rendering"
+msgstr "Proses membuat gambar"
msgid "Occlusion Culling"
msgstr "Pemusnahan Oklusi"
@@ -333,6 +337,12 @@ msgstr "Ukuran Maksimum (MB)"
msgid "Texture Upload Region Size Px"
msgstr "Ukuran Wilayah Unggah Tekstur Ukuran Px"
+msgid "Pipeline Cache"
+msgstr "Cache Alur"
+
+msgid "Save Chunk Size (MB)"
+msgstr "Simpan Ukuran Potongan"
+
msgid "Vulkan"
msgstr "Vulkan"
@@ -357,6 +367,9 @@ msgstr "Mode Penggunaan Processor Rendah"
msgid "Low Processor Usage Mode Sleep (µsec)"
msgstr "Mode Penggunaan Prosesor Rendah Tidur (μsec)"
+msgid "Delta Smoothing"
+msgstr "Penyempurnaan Perubahan"
+
msgid "Print Error Messages"
msgstr "Cetak Pesan Kesalahan"
@@ -384,6 +397,12 @@ msgstr "Gunakan Akumulasi Masukan"
msgid "Input Devices"
msgstr "Perangkat Masukan"
+msgid "Compatibility"
+msgstr "Kecocokan"
+
+msgid "Legacy Just Pressed Behavior"
+msgstr "Tekan Tombol hanya Sekali"
+
msgid "Device"
msgstr "Perangkat"
@@ -438,6 +457,9 @@ msgstr "Faktor"
msgid "Button Index"
msgstr "Tombol Indeks"
+msgid "Canceled"
+msgstr "Dibatalkan"
+
msgid "Double Click"
msgstr "Klik ganda"
@@ -481,7 +503,7 @@ msgid "Channel"
msgstr "Channel"
msgid "Pitch"
-msgstr "Pitch"
+msgstr "Tingkat Nada"
msgid "Instrument"
msgstr "Instrumen"
@@ -714,6 +736,12 @@ msgstr "Kata Sandi"
msgid "Default Feature Profile"
msgstr "Profil Fitur Default"
+msgid "Version Hash"
+msgstr "Versi Pencocokan"
+
+msgid "Classes"
+msgstr "Kelas-kelas"
+
msgid "Text Editor"
msgstr "Editor Teks"
@@ -747,6 +775,9 @@ msgstr "Dapat dihapus"
msgid "Distraction Free Mode"
msgstr "Mode Tanpa Gangguan"
+msgid "Movie Maker Enabled"
+msgstr "Pembuat Film Enabled"
+
msgid "Interface"
msgstr "Antarmuka"
@@ -816,6 +847,12 @@ msgstr "Bahasa Editor"
msgid "Display Scale"
msgstr "Skala Tampilan"
+msgid "Editor Screen"
+msgstr "Layar Editor"
+
+msgid "Project Manager Screen"
+msgstr "Layar Manajer Project"
+
msgid "Enable Pseudolocalization"
msgstr "Aktifkan Pseudolokalisasi"
@@ -894,6 +931,9 @@ msgstr "Item Dictionary Array Maks per Halaman"
msgid "Show Low Level OpenType Features"
msgstr "Tampilkan Fitur OpenType Tingkat Rendah"
+msgid "Float Drag Speed"
+msgstr "Float Kecepatan Tarikan"
+
msgid "Theme"
msgstr "Tema"
@@ -945,6 +985,9 @@ msgstr "Aktifkan Tekan Lama sebagai Klik Kanan"
msgid "Enable Pan and Scale Gestures"
msgstr "Aktifkan Gerakan Pan dan Scale"
+msgid "Scale Gizmo Handles"
+msgstr "Scale Gizmo Menangani"
+
msgid "Display Close Button"
msgstr "Tampilkan Tombol Tutup"
@@ -957,9 +1000,18 @@ msgstr "Lebar Maksimum"
msgid "Show Script Button"
msgstr "Tampilkan Tombol Skrip"
+msgid "Multi Window"
+msgstr "Layar Ganda"
+
msgid "Enable"
msgstr "Aktifkan"
+msgid "Restore Windows on Load"
+msgstr "Pulihkan Windows saat Memuat"
+
+msgid "Maximize Window"
+msgstr "Maksimalkan Jendela"
+
msgid "External Programs"
msgstr "Program Eksternal"
@@ -1020,6 +1072,9 @@ msgstr "Perluas Otomatis ke yang Dipilih"
msgid "Always Show Folders"
msgstr "Selalu Tampilkan Folder"
+msgid "TextFile Extensions"
+msgstr "Ekstensi File Teks"
+
msgid "Property Editor"
msgstr "Editor Properti"
@@ -1039,7 +1094,7 @@ msgid "Caret"
msgstr "Tanda sisipan"
msgid "Caret Blink"
-msgstr "Caret Blink"
+msgstr "Caret Berkedip"
msgid "Caret Blink Interval"
msgstr "Interval Kedipan Caret"
@@ -1425,6 +1480,9 @@ msgstr "Lapisan Onion Warna Masa Depan"
msgid "Shader Editor"
msgstr "Editor Shader"
+msgid "Restore Shaders on Load"
+msgstr "Pulihkan Shaders saat Dimuat"
+
msgid "Visual Editors"
msgstr "Editor Visual"
@@ -1452,6 +1510,9 @@ msgstr "Posisi Kotak Kustom"
msgid "Screen"
msgstr "Layar"
+msgid "Android Window"
+msgstr "Jendela Android"
+
msgid "Auto Save"
msgstr "Simpan Otomatis"
@@ -1629,6 +1690,9 @@ msgstr "Template Kustom"
msgid "Release"
msgstr "Rilis"
+msgid "Export Console Wrapper"
+msgstr "Export Pembungkus Konsol"
+
msgid "Binary Format"
msgstr "Format Biner"
@@ -2373,6 +2437,9 @@ msgstr "Tampilkan Pilihan Root Pohon Adegan"
msgid "Derive Script Globals by Name"
msgstr "Turunkan Script Globals berdasarkan Nama"
+msgid "Ask Before Deleting Related Animation Tracks"
+msgstr "Bertanya Sebelum Menghapus Trek Animasi Terkait"
+
msgid "Use Favorites Root Selection"
msgstr "Gunakan Pemilihan Root Favorit"
@@ -2404,11 +2471,14 @@ msgid "Max Log Files"
msgstr "File Log Maks"
msgid "Driver"
-msgstr "Driver"
+msgstr "Pengemudi"
msgid "GL Compatibility"
msgstr "Kompatibilitas GL"
+msgid "Nvidia Disable Threaded Optimization"
+msgstr "Nvidia Nonaktifkan Optimasi Berulir"
+
msgid "Renderer"
msgstr "Perender"
@@ -2443,7 +2513,7 @@ msgid "Orientation"
msgstr "Orientasi"
msgid "V-Sync"
-msgstr "V-Sync"
+msgstr "Sinkronisasi Vertikal"
msgid "V-Sync Mode"
msgstr "Mode V-Sync"
@@ -2548,7 +2618,7 @@ msgid "Windows Native Icon"
msgstr "Ikon Windows"
msgid "Buffering"
-msgstr "Buffering"
+msgstr "Proses Pengumpulan Data"
msgid "Agile Event Flushing"
msgstr "Flushing Event yang Tangkas"
@@ -2592,6 +2662,9 @@ msgstr "Nama Assembly"
msgid "Solution Directory"
msgstr "Direktori Solusi"
+msgid "Assembly Reload Attempts"
+msgstr "Upaya Muat Ulang Perakitan"
+
msgid "Operation"
msgstr "Operasi"
@@ -2617,7 +2690,7 @@ msgid "Collision Priority"
msgstr "Prioritas Collision"
msgid "Flip Faces"
-msgstr "Flip Faces"
+msgstr "Ubah Wajah"
msgid "Mesh"
msgstr "Jala"
@@ -2781,6 +2854,18 @@ msgstr "Kecepatan Linear"
msgid "Angular Velocity"
msgstr "Kecepatan Sudut"
+msgid "Inertia Tensor"
+msgstr "Tensor Inersia"
+
+msgid "Is Trigger"
+msgstr "Adalah Pemicu"
+
+msgid "Mesh Index"
+msgstr "Mesh Indeks"
+
+msgid "Importer Mesh"
+msgstr "Pengimpor Mesh"
+
msgid "Json"
msgstr "Json"
@@ -2980,7 +3065,7 @@ msgid "Src Image"
msgstr "Gambar Sumber"
msgid "Sampler"
-msgstr "Sampler"
+msgstr "Contoh Acak"
msgid "Mag Filter"
msgstr "Filter Mag"
@@ -3132,6 +3217,9 @@ msgstr "Path Root"
msgid "Replication Interval"
msgstr "Interval Replikasi"
+msgid "Delta Interval"
+msgstr "Interval Delta"
+
msgid "Visibility Update Mode"
msgstr "Mode Pembaruan Visibilitas"
@@ -3153,6 +3241,12 @@ msgstr "Tolak Koneksi Baru"
msgid "Server Relay"
msgstr "Relai Server"
+msgid "Max Sync Packet Size"
+msgstr "Ukuran Maksimum Paket Sinkronisasi"
+
+msgid "Max Delta Packet Size"
+msgstr "Ukuran Paket Maksimum Delta"
+
msgid "Noise Type"
msgstr "Tipe Kebisingan"
@@ -3252,6 +3346,9 @@ msgstr "Path Profil Interaksi"
msgid "Display Refresh Rate"
msgstr "Kecepatan Refresh Layar"
+msgid "Render Target Size Multiplier"
+msgstr "Render Pengganda Ukuran Target"
+
msgid "Hand"
msgstr "Tangan"
@@ -3702,18 +3799,48 @@ msgstr "macOS"
msgid "rcodesign"
msgstr "rcodesign"
+msgid "Distribution Type"
+msgstr "Jenis Distribusi"
+
msgid "Copyright"
msgstr "Hak Cipta"
msgid "Copyright Localized"
msgstr "Hak Cipta Dilokalkan"
+msgid "Min macOS Version"
+msgstr "Versi macOS Minimal"
+
msgid "High Res"
msgstr "Resolusi Tinggi"
+msgid "Xcode"
+msgstr "Xcode"
+
+msgid "Platform Build"
+msgstr "Membangun Platform"
+
+msgid "SDK Version"
+msgstr "Versi Kit Pengembangan Perangkat Lunak"
+
+msgid "SDK Build"
+msgstr "Membangun Kit Pengembangan Perangkat Lunak"
+
+msgid "SDK Name"
+msgstr "Nama Kit Pengembangan Perangkat Lunak"
+
+msgid "Xcode Version"
+msgstr "Versi Xcode"
+
+msgid "Xcode Build"
+msgstr "Membangun Xcode"
+
msgid "Codesign"
msgstr "Codesign"
+msgid "Installer Identity"
+msgstr "Identitas Pemasang"
+
msgid "Apple Team ID"
msgstr "ID Tim Apple"
@@ -3726,6 +3853,9 @@ msgstr "File Sertifikat"
msgid "Certificate Password"
msgstr "Kata Sandi Sertifikat"
+msgid "Provisioning Profile"
+msgstr "Provisioning Profile"
+
msgid "Entitlements"
msgstr "Hak"
@@ -3955,7 +4085,7 @@ msgid "Splash Screen"
msgstr "Splash Screen"
msgid "Tiles"
-msgstr "Ubin"
+msgstr "Petak"
msgid "Show Name on Square 150 X 150"
msgstr "Tampilkan Nama Pada Persegi 150 X 150"
@@ -4480,7 +4610,7 @@ msgid "Node B"
msgstr "Node B"
msgid "Bias"
-msgstr "Bias"
+msgstr "ketidakseimbangan"
msgid "Disable Collision"
msgstr "Nonaktifkan Tabrakan"
@@ -4626,9 +4756,24 @@ msgstr "Jarak Tetangga"
msgid "Max Neighbors"
msgstr "Tetangga Maks"
+msgid "Time Horizon Agents"
+msgstr "Agen Cakrawala Waktu"
+
+msgid "Time Horizon Obstacles"
+msgstr "Hambatan Cakrawala Waktu"
+
msgid "Max Speed"
msgstr "Kecepatan Maks"
+msgid "Avoidance Layers"
+msgstr "Lapisan Penghindaran"
+
+msgid "Avoidance Mask"
+msgstr "Masker Penghindaran"
+
+msgid "Avoidance Priority"
+msgstr "Prioritas Penghindaran"
+
msgid "Use Custom"
msgstr "Gunakan Kustom"
@@ -4656,9 +4801,18 @@ msgstr "Biaya Masuk"
msgid "Travel Cost"
msgstr "Biaya Perjalanan"
+msgid "Vertices"
+msgstr "Sudut"
+
msgid "Navigation Polygon"
msgstr "Poligon Navigasi"
+msgid "Use Edge Connections"
+msgstr "unakan Koneksi Tepi"
+
+msgid "Constrain Avoidance"
+msgstr "Penghindaran Pembatasan"
+
msgid "Skew"
msgstr "Condong"
@@ -5307,6 +5461,9 @@ msgstr "Penjajaran Vertikal"
msgid "Uppercase"
msgstr "Huruf Besar"
+msgid "Justification Flags"
+msgstr "Pembenaran Flags"
+
msgid "BiDi"
msgstr "BiDi"
@@ -5445,6 +5602,12 @@ msgstr "Data Cahaya"
msgid "Surface Material Override"
msgstr "Penggantian Material Permukaan"
+msgid "Path Height Offset"
+msgstr "Path Jarak Ketinggian"
+
+msgid "Use 3D Avoidance"
+msgstr "Gunakan Penghindaran 3D"
+
msgid "Navigation Mesh"
msgstr "Mesh Navigasi"
@@ -5478,6 +5641,9 @@ msgstr "Bake"
msgid "Rotation Mode"
msgstr "Mode Rotasi"
+msgid "Use Model Front"
+msgstr "Gunakan Model Depan"
+
msgid "Tilt Enabled"
msgstr "Kemiringan Diaktifkan"
@@ -5826,9 +5992,15 @@ msgstr "Mode Campuran"
msgid "Fadein Time"
msgstr "Waktu Fadein"
+msgid "Fadein Curve"
+msgstr "Kurva Pemudaran Masuk"
+
msgid "Fadeout Time"
msgstr "Waktu Fadeout"
+msgid "Fadeout Curve"
+msgstr "Kurva Pemudaran Keluar"
+
msgid "Auto Restart"
msgstr "Mulai Ulang Otomatis"
@@ -5859,12 +6031,18 @@ msgstr "Permintaan"
msgid "Active"
msgstr "Aktif"
+msgid "Internal Active"
+msgstr "Internal yang Aktif"
+
msgid "Add Amount"
msgstr "Tambahkan Jumlah"
msgid "Blend Amount"
msgstr "Jumlah Campuran"
+msgid "Sub Amount"
+msgstr "Jumlah Pengurangan"
+
msgid "Seek Request"
msgstr "Mencari Permintaan"
@@ -5895,6 +6073,12 @@ msgstr "Kondisi"
msgid "Expression"
msgstr "Ekspresi"
+msgid "State Machine Type"
+msgstr "Jenis Mesin Keadaan"
+
+msgid "Reset Ends"
+msgstr "Reset Berakhir"
+
msgid "Libraries"
msgstr "Library"
@@ -5979,6 +6163,9 @@ msgstr "Pintasan di Tooltip"
msgid "Button Shortcut Feedback Highlight Time"
msgstr "Tombol Pintasan Umpan Balik Sorot Waktu"
+msgid "Allow Unpress"
+msgstr "Izinkan Pemencetan Ulang"
+
msgid "Text Behavior"
msgstr "Perilaku Teks"
@@ -5994,6 +6181,9 @@ msgstr "Perilaku Ikon"
msgid "Icon Alignment"
msgstr "Penjajaran Ikon"
+msgid "Vertical Icon Alignment"
+msgstr "Penyelarasan Icon Secara Vertikal"
+
msgid "Expand Icon"
msgstr "Perluas Ikon"
@@ -6315,6 +6505,9 @@ msgstr "Ukuran Ikon Tetap"
msgid "Label Settings"
msgstr "Pengaturan Label"
+msgid "Tab Stops"
+msgstr "Tab Berhenti"
+
msgid "Displayed Text"
msgstr "Teks yang Ditampilkan"
@@ -6481,7 +6674,7 @@ msgid "Outline"
msgstr "Garis besar"
msgid "Env"
-msgstr "Env"
+msgstr "Lingkungan"
msgid "Glyph Index"
msgstr "Indeks Glyph"
@@ -6540,6 +6733,12 @@ msgstr "Langkah Kustom"
msgid "Follow Focus"
msgstr "Ikuti Fokus"
+msgid "Horizontal Custom Step"
+msgstr "Langkah Kustom Horizontal"
+
+msgid "Vertical Custom Step"
+msgstr "Langkah Kustom Vertikal"
+
msgid "Horizontal Scroll Mode"
msgstr "Mode Gulir Horizontal"
@@ -6568,7 +6767,7 @@ msgid "Custom Arrow Step"
msgstr "Langkah Panah Kustom"
msgid "Split Offset"
-msgstr "Split Offset"
+msgstr "Pemisahan Posisi"
msgid "Collapsed"
msgstr "Runtuh"
@@ -6642,6 +6841,9 @@ msgstr "Ketinggian Konten yang Sesuai"
msgid "Draw"
msgstr "Menggambar"
+msgid "Draw When Editable Disabled"
+msgstr "Gambar saat Tidak Dapat Diedit"
+
msgid "Move on Right Click"
msgstr "Pindah ke Klik Kanan"
@@ -6796,7 +6998,7 @@ msgid "Max Redirects"
msgstr "Pengalihan Maks"
msgid "Timeout"
-msgstr "Timeout"
+msgstr "Waktu Habis"
msgid "Transfer Mode"
msgstr "Mode Transfer"
@@ -6810,6 +7012,21 @@ msgstr "Nama Node Pemisah Angka"
msgid "Node Name Casing"
msgstr "Casing Nama Node"
+msgid "Physics Priority"
+msgstr "Prioritas Fisika"
+
+msgid "Thread Group"
+msgstr "Grup Benang"
+
+msgid "Group"
+msgstr "Kelompok"
+
+msgid "Group Order"
+msgstr "Pemesanan Kelompok"
+
+msgid "Messages"
+msgstr "Pesan"
+
msgid "Editor Description"
msgstr "Deskripsi Editor"
@@ -7153,7 +7370,7 @@ msgid "Max Sensitivity"
msgstr "Sensitivitas Maks"
msgid "Frustum"
-msgstr "Frustum"
+msgstr "Bangun Tumpul"
msgid "Focus Distance"
msgstr "Jarak Fokus"
@@ -7198,7 +7415,7 @@ msgid "Bake Resolution"
msgstr "Bake Resolusi"
msgid "Bake Interval"
-msgstr "Bake Interval"
+msgstr "Waktu Pemanggangan"
msgid "Up Vector"
msgstr "Vektor Atas"
@@ -7248,6 +7465,9 @@ msgstr "Ikon Warna yang Dinonaktifkan"
msgid "H Separation"
msgstr "Pemisahan H"
+msgid "Icon Max Width"
+msgstr "Icon Lebar Maksimum"
+
msgid "Underline Spacing"
msgstr "Menggarisbawahi Spasi"
@@ -7360,7 +7580,7 @@ msgid "Font Readonly Color"
msgstr "Warna Hanya Baca Font"
msgid "Breakpoint"
-msgstr "Breakpoint"
+msgstr "Titik Batas"
msgid "Bookmark"
msgstr "Bookmark"
@@ -7431,6 +7651,9 @@ msgstr "Perampas Dinonaktifkan"
msgid "Tick"
msgstr "Centang"
+msgid "Center Grabber"
+msgstr "Pengambil Pusat"
+
msgid "Grabber Offset"
msgstr "Offset Perampas"
@@ -7519,7 +7742,7 @@ msgid "Labeled Separator Right"
msgstr "Pemisah Berlabel Kanan"
msgid "Submenu"
-msgstr "Submenu"
+msgstr "Menu Tambahan"
msgid "Submenu Mirrored"
msgstr "Submenu Dicerminkan"
@@ -7674,15 +7897,42 @@ msgstr "Perbatasan Gulir"
msgid "Scroll Speed"
msgstr "Kecepatan Gulir"
+msgid "Scrollbar Margin Left"
+msgstr "Scrollbar Jarak Kiri"
+
+msgid "Scrollbar Margin Top"
+msgstr "Scrollbar Jarak Atas"
+
+msgid "Scrollbar Margin Right"
+msgstr "Scrollbar Jarak Kanan"
+
+msgid "Scrollbar Margin Bottom"
+msgstr "Scrollbar Jarak Bawah"
+
+msgid "Scrollbar H Separation"
+msgstr "Scrollbar Pemisah H"
+
+msgid "Scrollbar V Separation"
+msgstr "Scrollbar Pemisah V"
+
msgid "Icon Margin"
msgstr "Ikon Margin"
msgid "Line Separation"
msgstr "Pemisahan Garis"
+msgid "Font Hovered Color"
+msgstr "Color Font Melayang"
+
+msgid "Hovered"
+msgstr "Melayang"
+
msgid "Tab Selected"
msgstr "Tab Dipilih"
+msgid "Tab Hovered"
+msgstr "Tab Melayang"
+
msgid "Tab Unselected"
msgstr "Tab Tidak Dipilih"
@@ -7731,6 +7981,9 @@ msgstr "Lebar H"
msgid "Label Width"
msgstr "Lebar Label"
+msgid "Center Slider Grabbers"
+msgstr "Pengait Pusat Slider"
+
msgid "Folded Arrow"
msgstr "Panah Terlipat"
@@ -7815,42 +8068,315 @@ msgstr "Pemisah H Tabel"
msgid "Table V Separation"
msgstr "Pemisah V Tabel"
+msgid "Table Odd Row BG"
+msgstr "Latar Belakang Baris Ganjil pada Tabel"
+
+msgid "Table Even Row BG"
+msgstr "Latar Belakang Baris Genap pada Tabel"
+
+msgid "Table Border"
+msgstr "Batas Tabel"
+
+msgid "Text Highlight H Padding"
+msgstr "Jarak H Penyorotan Teks"
+
+msgid "Text Highlight V Padding"
+msgstr "Jarak V Penyorotan Teks"
+
+msgid "H Grabber"
+msgstr "Pengait H"
+
+msgid "V Grabber"
+msgstr "Pengait V"
+
+msgid "Margin Left"
+msgstr "Jarak Kiri"
+
+msgid "Margin Top"
+msgstr "Jarak Atas"
+
+msgid "Margin Right"
+msgstr "Jarak Kanan"
+
+msgid "Margin Bottom"
+msgstr "Jarak Bawah"
+
+msgid "Minimum Grab Thickness"
+msgstr "Tebal Minimum yang Dapat Diambil"
+
+msgid "Autohide"
+msgstr "Otomatis Tersembunyi"
+
+msgid "Minus"
+msgstr "Minus"
+
+msgid "More"
+msgstr "Lebih"
+
+msgid "Grid Minor"
+msgstr "Garis Pembantu"
+
+msgid "Grid Major"
+msgstr "Garis Utama"
+
+msgid "Selection Fill"
+msgstr "Pengisian Seleksi"
+
+msgid "Selection Stroke"
+msgstr "Garis Seleksi"
+
+msgid "Activity"
+msgstr "Aktifitas"
+
+msgid "Port Hotzone Inner Extent"
+msgstr "Batas Bagian Dalam Area Pusat Panas"
+
+msgid "Port Hotzone Outer Extent"
+msgstr "Batas Bagian Luar Area Pusat Panas"
+
msgid "Node"
msgstr "Node"
+msgid "Energy Multiplier"
+msgstr "Pengganda Energi"
+
+msgid "Canvas Max Layer"
+msgstr "Lapisan Maksimum Kanvas"
+
+msgid "Camera Feed ID"
+msgstr "ID Halaman Beranda Kamera"
+
+msgid "Sky"
+msgstr "Langit"
+
+msgid "Custom FOV"
+msgstr "Kostum FOV"
+
+msgid "Ambient Light"
+msgstr "Cahaya Lingkungan"
+
msgid "Source"
msgstr "Sumber"
+msgid "Sky Contribution"
+msgstr "Kontribusi Langit"
+
+msgid "Reflected Light"
+msgstr "Cahaya Pantulan"
+
msgid "Tonemap"
msgstr "Tonemap"
+msgid "White"
+msgstr "Putih"
+
+msgid "SSR"
+msgstr "SSR"
+
+msgid "Max Steps"
+msgstr "Langkah Maksimum"
+
+msgid "Fade In"
+msgstr "Memudar"
+
+msgid "Fade Out"
+msgstr "Memudar"
+
+msgid "Depth Tolerance"
+msgstr "Toleransi Kedalaman"
+
msgid "SSAO"
msgstr "SSAO"
+msgid "Power"
+msgstr "Kekuatan"
+
+msgid "Detail"
+msgstr "Detil"
+
+msgid "Horizon"
+msgstr "Garis Cakrawala"
+
+msgid "Sharpness"
+msgstr "Ketajaman"
+
+msgid "Light Affect"
+msgstr "Efek Cahaya"
+
+msgid "AO Channel Affect"
+msgstr "Efek AO Channel"
+
msgid "SSIL"
msgstr "SSIL"
+msgid "Normal Rejection"
+msgstr "Penolakan Normal"
+
+msgid "SDFGI"
+msgstr "SDFGI"
+
+msgid "Use Occlusion"
+msgstr "Menggunakan Penghalangan"
+
+msgid "Cascades"
+msgstr "Bertumpukan"
+
+msgid "Min Cell Size"
+msgstr "Ukuran Sel Minimal"
+
+msgid "Cascade 0 Distance"
+msgstr "Jarak Tumpuan 0"
+
+msgid "Probe Bias"
+msgstr "Kecenderungan Probe"
+
msgid "Glow"
msgstr "Bersinar"
+msgid "1"
+msgstr "1"
+
msgid "2"
msgstr "2"
+msgid "4"
+msgstr "4"
+
+msgid "5"
+msgstr "5"
+
+msgid "6"
+msgstr "6"
+
+msgid "7"
+msgstr "7"
+
msgid "Mix"
msgstr "Bercampur"
+msgid "Bloom"
+msgstr "Mekar"
+
+msgid "HDR Threshold"
+msgstr "Ambang Dinamik Tinggi"
+
+msgid "HDR Luminance Cap"
+msgstr "Batas Cahaya HDR"
+
+msgid "Fog"
+msgstr "Kabut"
+
+msgid "Sun Scatter"
+msgstr "Taburan Cahaya Matahari"
+
+msgid "GI Inject"
+msgstr "Injeksi GI"
+
+msgid "Anisotropy"
+msgstr "Anisotrop"
+
+msgid "Adjustments"
+msgstr "Penyesuaian"
+
+msgid "Saturation"
+msgstr "Ketepatan Warna"
+
+msgid "Color Correction"
+msgstr "Koreksi Color"
+
+msgid "Edge Fade"
+msgstr "Pelepasan Tepi"
+
msgid "Features"
msgstr "Fitur-fitur"
+msgid "Extra Spacing"
+msgstr "Jarak Tambahan"
+
+msgid "Glyph"
+msgstr "Glyph"
+
+msgid "Offsets"
+msgstr "Perpindahan"
+
+msgid "Map Width"
+msgstr "Lebar Peta"
+
msgid "Shader"
msgstr "Shader"
msgid "Shading"
-msgstr "Shading"
+msgstr "Pengarsiran"
+
+msgid "Use as Albedo"
+msgstr "Gunakan sebagai Albedo"
+
+msgid "Is sRGB"
+msgstr "Adalah sRGB"
+
+msgid "ORM"
+msgstr "ORM"
+
+msgid "Metallic"
+msgstr "Berbahan Logam"
+
+msgid "Operator"
+msgstr "Operator"
+
+msgid "On UV2"
+msgstr "Di UV2"
+
+msgid "Rim"
+msgstr "Lingkaran Luar"
+
+msgid "Flowmap"
+msgstr "Peta Aliran"
+
+msgid "Deep Parallax"
+msgstr "Efek Kedalaman Mendalam"
+
+msgid "Flip Tangent"
+msgstr "Pembalikan Garis Singgung"
+
+msgid "Subsurface Scattering"
+msgstr "Subsurface Scattering"
+
+msgid "Transmittance"
+msgstr "Transmisi"
+
+msgid "Boost"
+msgstr "Meningkatkan"
+
+msgid "Refraction"
+msgstr "Refraction"
+
+msgid "Triplanar"
+msgstr "Tiga Dimensi"
+
+msgid "Triplanar Sharpness"
+msgstr "Ketajaman dalam Tiga Dimensi"
+
+msgid "World Triplanar"
+msgstr "Dunia Tiga Dimensi"
+
+msgid "Sampling"
+msgstr "Contoh"
msgid "Shadows"
msgstr "Bayangan"
+msgid "H Frames"
+msgstr "Bingkai H"
+
+msgid "V Frames"
+msgstr "Bingkai V"
+
+msgid "Grow"
+msgstr "Tumbuh"
+
+msgid "Distance"
+msgstr "Jarak"
+
msgid "MSDF"
msgstr "MSDF"
@@ -7860,36 +8386,156 @@ msgstr "Item"
msgid "Preview"
msgstr "Pratinjau"
+msgid "Transform Format"
+msgstr "Format Transformasi"
+
+msgid "Visible Instance Count"
+msgstr "Jumlah Instance Terlihat"
+
msgid "Parsed Geometry Type"
msgstr "Jenis Geometri yang Diuraikan"
+msgid "Source Geometry Mode"
+msgstr "Mode Geometri Sumber"
+
+msgid "Agents"
+msgstr "Agen"
+
+msgid "Max Climb"
+msgstr "Maksimum Kenaikan"
+
+msgid "Max Slope"
+msgstr "Kemiringan Maksimum"
+
+msgid "Edges"
+msgstr "Ujung"
+
msgid "Sample Distance"
msgstr "Jarak sampel"
+msgid "Low Hanging Obstacles"
+msgstr "Hambatan yang Mudah Dihindari"
+
+msgid "Ledge Spans"
+msgstr "Jarak Antara Aliran Batu"
+
+msgid "Walkable Low Height Spans"
+msgstr "Jembatan Ketinggian Rendah yang Bisa Dijalani Kaki"
+
+msgid "Baking AABB Offset"
+msgstr "Jarak Baking AABB"
+
+msgid "Bundled"
+msgstr "Dikemas Bersama"
+
msgid "Point Texture"
msgstr "Tekstur Titik"
msgid "Normal Texture"
msgstr "Texture Normal"
+msgid "Turbulence"
+msgstr "Turbulence"
+
+msgid "Noise Speed"
+msgstr "Kecepatan Suara"
+
+msgid "Influence Min"
+msgstr "Pengaruh Minimum"
+
+msgid "Influence Max"
+msgstr "Pengaruh Maksimum"
+
+msgid "Initial Displacement Min"
+msgstr "Jarak Awal Minimum"
+
+msgid "Initial Displacement Max"
+msgstr "Perpindahan Awal Maksimum"
+
+msgid "Influence over Life"
+msgstr "Pengaruh terhadap Kehidupan"
+
+msgid "Rough"
+msgstr "Kasar"
+
+msgid "Absorbent"
+msgstr "Bahan Penyerap"
+
+msgid "Add UV2"
+msgstr "Tambah UV2"
+
+msgid "Subdivide Width"
+msgstr "Membagi Lebar"
+
+msgid "Subdivide Height"
+msgstr "Pemisahan Tinggi"
+
+msgid "Subdivide Depth"
+msgstr "Kedalaman Pembagian Subbagian"
+
msgid "Top Radius"
msgstr "Radius Atas"
msgid "Bottom Radius"
msgstr "Radius Bawah"
+msgid "Is Hemisphere"
+msgstr "Adalah Selatan Belahan Bumi"
+
+msgid "Ring Segments"
+msgstr "Segmen Cincin"
+
+msgid "Radial Steps"
+msgstr "Langkah-langkah Radial"
+
+msgid "Section Segments"
+msgstr "Bagian Segmen"
+
+msgid "A"
+msgstr "A"
+
msgid "B"
msgstr "B"
+msgid "Custom Solver Bias"
+msgstr "Penyesuaian Penyelesaian Kustom"
+
+msgid "CCDIK Data Chain Length"
+msgstr "CCDIK Panjang Rantai Data"
+
+msgid "FABRIK Data Chain Length"
+msgstr "FABRIK Panjang Rantai Data"
+
+msgid "Jiggle Data Chain Length"
+msgstr "Panjang Rantai Data Getar"
+
+msgid "Target Maximum Distance"
+msgstr "Jarak Maksimum Target"
+
+msgid "Sky Material"
+msgstr "Bahan Langit"
+
msgid "Radiance Size"
msgstr "Ukuran Pancaran"
msgid "Horizon Color"
msgstr "Warna Horizon"
+msgid "Cover"
+msgstr "Sampul"
+
+msgid "Panorama"
+msgstr "Pemandangan Luas"
+
msgid "Rayleigh"
msgstr "Rayleigh"
+msgid "Eccentricity"
+msgstr "Keanehan"
+
+msgid "Turbidity"
+msgstr "Kekeruhan"
+
msgid "Ground Color"
msgstr "Warna Daratan"
@@ -7908,6 +8554,21 @@ msgstr "Kanan Bawah"
msgid "Bottom Left"
msgstr "Kiri Bawah"
+msgid "Corner Detail"
+msgstr "Detail Sudut"
+
+msgid "Grow Begin"
+msgstr "Tumbuh Dimulai"
+
+msgid "Grow End"
+msgstr "Tumbuh Berakhir"
+
+msgid "Break Flags"
+msgstr "Hancurkan Flags"
+
+msgid "Keep Compressed Buffer"
+msgstr "Menyimpan Buffer yang Tertekan"
+
msgid "Image Size"
msgstr "Ukuran Gambar"
@@ -7920,30 +8581,102 @@ msgstr "Ke"
msgid "Frames"
msgstr "Bingkai-bingkai"
+msgid "Which Feed"
+msgstr "Umpan yang Mana"
+
+msgid "Terrains"
+msgstr "Lahan"
+
+msgid "Alternative Level"
+msgstr "Tingkat Alternatif"
+
+msgid "UV Clipping"
+msgstr "Pemotongan UV"
+
+msgid "Custom Data Layers"
+msgstr "Lapisan Data Kustom"
+
msgid "Scene"
msgstr "Adegan"
+msgid "One Way"
+msgstr "Satu Cara"
+
msgid "Transpose"
msgstr "Mengubah urutan"
+msgid "Terrain"
+msgstr "Lahan"
+
+msgid "Miscellaneous"
+msgstr "Lain-lain"
+
+msgid "Output Port for Preview"
+msgstr "Output Port untuk Preview"
+
+msgid "Parameter Name"
+msgstr "Nama Parameter"
+
msgid "Constant"
msgstr "Konstan"
+msgid "Cube Map"
+msgstr "Peta Kubus"
+
msgid "Function"
msgstr "Fungsi"
+msgid "Hint"
+msgstr "Petunjuk"
+
msgid "Plane"
-msgstr "Plane"
+msgstr "Pesawat"
msgid "Custom"
msgstr "Kustom"
+msgid "Default Font Multichannel Signed Distance Field"
+msgstr "Font Standar Multichannel Signed Distance Field"
+
+msgid "Playback Mode"
+msgstr "Mode Pemutaran"
+
msgid "Random Pitch"
msgstr "Pitch Acak"
+msgid "Random Volume Offset dB"
+msgstr "Penyesuaian Volume Acak dalam dB"
+
+msgid "Buffer Length"
+msgstr "Panjang Buffer"
+
+msgid "Voice Count"
+msgstr "Jumlah Suara"
+
+msgid "Dry"
+msgstr "Kering"
+
+msgid "Wet"
+msgstr "Basah"
+
+msgid "Voice"
+msgstr "Suara"
+
+msgid "Delay (ms)"
+msgstr "Jeda (milidetik)"
+
+msgid "Rate Hz"
+msgstr "Laju Hz"
+
+msgid "Level dB"
+msgstr "Tingkat dB"
+
msgid "Pan"
msgstr "Pan"
+msgid "Attack (µs)"
+msgstr "Serangan (µs)"
+
msgid "Sidechain"
msgstr "Sidechain"
@@ -7953,39 +8686,231 @@ msgstr "Tap 1"
msgid "Tap 2"
msgstr "Tap 2"
+msgid "Pre Gain"
+msgstr "Penyetelan Awal Gain"
+
+msgid "Keep Hf Hz"
+msgstr "Pertahankan Frekuensi Tinggi dalam Hertz"
+
+msgid "Drive"
+msgstr "Drive"
+
+msgid "Ceiling dB"
+msgstr "Atap dB"
+
+msgid "Threshold dB"
+msgstr "Batas Minimum dB"
+
msgid "Soft Clip dB"
msgstr "Soft Clip dB"
msgid "Soft Clip Ratio"
msgstr "Rasio Soft Clip"
+msgid "Range Min Hz"
+msgstr "Rentang Frekuensi Minimum"
+
+msgid "Range Max Hz"
+msgstr "Rentang Frekuensi Maksimum"
+
msgid "FFT Size"
msgstr "Ukuran FFT"
+msgid "Predelay"
+msgstr "Lagu Awal Echo"
+
+msgid "Msec"
+msgstr "Milidetik"
+
+msgid "Room Size"
+msgstr "Ukuran Room"
+
+msgid "Tap Back Pos"
+msgstr "Posisi Tap Kembali"
+
+msgid "Pan Pullout"
+msgstr "Lemari Keluar Pan"
+
+msgid "Time Pullout (ms)"
+msgstr "Penarikan Waktu (ms)"
+
+msgid "Surround"
+msgstr "Sekitar"
+
+msgid "Channel Disable Threshold dB"
+msgstr "Channel Ambang dB Nonaktif"
+
+msgid "Video Delay Compensation (ms)"
+msgstr "Pengompensasian Tunda Video (ms)"
+
+msgid "Feed"
+msgstr "Makanan"
+
+msgid "Metadata Flags"
+msgstr "Metadata Flags"
+
+msgid "Path Rids"
+msgstr "Menyingkirkan Path"
+
+msgid "Path Owner IDs"
+msgstr "Path Pemilik ID"
+
+msgid "Default Edge Connection Margin"
+msgstr "Batas Pinggiran Koneksi Standar"
+
+msgid "Default Link Connection Radius"
+msgstr "Jarak Standar Koneksi Tautan"
+
+msgid "Avoidance Use High Priority Threads"
+msgstr "Menghindari Penggunaan Utas Prioritas Tinggi"
+
+msgid "Edge Connection Color"
+msgstr "Color Koneksi Tepi"
+
+msgid "Enable Edge Connections X-Ray"
+msgstr "Aktifkan Koneksi Tepi X-Ray"
+
+msgid "Enable Edge Lines X-Ray"
+msgstr "Aktifkan Garis-Garis Tepi X-Ray"
+
+msgid "Enable Agent Paths X-Ray"
+msgstr "Aktifkan Fitur X-Ray pada Jalur Agen"
+
+msgid "Obstacles Radius Color"
+msgstr "Radius Hambatan Color"
+
+msgid "Obstacles Static Face Pushin Color"
+msgstr "Color untuk Mendorong Rintangan Tidak Bergerak pada Sisi Tetap"
+
+msgid "Obstacles Static Edge Pushin Color"
+msgstr "Color Dorongan Pinggiran untuk Menghindari Halangan Statis"
+
+msgid "Obstacles Static Face Pushout Color"
+msgstr "Color Pendorong Wajah Tetap Halangan"
+
+msgid "Obstacles Static Edge Pushout Color"
+msgstr "Color Pendorong Tepi Statik untuk Kendala"
+
+msgid "Enable Obstacles Static"
+msgstr "Aktifkan Rintangan yang Statis"
+
+msgid "Inverse Mass"
+msgstr "Massa Terbalik"
+
+msgid "Total Angular Damp"
+msgstr "Peredaman Sudut Total"
+
+msgid "Exclude"
+msgstr "Mengesampingkan"
+
+msgid "Collide With Areas"
+msgstr "Tabrak Dengan Area"
+
+msgid "Shape RID"
+msgstr "ID Bentuk"
+
+msgid "Collide Separation Ray"
+msgstr "Sinar Pemisahan Tabrakan"
+
msgid "Default Gravity"
msgstr "Gravitasi Baku"
+msgid "Sleep Threshold Linear"
+msgstr "Ambang Tidur Linier"
+
+msgid "Sleep Threshold Angular"
+msgstr "Ambang Batas Sudut Tidur"
+
+msgid "Time Before Sleep"
+msgstr "Waktu Sebelum Tidur"
+
+msgid "Solver"
+msgstr "Pemecah Masalah"
+
+msgid "Contact Max Separation"
+msgstr "Jarak Maksimum Kontak"
+
+msgid "Contact Max Allowed Penetration"
+msgstr "Kontak Maksimal yang Diizinkan untuk Penetrasi"
+
+msgid "Physics Engine"
+msgstr "Mesin Fisika"
+
+msgid "Principal Inertia Axes"
+msgstr "Sumbu Inersia Utama"
+
msgid "Vertex"
msgstr "Titik"
msgid "Fragment"
msgstr "Fragmen"
+msgid "Tesselation Evaluation"
+msgstr "Evaluasi Pengekerutan"
+
+msgid "Syntax"
+msgstr "Tata Bahasa"
+
+msgid "Bytecode"
+msgstr "Kode Byte"
+
+msgid "Base Error"
+msgstr "Error Dasar"
+
+msgid "IDs"
+msgstr "ID"
+
+msgid "Depth Prepass Alpha"
+msgstr "Pra-Penjelajahan Kedalaman Alfa"
+
+msgid "SSS Mode Skin"
+msgstr "Mode Skin SSS"
+
msgid "Cull"
msgstr "Cull"
+msgid "Ensure Correct Normals"
+msgstr "Pastikan Normal yang Benar"
+
+msgid "Alpha to Coverage"
+msgstr "Alfa to Tutupan"
+
+msgid "Alpha to Coverage and One"
+msgstr "Alfa to Tutupan and Satu"
+
+msgid "Use Half Res Pass"
+msgstr "Gunakan Pass Setengah Resolusi"
+
+msgid "Use Quarter Res Pass"
+msgstr "Menggunakan Pass Resolusi Kuartal"
+
msgid "Render Loop Enabled"
msgstr "Render Loop Diaktifkan"
msgid "VRAM Compression"
msgstr "Kompresi VRAM"
+msgid "Lossless Compression"
+msgstr "Kompresi Tanpa Hilang"
+
msgid "Force PNG"
msgstr "Paksa PNG"
+msgid "Time Rollover Secs"
+msgstr "Detik Bergulir Waktu"
+
+msgid "Use Physical Light Units"
+msgstr "Gunakan Satuan Cahaya Fisik"
+
+msgid "Soft Shadow Filter Quality"
+msgstr "Kualitas Filter Bayangan Lembut"
+
msgid "Shadow Atlas"
msgstr "Atlas Bayangan"
+msgid "Shader Cache"
+msgstr "Penyimpanan Shader"
+
msgid "Reflections"
msgstr "Refleksi"
@@ -7998,11 +8923,92 @@ msgstr "GI"
msgid "Overrides"
msgstr "Menimpa"
+msgid "Force Vertex Shading"
+msgstr "Pemberian Efek Warna Titik Paksa"
+
+msgid "Force Lambert over Burley"
+msgstr "Paksa Lambert atas Burley"
+
+msgid "Depth Prepass"
+msgstr "Pra-penjelajahan Kedalaman"
+
+msgid "Use Nearest Mipmap Filter"
+msgstr "Gunakan Mipmap Filter Terdekat"
+
+msgid "Anisotropic Filtering Level"
+msgstr "Tingkat Penyaringan Anisotropik"
+
+msgid "Depth of Field Use Jitter"
+msgstr "Getaran Penggunaan Kedalaman Bidang"
+
+msgid "Adaptive Target"
+msgstr "Sasaran yang Beradaptasi"
+
+msgid "Blur Passes"
+msgstr "Blur Data"
+
+msgid "Fadeout From"
+msgstr "Meredupkan Dari"
+
+msgid "Fadeout To"
+msgstr "Meredupkan To"
+
+msgid "Screen Space Roughness Limiter"
+msgstr "Pembatasan Roughness Ruang Layar"
+
+msgid "Decals"
+msgstr "Decals"
+
+msgid "Occlusion Rays per Thread"
+msgstr "Sinar Penyembunyian per Utas"
+
+msgid "Subsurface Scattering Quality"
+msgstr "Kualitas Subsurface Scattering"
+
+msgid "Subsurface Scattering Depth Scale"
+msgstr "Subsurface Scattering Kedalaman Scale"
+
+msgid "Probe Capture"
+msgstr "Gambar Probe"
+
+msgid "Frames to Converge"
+msgstr "Bingkai to Dikonvergensi"
+
+msgid "Frames to Update Lights"
+msgstr "Bingkai to Perbarui Lampu"
+
+msgid "Update Iterations per Frame"
+msgstr "Perulangan Pembaruan per Frame"
+
+msgid "Max Renderable Elements"
+msgstr "Elemen yang Dapat Dihentikan Sebanyak Maksimal"
+
+msgid "Max Renderable Lights"
+msgstr "Jumlah Lampu yang Bisa Dihitung Maksimal"
+
+msgid "Max Lights per Object"
+msgstr "Maksimal Lampu per Object"
+
msgid "Shader Language"
msgstr "Bahasa Shader"
msgid "Treat Warnings as Errors"
msgstr "Perlakukan Peringatan Sebagai Error"
+msgid "Is Primary"
+msgstr "Adalah Pertama"
+
+msgid "Play Area Mode"
+msgstr "Mode Area Bermain"
+
+msgid "AR"
+msgstr "AR"
+
+msgid "Is Anchor Detection Enabled"
+msgstr "Adalah Deteksi Pemancangan Enabled"
+
+msgid "Tracking Confidence"
+msgstr "Keyakinan Pelacakan"
+
msgid "Property"
msgstr "Properti"
diff --git a/editor/translations/properties/ko.po b/editor/translations/properties/ko.po
index 2479b26c23..e68e2343ec 100644
--- a/editor/translations/properties/ko.po
+++ b/editor/translations/properties/ko.po
@@ -46,13 +46,14 @@
# Overdue - <kaameo12@gmail.com>, 2023.
# nulta <un5450@naver.com>, 2023.
# 이정희 <daemul72@gmail.com>, 2023.
+# Zinccccc <velocity2772@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-07-31 18:39+0000\n"
-"Last-Translator: 이정희 <daemul72@gmail.com>\n"
+"PO-Revision-Date: 2023-09-05 08:33+0000\n"
+"Last-Translator: Zinccccc <velocity2772@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/godot-"
"properties/ko/>\n"
"Language: ko\n"
@@ -60,7 +61,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "어플리케이션"
@@ -3854,6 +3855,9 @@ msgstr "권한 설정 프로파일"
msgid "Location"
msgstr "위치"
+msgid "Notarization"
+msgstr "공증"
+
msgid "UWP"
msgstr "UWP"
@@ -7199,6 +7203,12 @@ msgstr "상수"
msgid "Function"
msgstr "함수"
+msgid "Use All Surfaces"
+msgstr "모든 서피스 사용"
+
+msgid "Surface Index"
+msgstr "서피스 인덱스"
+
msgid "Degrees Mode"
msgstr "각도 모드"
diff --git a/editor/translations/properties/pt_BR.po b/editor/translations/properties/pt_BR.po
index 5689257f84..84fe20e6ff 100644
--- a/editor/translations/properties/pt_BR.po
+++ b/editor/translations/properties/pt_BR.po
@@ -158,13 +158,14 @@
# Zer0-Zer0 <dankmemerson@tutanota.com>, 2022.
# Levi Ferreira <leviferreiramorais@gmail.com>, 2023.
# Daniel Mucciolo <danielviannapsi@gmail.com>, 2023.
+# Romildo Franco <rtfranco@gmail.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2023-06-30 06:50+0000\n"
-"Last-Translator: Daniel Mucciolo <danielviannapsi@gmail.com>\n"
+"PO-Revision-Date: 2023-09-08 09:58+0000\n"
+"Last-Translator: Romildo Franco <rtfranco@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/godot-"
"engine/godot-properties/pt_BR/>\n"
"Language: pt_BR\n"
@@ -172,7 +173,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.18.1\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Aplicação"
@@ -219,6 +220,9 @@ msgstr "Tipo de Loop Principal"
msgid "Auto Accept Quit"
msgstr "Aceitar Sair Automaticamente"
+msgid "Quit on Go Back"
+msgstr "Encerrar ao Voltar"
+
msgid "Display"
msgstr "Exibição"
@@ -399,6 +403,9 @@ msgstr "Internacionalização"
msgid "Force Right to Left Layout Direction"
msgstr "Forçar Direção de Layout Direita para Esquerda"
+msgid "Root Node Layout Direction"
+msgstr "Direção da Estrutura do Nó Raiz"
+
msgid "GUI"
msgstr "GUI (Interface Gráfica de Usuário)"
@@ -411,6 +418,9 @@ msgstr "Máximo intervalo de busca incremental Msec"
msgid "Common"
msgstr "Comum"
+msgid "Snap Controls to Pixels"
+msgstr "Fixar Controles em Pixels"
+
msgid "Fonts"
msgstr "Fontes"
@@ -435,6 +445,12 @@ msgstr "Tamanho Máximo (MB)"
msgid "Texture Upload Region Size Px"
msgstr "Tamanho da região de upload de Textura (PX)"
+msgid "Pipeline Cache"
+msgstr "Armazenamento Temporário"
+
+msgid "Save Chunk Size (MB)"
+msgstr "Tamanho (MB) dos Blocos Salvos"
+
msgid "Vulkan"
msgstr "Vulkan"
@@ -459,6 +475,9 @@ msgstr "Modo de Baixo Uso de Processador"
msgid "Low Processor Usage Mode Sleep (µsec)"
msgstr "Modo de Baixo Uso de Processador (µsec)"
+msgid "Delta Smoothing"
+msgstr "Suavização de Deltas"
+
msgid "Print Error Messages"
msgstr "Imprimir Mensagens de Erro"
@@ -486,6 +505,12 @@ msgstr "Usar entrada acumulada"
msgid "Input Devices"
msgstr "Dispositivos de Entrada"
+msgid "Compatibility"
+msgstr "Compatibilidade"
+
+msgid "Legacy Just Pressed Behavior"
+msgstr "Comportamento do Pressionamento Instantâneo Clássico"
+
msgid "Device"
msgstr "Dispositivo"
@@ -513,11 +538,14 @@ msgstr "Pressionado"
msgid "Keycode"
msgstr "Keycode (Código de Tecla)"
+msgid "Physical Keycode"
+msgstr "Código de Tecla Física"
+
msgid "Key Label"
-msgstr "Rótulo da Tecla"
+msgstr "Inscrição da Tecla"
msgid "Unicode"
-msgstr "Unicode"
+msgstr "Padrão Unicode"
msgid "Echo"
msgstr "Eco"
@@ -537,6 +565,9 @@ msgstr "Fator"
msgid "Button Index"
msgstr "Índice do Botão"
+msgid "Canceled"
+msgstr "Cancelado"
+
msgid "Double Click"
msgstr "Clique Duplo"
@@ -564,6 +595,9 @@ msgstr "Valor do Eixo"
msgid "Index"
msgstr "Índice"
+msgid "Double Tap"
+msgstr "Toque Duplo"
+
msgid "Action"
msgstr "Ação"
@@ -588,6 +622,9 @@ msgstr "Número do Controlador"
msgid "Controller Value"
msgstr "Valor do Controlador"
+msgid "Shortcut"
+msgstr "Atalho"
+
msgid "Events"
msgstr "Eventos"
@@ -786,6 +823,9 @@ msgstr "Adaptador de Depurador"
msgid "Remote Port"
msgstr "Porta Remota"
+msgid "Request Timeout"
+msgstr "Tempo Limite de Solicitação"
+
msgid "Sync Breakpoints"
msgstr "Pontos de Quebra de Sincronismo"
@@ -804,6 +844,12 @@ msgstr "Senha"
msgid "Default Feature Profile"
msgstr "Perfil de funcionalidade Padrão"
+msgid "Version Hash"
+msgstr "Versão do Hash"
+
+msgid "Classes"
+msgstr "Classes"
+
msgid "Text Editor"
msgstr "Editor de Texto"
@@ -825,6 +871,9 @@ msgstr "Checável"
msgid "Checked"
msgstr "Checado"
+msgid "Draw Warning"
+msgstr "Desenhar Aviso"
+
msgid "Keying"
msgstr "Chaveamento"
@@ -834,9 +883,15 @@ msgstr "Deletável"
msgid "Distraction Free Mode"
msgstr "Modo Sem Distrações"
+msgid "Movie Maker Enabled"
+msgstr "Criador de filmes Ativado"
+
msgid "Interface"
msgstr "Interface"
+msgid "Save on Focus Loss"
+msgstr "Salvar ao perder o foco"
+
msgid "Show Update Spinner"
msgstr "Mostrar Spinner de Atualização"
@@ -849,6 +904,9 @@ msgstr "Configurações de Localização"
msgid "Scene Tabs"
msgstr "Abas de Cena"
+msgid "Restore Scenes on Load"
+msgstr "Restaurar Cenas ao Inicializar"
+
msgid "Inspector"
msgstr "Inspetor"
@@ -870,6 +928,12 @@ msgstr "Edição Horizontal do Vector2"
msgid "Horizontal Vector Types Editing"
msgstr "Edição Horizontal de Tipos de Vetor"
+msgid "Open Resources in Current Inspector"
+msgstr "Abrir Recursos no Inspetor Atual"
+
+msgid "Resources to Open in New Inspector"
+msgstr "Recursos para abrir em Novo Inspetor"
+
msgid "Default Color Picker Mode"
msgstr "Modo de Seletor de Cores Padrão"
@@ -891,6 +955,12 @@ msgstr "Linguagem do Editor"
msgid "Display Scale"
msgstr "Exibir Escala"
+msgid "Editor Screen"
+msgstr "Tela do Editor"
+
+msgid "Project Manager Screen"
+msgstr "Tela do Gerenciador de Projetos"
+
msgid "Enable Pseudolocalization"
msgstr "Habilitar Pseudo Localização"
@@ -4848,11 +4918,20 @@ msgstr "Modo de Reprodução"
msgid "Sync"
msgstr "Sincronizar"
+msgid "Mix Mode"
+msgstr "Modo Mix"
+
msgid "Fadein Time"
-msgstr "Tempo de Esmaecer de Entrada"
+msgstr "Tempo do Fadein"
+
+msgid "Fadein Curve"
+msgstr "Curva Fadein"
msgid "Fadeout Time"
-msgstr "Tempo de Esmaecer de Saída"
+msgstr "Tempo de Fadeout"
+
+msgid "Fadeout Curve"
+msgstr "Curva Fadeout"
msgid "Auto Restart"
msgstr "Reinício Automático"
@@ -4867,20 +4946,38 @@ msgid "Random Delay"
msgstr "Atraso Aleatório"
msgid "Xfade Time"
-msgstr "Tempo do Esmaecer Cruzado"
+msgstr "Tempo do Xfade"
+
+msgid "Xfade Curve"
+msgstr "Curva Xfade"
msgid "Allow Transition to Self"
msgstr "Permitir Transição para Auto"
+msgid "Input Count"
+msgstr "Contador de Inputs"
+
msgid "Request"
-msgstr "Solicitar"
+msgstr "Solicitação"
msgid "Active"
msgstr "Ativo"
+msgid "Internal Active"
+msgstr "Atividade Interna"
+
+msgid "Add Amount"
+msgstr "Adicionar Quantidade"
+
msgid "Seek Request"
msgstr "Solicitar Busca"
+msgid "Current Index"
+msgstr "Índice Atual"
+
+msgid "Current State"
+msgstr "Estado Atual"
+
msgid "Reset"
msgstr "Redefinir"
@@ -5118,11 +5215,17 @@ msgstr "Permitir Menor"
msgid "Elapsed Time"
msgstr "Tempo Decorrido"
+msgid "BBCode Enabled"
+msgstr "BBCode Ativado"
+
+msgid "Fit Content"
+msgstr "Encaixar Conteúdo"
+
msgid "Scroll Active"
msgstr "Rolagem Ativa"
msgid "Scroll Following"
-msgstr "Rolar Seguindo"
+msgstr "Seguir Rolagem"
msgid "Tab Size"
msgstr "Tamanho da Tabulação"
@@ -5136,14 +5239,59 @@ msgstr "Meta Sublinhado"
msgid "Progress Bar Delay"
msgstr "Atraso da Barra de Progresso"
+msgid "Text Selection"
+msgstr "Seleção de Texto"
+
+msgid "Selection Enabled"
+msgstr "Seleção Ativada"
+
+msgid "Custom Step"
+msgstr "Intervalo Personalizado"
+
+msgid "Follow Focus"
+msgstr "Siga o Foco"
+
+msgid "Horizontal Custom Step"
+msgstr "Intervalo Horizontal Personalizado"
+
+msgid "Vertical Custom Step"
+msgstr "Intervalo Personalizado Vertical"
+
+msgid "Horizontal Scroll Mode"
+msgstr "Modo de Rolagem Horizontal"
+
+msgid "Vertical Scroll Mode"
+msgstr "Modo de Rolagem Vertical"
+
+msgid "Scroll Deadzone"
+msgstr "Zona Morta da Rolagem"
+
msgid "Default Scroll Deadzone"
msgstr "Padrão: Rolagem por Zona-Morta"
msgid "Scrollable"
msgstr "Rolagem"
+msgid "Tick Count"
+msgstr "Contador de Marcações"
+
+msgid "Ticks on Borders"
+msgstr "Marcações nas Bordas"
+
+msgid "Update on Text Changed"
+msgstr "Atualizar na Mudança do Texto"
+
+msgid "Custom Arrow Step"
+msgstr "Intervalo de Seta Personalizado"
+
msgid "Split Offset"
-msgstr "Deslocamento de Divisão"
+msgstr "Deslocamento Dividido"
+
+msgid "Collapsed"
+msgstr "Recolhido"
+
+msgid "Dragger Visibility"
+msgstr "Visibilidade do Arrastador"
msgid "Stretch Shrink"
msgstr "Esticar Encolher"
@@ -5166,6 +5314,9 @@ msgstr "Modo Enrolar"
msgid "Syntax Highlighter"
msgstr "Realçar Sintaxe"
+msgid "Fit Content Height"
+msgstr "Ajustar Altura do Conteúdo"
+
msgid "Draw"
msgstr "Desenhar"
@@ -5184,6 +5335,9 @@ msgstr "Flutuar"
msgid "Under"
msgstr "Abaixo"
+msgid "Over"
+msgstr "Por Cima"
+
msgid "Progress Offset"
msgstr "Desvio de Progresso"
@@ -5196,6 +5350,12 @@ msgstr "Preenchimento Radial"
msgid "Fill Degrees"
msgstr "Graus de Preenchimento"
+msgid "Center Offset"
+msgstr "Deslocamento Central"
+
+msgid "Expand Mode"
+msgstr "Modo de Expansão"
+
msgid "Custom Minimum Height"
msgstr "Altura Mínima Personalizada"
@@ -5211,8 +5371,11 @@ msgstr "Pausado"
msgid "Expand"
msgstr "Expandir"
+msgid "Buffering Msec"
+msgstr "Armazenamento ms"
+
msgid "Self Modulate"
-msgstr "Auto Modular"
+msgstr "Auto Modulação"
msgid "Show Behind Parent"
msgstr "Mostrar Atrás do Pai"
@@ -5244,9 +5407,21 @@ msgstr "Repetir"
msgid "Use Parent Material"
msgstr "Usar Material do Pai"
+msgid "Diffuse"
+msgstr "Difusão"
+
msgid "NormalMap"
msgstr "'NormalMap'"
+msgid "Download File"
+msgstr "Arquivo do Download"
+
+msgid "Download Chunk Size"
+msgstr "Tamanho do Bloco do Download"
+
+msgid "Accept Gzip"
+msgstr "Aceitar Gzip"
+
msgid "Body Size Limit"
msgstr "Limite de Medidas de Corpo"
@@ -5268,6 +5443,21 @@ msgstr "Separador Num. de Nome de Nó"
msgid "Node Name Casing"
msgstr "Nome do Nós (Maiúsculas/Minúsculas)"
+msgid "Physics Priority"
+msgstr "Prioridade Física"
+
+msgid "Thread Group"
+msgstr "Grupo da Thread"
+
+msgid "Group"
+msgstr "Grupo"
+
+msgid "Group Order"
+msgstr "Ordem do Grupo"
+
+msgid "Messages"
+msgstr "Mensagens"
+
msgid "Editor Description"
msgstr "Descrição do Editor"
@@ -5280,6 +5470,9 @@ msgstr "Formas"
msgid "Shape Color"
msgstr "Cor da Forma"
+msgid "Contact Color"
+msgstr "Cor de Contato"
+
msgid "Geometry Color"
msgstr "Cor da Geometria"
@@ -5295,6 +5488,12 @@ msgstr "'MSAA 3D'"
msgid "Use Debanding"
msgstr "Usar Debanding"
+msgid "Use Occlusion Culling"
+msgstr "Usa Ocultação de Objetos"
+
+msgid "Mesh LOD"
+msgstr "Malha LOD"
+
msgid "LOD Change"
msgstr "LOD (Nível de Detalhe)"
@@ -5307,6 +5506,9 @@ msgstr "Luzes e Sombras"
msgid "Atlas Size"
msgstr "Tamanho do Atlas"
+msgid "Atlas Quadrant 3 Subdiv"
+msgstr "Quadrante de Subdivisão 3 Atlas"
+
msgid "SDF"
msgstr "SDF"
@@ -5319,6 +5521,9 @@ msgstr "Início Automático"
msgid "Transparent BG"
msgstr "Fundo Transparente"
+msgid "Debug Draw"
+msgstr "Desenho da Depuração"
+
msgid "Scaling 3D"
msgstr "Escala 3D"
@@ -5331,6 +5536,27 @@ msgstr "Taxa variável de Shading"
msgid "Audio Listener"
msgstr "Ouvinte de Áudio"
+msgid "Enable 2D"
+msgstr "Habilitar 2D"
+
+msgid "Enable 3D"
+msgstr "Habilitar 3D"
+
+msgid "Object Picking"
+msgstr "Seleção de Objetos"
+
+msgid "Object Picking Sort"
+msgstr "Seleção Ordenada de Objetos"
+
+msgid "Disable Input"
+msgstr "Input Desativado"
+
+msgid "Positional Shadow Atlas"
+msgstr "Sombra Posicional Atlas"
+
+msgid "16 Bits"
+msgstr "16 Bits"
+
msgid "Quad 0"
msgstr "'Quad 0'"
@@ -5346,12 +5572,36 @@ msgstr "'Quad 3'"
msgid "Canvas Cull Mask"
msgstr "Máscara de tela"
+msgid "Tooltip Delay (sec)"
+msgstr "Delay do Tooltip (seg)"
+
+msgid "Size 2D Override"
+msgstr "Sobreposição de Tamanho 2D"
+
+msgid "Size 2D Override Stretch"
+msgstr "Sobreposição de Tamanho Esticamento 2D"
+
msgid "Render Target"
msgstr "Alvo do Renderizador"
msgid "Current Screen"
msgstr "Tela Atual"
+msgid "Mouse Passthrough Polygon"
+msgstr "Polígono de Passagem do Mouse"
+
+msgid "Wrap Controls"
+msgstr "Ajustar Controles"
+
+msgid "Transient"
+msgstr "Transitória"
+
+msgid "Exclusive"
+msgstr "Exclusivo"
+
+msgid "Unresizable"
+msgstr "Não redimensionável"
+
msgid "Unfocusable"
msgstr "Infocalizável"
@@ -5361,6 +5611,12 @@ msgstr "Tamanho Mínimo"
msgid "Max Size"
msgstr "Tamanho Máximo"
+msgid "2D Render"
+msgstr "Renderização 2D"
+
+msgid "3D Render"
+msgstr "Renderização 3D"
+
msgid "2D Physics"
msgstr "Física 2D"
@@ -5373,12 +5629,48 @@ msgstr "Formato"
msgid "Stereo"
msgstr "Stereo"
+msgid "Profile"
+msgstr "Perfil"
+
+msgid "Bonemap"
+msgstr "Mapeamento dos Bones"
+
+msgid "Exposure"
+msgstr "Exposição"
+
+msgid "Sensitivity"
+msgstr "Sensibilidade"
+
+msgid "Multiplier"
+msgstr "Multiplicador"
+
msgid "Auto Exposure"
msgstr "Auto Exposição"
msgid "DOF Blur"
msgstr "Embaçamento DOF"
+msgid "Far Transition"
+msgstr "Transição à Distância"
+
+msgid "Near Enabled"
+msgstr "Proximidade Ativado"
+
+msgid "Near Distance"
+msgstr "Distância Próxima"
+
+msgid "Near Transition"
+msgstr "Transição Próxima"
+
+msgid "Min Sensitivity"
+msgstr "Min Sensibilidade"
+
+msgid "Max Sensitivity"
+msgstr "Max Sensibilidade"
+
+msgid "Light Mode"
+msgstr "Modo Luz"
+
msgid "Particles Animation"
msgstr "Animação de Partículas"
@@ -5397,20 +5689,92 @@ msgstr "Intervalo de Bake"
msgid "Panel"
msgstr "Painel"
+msgid "Font Hover Color"
+msgstr "Cor da Fonte Hover"
+
+msgid "Font Focus Color"
+msgstr "Cor da Fonte Foco"
+
+msgid "Font Hover Pressed Color"
+msgstr "Cor da Fonte Hover Pressionado"
+
+msgid "Font Disabled Color"
+msgstr "Cor da Fonte Desabilitado"
+
+msgid "Font Outline Color"
+msgstr "Cor do Contorno da Fonte"
+
+msgid "Icon Hover Color"
+msgstr "Cor do Icon Hover"
+
+msgid "Icon Hover Pressed Color"
+msgstr "Cor Icon Hover Pressionado"
+
+msgid "Icon Focus Color"
+msgstr "Cor de Foco do Ícone"
+
+msgid "Icon Disabled Color"
+msgstr "Cor do Ícone Desativado"
+
msgid "H Separation"
msgstr "Separação Horizontal"
+msgid "Icon Max Width"
+msgstr "Largura Máxima do Ícone"
+
+msgid "Underline Spacing"
+msgstr "Espaço Underline"
+
+msgid "Normal Mirrored"
+msgstr "Normal Espelhado"
+
+msgid "Hover Mirrored"
+msgstr "Hover Espelhado"
+
+msgid "Pressed Mirrored"
+msgstr "Pressionamento Espelhado"
+
+msgid "Disabled Mirrored"
+msgstr "Desabilitar Espelhamento"
+
msgid "Arrow"
msgstr "Seta"
+msgid "Arrow Margin"
+msgstr "Margem da Seta"
+
msgid "Modulate Arrow"
-msgstr "Modular Seta"
+msgstr "Modifica a Seta"
+
+msgid "Hover Pressed"
+msgstr "Hover Pressionado"
+
+msgid "Checked Disabled"
+msgstr "Verificado Desativado"
+
+msgid "Unchecked"
+msgstr "Desmarcado"
+
+msgid "Unchecked Disabled"
+msgstr "Desmarcado Desativado"
+
+msgid "Radio Checked"
+msgstr "Radio Marcado"
+
+msgid "Radio Checked Disabled"
+msgstr "Radio Marcado Desativado"
msgid "Radio Unchecked"
-msgstr "Radio não selecionado"
+msgstr "Radio Desmarcado"
msgid "Radio Unchecked Disabled"
-msgstr "Radio não checado desabilitado"
+msgstr "Radio Desmarcado Desabilitado"
+
+msgid "Check V Offset"
+msgstr "Deslocamento V Verificadores"
+
+msgid "Checked Mirrored"
+msgstr "Verificação Espelhada"
msgid "Shadow Offset X"
msgstr "Deslocamento da Sombra em X"
@@ -5418,6 +5782,9 @@ msgstr "Deslocamento da Sombra em X"
msgid "Shadow Offset Y"
msgstr "Deslocamento da Sombra em Y"
+msgid "Caret Width"
+msgstr "Largura do Cursor"
+
msgid "Clear"
msgstr "Limpar"
@@ -5430,6 +5797,9 @@ msgstr "Dobrado"
msgid "Folded EOL Icon"
msgstr "Ícone EOL dobrado"
+msgid "Scroll Focus"
+msgstr "Foco do Scroll"
+
msgid "Grabber"
msgstr "Agarrador"
@@ -5451,6 +5821,9 @@ msgstr "Destaque de Área Agarrada"
msgid "Tick"
msgstr "Marcação"
+msgid "Center Grabber"
+msgstr "Agarrador Central"
+
msgid "Updown"
msgstr "De cima para baixo"
@@ -5463,6 +5836,9 @@ msgstr "Modular Contorno do Título"
msgid "Close"
msgstr "Fechar"
+msgid "Close V Offset"
+msgstr "Deslocamento V do Fechar"
+
msgid "Reload"
msgstr "Recarregar"
@@ -5475,15 +5851,36 @@ msgstr "Arquivo"
msgid "Separator"
msgstr "Separador"
+msgid "Labeled Separator Left"
+msgstr "Esquerda do Separador Rotulado"
+
+msgid "Labeled Separator Right"
+msgstr "Direita do Separador Rotulado"
+
msgid "Submenu"
msgstr "Sub-menu"
msgid "V Separation"
msgstr "Separação Vertical"
+msgid "Item Start Padding"
+msgstr "Margem inicial do item"
+
+msgid "Item End Padding"
+msgstr "Margem Final do Item"
+
+msgid "Selected Frame"
+msgstr "Frame Selecionado"
+
+msgid "Comment Focus"
+msgstr "Foco de Comentário"
+
msgid "Slot"
msgstr "'Slot'"
+msgid "Resizer"
+msgstr "Redimensionador"
+
msgid "Port Offset"
msgstr "Deslocamento de Porta"
@@ -5493,6 +5890,9 @@ msgstr "Ponteiro"
msgid "Cursor Unfocused"
msgstr "Cursor Desfocado"
+msgid "Title Button Normal"
+msgstr "Padrão do Botão de Título"
+
msgid "Custom Button Font Highlight"
msgstr "Destaque de Fonte de Botão Personalizado"
diff --git a/editor/translations/properties/ru.po b/editor/translations/properties/ru.po
index 2a3b553500..c5064d07a0 100644
--- a/editor/translations/properties/ru.po
+++ b/editor/translations/properties/ru.po
@@ -144,13 +144,14 @@
# Mmaxum <max55926@yandex.ru>, 2023.
# ZIP2020 <folstagking@gmail.com>, 2023.
# Daniil Ryakhinov <danik.relien@gmail.com>, 2023.
+# 0que <0que@users.noreply.hosted.weblate.org>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-15 16:33+0000\n"
-"Last-Translator: Daniil Ryakhinov <danik.relien@gmail.com>\n"
+"PO-Revision-Date: 2023-08-30 14:58+0000\n"
+"Last-Translator: 0que <0que@users.noreply.hosted.weblate.org>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot-properties/ru/>\n"
"Language: ru\n"
@@ -159,7 +160,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Приложение"
@@ -269,6 +270,9 @@ msgstr "Не выключать экран"
msgid "Audio"
msgstr "Аудио"
+msgid "Buses"
+msgstr "Шины"
+
msgid "Default Bus Layout"
msgstr "Значение по умолчанию включено"
@@ -338,6 +342,9 @@ msgstr "Сжатие"
msgid "Formats"
msgstr "Форматы"
+msgid "Zstd"
+msgstr "Zstd"
+
msgid "Long Distance Matching"
msgstr "Сравнение Длинных Дистанций"
@@ -347,6 +354,12 @@ msgstr "Уровень сжатия"
msgid "Window Log Size"
msgstr "Размер Лога Окна"
+msgid "Zlib"
+msgstr "Zlib"
+
+msgid "Gzip"
+msgstr "Gzip"
+
msgid "Crash Handler"
msgstr "Обработчик падений"
@@ -356,6 +369,9 @@ msgstr "Сообщение"
msgid "Rendering"
msgstr "*Рендеринг*"
+msgid "Occlusion Culling"
+msgstr "Occlusion Culling"
+
msgid "BVH Build Quality"
msgstr "Качество сборки BVH"
@@ -368,6 +384,9 @@ msgstr "Ограничения"
msgid "Multithreaded Server"
msgstr "Многопоточный сервер"
+msgid "RID Pool Prealloc"
+msgstr "Предварительное распределение пула RID"
+
msgid "Internationalization"
msgstr "Интернационализация"
@@ -389,6 +408,9 @@ msgstr "Максимальный интервал инкрементного п
msgid "Common"
msgstr "Общий"
+msgid "Snap Controls to Pixels"
+msgstr "Пиксельная привязка управления"
+
msgid "Fonts"
msgstr "Шрифты"
@@ -401,6 +423,9 @@ msgstr "Использовать передискретизацию"
msgid "Rendering Device"
msgstr "Устройство рендеринга"
+msgid "Staging Buffer"
+msgstr "Промежуточный буфер"
+
msgid "Block Size (KB)"
msgstr "Размер блока (КБ)"
@@ -413,6 +438,9 @@ msgstr "Размер области текстуры Px"
msgid "Pipeline Cache"
msgstr "Кэш конвеера"
+msgid "Save Chunk Size (MB)"
+msgstr "Сохранить размер блока (МБ)"
+
msgid "Vulkan"
msgstr "Vulkan"
@@ -422,18 +450,36 @@ msgstr "Макс. дескрипторов на пул"
msgid "Textures"
msgstr "Текстуры"
+msgid "Canvas Textures"
+msgstr "Текстура холста"
+
+msgid "Default Texture Filter"
+msgstr "Фильтр текстур по умолчанию"
+
+msgid "Default Texture Repeat"
+msgstr "Повторение текстур по умолчанию"
+
msgid "Low Processor Usage Mode"
msgstr "Режим низкой нагрузки процессора"
msgid "Low Processor Usage Mode Sleep (µsec)"
msgstr "Задержка в режиме низкой нагрузки процессора (мксек)"
+msgid "Delta Smoothing"
+msgstr "Дельта сглаживание"
+
msgid "Print Error Messages"
msgstr "Печатать сообщения об ошибках"
msgid "Physics Ticks per Second"
msgstr "Частота обновления физических кадров"
+msgid "Max Physics Steps per Frame"
+msgstr "Макс. количество физических шагов на кадр"
+
+msgid "Max FPS"
+msgstr "Макс. FPS"
+
msgid "Time Scale"
msgstr "Масштаб времени"
@@ -449,15 +495,42 @@ msgstr "Использовать накопленный ввод"
msgid "Input Devices"
msgstr "Устройства ввода"
+msgid "Compatibility"
+msgstr "Совместимость"
+
msgid "Device"
msgstr "Устройство"
+msgid "Window ID"
+msgstr "Идентификатор окна"
+
+msgid "Command or Control Autoremap"
+msgstr "Команда или управление автоперестановка"
+
+msgid "Alt Pressed"
+msgstr "Нажатие Alt"
+
+msgid "Shift Pressed"
+msgstr "Нажатие Shift"
+
+msgid "Ctrl Pressed"
+msgstr "Нажатие Ctrl"
+
+msgid "Meta Pressed"
+msgstr "Нажато Meta"
+
msgid "Pressed"
msgstr "Нажато"
msgid "Keycode"
msgstr "Код клавиши"
+msgid "Physical Keycode"
+msgstr "Физический код клавиши"
+
+msgid "Key Label"
+msgstr "Метка клавиши"
+
msgid "Unicode"
msgstr "Unicode"
@@ -479,6 +552,9 @@ msgstr "Множитель"
msgid "Button Index"
msgstr "Индекс кнопки"
+msgid "Canceled"
+msgstr "Отменено"
+
msgid "Double Click"
msgstr "Двойной щелчок"
@@ -506,6 +582,9 @@ msgstr "Значение оси"
msgid "Index"
msgstr "Индекс"
+msgid "Double Tap"
+msgstr "Двойное касание"
+
msgid "Action"
msgstr "Действие"
@@ -533,6 +612,15 @@ msgstr "Значение контроллера"
msgid "Shortcut"
msgstr "Ярлык"
+msgid "Events"
+msgstr "События"
+
+msgid "Include Navigational"
+msgstr "Включить навигацию"
+
+msgid "Include Hidden"
+msgstr "Включить скрытый"
+
msgid "Big Endian"
msgstr "Прямой порядок байтов"
@@ -560,6 +648,9 @@ msgstr "Максимальный размер исходящего буфера"
msgid "Resource"
msgstr "Ресурс"
+msgid "Local to Scene"
+msgstr "Локальный для сцены"
+
msgid "Path"
msgstr "Путь"
@@ -578,24 +669,57 @@ msgstr "Отступ"
msgid "Cell Size"
msgstr "Размер ячейки"
+msgid "Jumping Enabled"
+msgstr "Прыжки включены"
+
+msgid "Default Compute Heuristic"
+msgstr "Эвристика расчета по умолчанию"
+
+msgid "Default Estimate Heuristic"
+msgstr "Эвристика оценок по умолчанию"
+
+msgid "Diagonal Mode"
+msgstr "Диагональный режим"
+
msgid "Seed"
msgstr "Зерно"
msgid "State"
msgstr "Состояние"
+msgid "Message Queue"
+msgstr "Список сообщений"
+
msgid "Network"
msgstr "Сеть"
+msgid "TCP"
+msgstr "TCP"
+
+msgid "Connect Timeout Seconds"
+msgstr "Время ожидания соединения в секундах"
+
+msgid "Packet Peer Stream"
+msgstr "Пакетный одно ранговый поток"
+
msgid "Max Buffer (Power of 2)"
msgstr "Максимальный буфер (Уровень 2)"
msgid "TLS"
msgstr "TLS"
+msgid "Certificate Bundle Override"
+msgstr "Переназначение пакета сертификатов"
+
+msgid "Threading"
+msgstr "Потоки"
+
msgid "Worker Pool"
msgstr "Рабочий пул"
+msgid "Max Threads"
+msgstr "Макс. потоков"
+
msgid "Use System Threads for Low Priority Tasks"
msgstr "Использовать потоки системы для низкоприоритеных задач"
@@ -611,12 +735,36 @@ msgstr "Тест"
msgid "Fallback"
msgstr "Запасной вариант"
+msgid "Pseudolocalization"
+msgstr "Псевдолокализация"
+
+msgid "Use Pseudolocalization"
+msgstr "Использовать псевдолокализацию"
+
+msgid "Replace With Accents"
+msgstr "Заменить с акцентами"
+
+msgid "Double Vowels"
+msgstr "Удвоенные гласные"
+
+msgid "Fake BiDi"
+msgstr "Ложный BiDi"
+
+msgid "Override"
+msgstr "Переопределить"
+
+msgid "Expansion Ratio"
+msgstr "Коэффициент расширения"
+
msgid "Prefix"
msgstr "Префикс"
msgid "Suffix"
msgstr "Суффикс"
+msgid "Skip Placeholders"
+msgstr "Пропустить заполнитель"
+
msgid "Rotation"
msgstr "Поворот"
@@ -638,6 +786,9 @@ msgstr "Задать обработчик"
msgid "Out Handle"
msgstr "Задать обработчик"
+msgid "Handle Mode"
+msgstr "Ручной режим"
+
msgid "Stream"
msgstr "Поток"
@@ -653,9 +804,18 @@ msgstr "Анимация"
msgid "Easing"
msgstr "Облегчение"
+msgid "Debug Adapter"
+msgstr "Отладочный адаптер"
+
msgid "Remote Port"
msgstr "Удалённый порт"
+msgid "Request Timeout"
+msgstr "Время ожидания запроса"
+
+msgid "Sync Breakpoints"
+msgstr "Синхронизация точек остановки"
+
msgid "FileSystem"
msgstr "Файловая система"
@@ -671,6 +831,12 @@ msgstr "Пароль"
msgid "Default Feature Profile"
msgstr "Профиль возможностей по умолчанию"
+msgid "Version Hash"
+msgstr "Хэш версии"
+
+msgid "Classes"
+msgstr "Классы"
+
msgid "Text Editor"
msgstr "Текстовый редактор"
@@ -692,12 +858,21 @@ msgstr "Отмечаемый"
msgid "Checked"
msgstr "Отмеченный"
+msgid "Draw Warning"
+msgstr "Предупреждение рисования"
+
msgid "Keying"
msgstr "Вставка ключей"
+msgid "Deletable"
+msgstr "Удаляемый"
+
msgid "Distraction Free Mode"
msgstr "Режим без отвлечения"
+msgid "Movie Maker Enabled"
+msgstr "Movie Maker Включен"
+
msgid "Interface"
msgstr "Интерфейс"
@@ -848,6 +1023,9 @@ msgstr "Включить долгие нажатия ПКМ"
msgid "Enable Pan and Scale Gestures"
msgstr "Включить касания щипка и увеличения"
+msgid "Scale Gizmo Handles"
+msgstr "Масштаб Гизмо Дескрипторы"
+
msgid "Show Script Button"
msgstr "Показать кнопку скрипта"
@@ -4379,6 +4557,9 @@ msgstr "Персональная сеть"
msgid "Release (ms)"
msgstr "Релиз (мс)"
+msgid "Sidechain"
+msgstr "Боковая цепь"
+
msgid "Tap 1"
msgstr "Нажмите 1"
diff --git a/editor/translations/properties/tr.po b/editor/translations/properties/tr.po
index b12e459a9d..291899e23f 100644
--- a/editor/translations/properties/tr.po
+++ b/editor/translations/properties/tr.po
@@ -99,8 +99,8 @@ msgstr ""
"Project-Id-Version: Godot Engine properties\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-08-16 20:55+0000\n"
-"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
+"PO-Revision-Date: 2023-09-08 02:18+0000\n"
+"Last-Translator: Yılmaz Durmaz <yilmaz_durmaz@hotmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot-properties/tr/>\n"
"Language: tr\n"
@@ -108,7 +108,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "Uygulama"
@@ -345,7 +345,7 @@ msgid "Root Node Layout Direction"
msgstr "Kök Düğüm Yerleşim Düzeni Yönü"
msgid "GUI"
-msgstr "Grafiksel Kullanıcı Arayüzü"
+msgstr "Grafiksel Kullanıcı Arayüzü (GUI)"
msgid "Timers"
msgstr "Zamanlayıcılar"
@@ -678,7 +678,7 @@ msgid "Low Priority Thread Ratio"
msgstr "Düşük Öncelikli İş Parçacığı Oranı"
msgid "Locale"
-msgstr "Yerel"
+msgstr "Yerel kodu"
msgid "Test"
msgstr "Deneme"
@@ -1152,7 +1152,7 @@ msgid "Highlight All Occurrences"
msgstr "Tüm Bulunanları Vurgula"
msgid "Guidelines"
-msgstr "Kılavuz çizgiler"
+msgstr "Kılavuzlar"
msgid "Show Line Length Guidelines"
msgstr "Satır Uzunluğu Kılavuz Çizgilerini Göster"
@@ -1956,7 +1956,7 @@ msgid "Channel Pack"
msgstr "Kanal Paketi"
msgid "Mipmaps"
-msgstr "Mip-haritalar"
+msgstr "Mip-haritaları"
msgid "Generate"
msgstr "Üret"
@@ -2016,7 +2016,7 @@ msgid "Advanced"
msgstr "Gelişmiş"
msgid "Precision"
-msgstr "Keskinik"
+msgstr "Kesinlik"
msgid "Max Concavity"
msgstr "En Fazla İçbükeylik"
@@ -2205,7 +2205,7 @@ msgid "Size Limit"
msgstr "Boyut Sınırı"
msgid "Detect 3D"
-msgstr "3D Algıla"
+msgstr "3B Algıla"
msgid "Compress To"
msgstr "Şuna Sıkıştır"
@@ -4212,7 +4212,7 @@ msgid "Icon 512 X 512"
msgstr "Simge 512 X 512"
msgid "Windows"
-msgstr "Pencereler"
+msgstr "Windows"
msgid "rcedit"
msgstr "rcedit"
@@ -4476,7 +4476,7 @@ msgid "Lifetime Randomness"
msgstr "Yaşam süresi Rastgeleliği"
msgid "Fixed FPS"
-msgstr "FPS'yi Sabitle"
+msgstr "Sabit FPS"
msgid "Fract Delta"
msgstr "Kesirli Delta"
@@ -6105,7 +6105,7 @@ msgid "Reset"
msgstr "Sıfırla"
msgid "Switch"
-msgstr "Değiştir"
+msgstr "Switch"
msgid "Switch Mode"
msgstr "Kipi Değiştir"
@@ -7620,7 +7620,7 @@ msgid "Tab"
msgstr "Sekme"
msgid "Space"
-msgstr "Boşluk"
+msgstr "Uzay"
msgid "Font Readonly Color"
msgstr "Yazıtipi Sadece Okunabilir Rengi"
diff --git a/editor/translations/properties/zh_CN.po b/editor/translations/properties/zh_CN.po
index 0bfe37e591..f0b6e9b716 100644
--- a/editor/translations/properties/zh_CN.po
+++ b/editor/translations/properties/zh_CN.po
@@ -88,13 +88,14 @@
# 1104 EXSPIRAVIT_ <m18621006730@gmail.com>, 2022.
# ChairC <974833488@qq.com>, 2022.
# dmit-225 <c3204835842@icloud.com>, 2023.
+# GT-610 <myddz1005@163.com>, 2023.
msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2023-07-12 02:49+0000\n"
-"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
+"PO-Revision-Date: 2023-08-25 09:47+0000\n"
+"Last-Translator: GT-610 <myddz1005@163.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot-properties/zh_Hans/>\n"
"Language: zh_CN\n"
@@ -102,7 +103,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.0-dev\n"
+"X-Generator: Weblate 5.0.1-dev\n"
msgid "Application"
msgstr "应用"
@@ -4356,7 +4357,7 @@ msgid "Left"
msgstr "左"
msgid "Top"
-msgstr "顶"
+msgstr "顶部"
msgid "Right"
msgstr "右"
diff --git a/editor/window_wrapper.cpp b/editor/window_wrapper.cpp
index 91d5aa8860..2570574823 100644
--- a/editor/window_wrapper.cpp
+++ b/editor/window_wrapper.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
@@ -150,7 +151,7 @@ void WindowWrapper::_notification(int p_what) {
set_process_shortcut_input(true);
} break;
case NOTIFICATION_THEME_CHANGED: {
- window_background->add_theme_style_override("panel", get_theme_stylebox("PanelForeground", "EditorStyles"));
+ window_background->add_theme_style_override("panel", get_theme_stylebox("PanelForeground", EditorStringName(EditorStyles)));
} break;
}
}
@@ -360,7 +361,7 @@ void ScreenSelect::_build_advanced_menu() {
button->set_tooltip_text(vformat(TTR("Make this panel floating in the screen %d."), i));
if (i == current_screen) {
- Color accent_color = get_theme_color("accent_color", "Editor");
+ Color accent_color = get_theme_color("accent_color", EditorStringName(Editor));
button->add_theme_color_override("font_color", accent_color);
}
@@ -384,8 +385,8 @@ void ScreenSelect::_notification(int p_what) {
connect("gui_input", callable_mp(this, &ScreenSelect::_handle_mouse_shortcut));
} break;
case NOTIFICATION_THEME_CHANGED: {
- set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("MakeFloating", "EditorIcons"));
- popup_background->add_theme_style_override("panel", get_theme_stylebox("PanelForeground", "EditorStyles"));
+ set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("MakeFloating"));
+ popup_background->add_theme_style_override("panel", get_theme_stylebox("PanelForeground", EditorStringName(EditorStyles)));
const real_t popup_height = real_t(get_theme_font_size("font_size")) * 2.0;
popup->set_min_size(Size2(0, popup_height * 3));
diff --git a/main/main.cpp b/main/main.cpp
index 0a9ebd4c61..32262b50b3 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -570,9 +570,15 @@ Error Main::test_setup() {
ResourceLoader::load_path_remaps();
+ // Initialize ThemeDB early so that scene types can register their theme items.
+ // Default theme will be initialized later, after modules and ScriptServer are ready.
+ initialize_theme_db();
+
register_scene_types();
register_driver_types();
+ register_scene_singletons();
+
initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SCENE);
@@ -588,9 +594,7 @@ Error Main::test_setup() {
register_platform_apis();
// Theme needs modules to be initialized so that sub-resources can be loaded.
- initialize_theme_db();
- theme_db->initialize_theme();
- register_scene_singletons();
+ theme_db->initialize_theme_noproject();
initialize_navigation_server();
@@ -723,8 +727,7 @@ int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
* responsible for the initialization of all low level singletons and core types, and parsing
* command line arguments to configure things accordingly.
* If p_second_phase is true, it will chain into setup2() (default behavior). This is
- * disabled on some platforms (Android, iOS, UWP) which trigger the second step in their
- * own time.
+ * disabled on some platforms (Android, iOS) which trigger the second step in their own time.
*
* - setup2(p_main_tid_override) registers high level servers and singletons, displays the
* boot splash, then registers higher level types (scene, editor, etc.).
@@ -2561,9 +2564,15 @@ Error Main::setup2() {
OS::get_singleton()->benchmark_begin_measure("scene");
+ // Initialize ThemeDB early so that scene types can register their theme items.
+ // Default theme will be initialized later, after modules and ScriptServer are ready.
+ initialize_theme_db();
+
register_scene_types();
register_driver_types();
+ register_scene_singletons();
+
initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SCENE);
@@ -2581,11 +2590,6 @@ Error Main::setup2() {
register_platform_apis();
- // Theme needs modules to be initialized so that sub-resources can be loaded.
- // Default theme is initialized later, after ScriptServer is ready.
- initialize_theme_db();
- register_scene_singletons();
-
GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/mouse_cursor/custom_image", PROPERTY_HINT_FILE, "*.png,*.webp"), String());
GLOBAL_DEF_BASIC("display/mouse_cursor/custom_image_hotspot", Vector2());
GLOBAL_DEF_BASIC("display/mouse_cursor/tooltip_position_offset", Point2(10, 10));
diff --git a/methods.py b/methods.py
index 97e9026fea..a6416ccdd2 100644
--- a/methods.py
+++ b/methods.py
@@ -776,8 +776,18 @@ def add_to_vs_project(env, sources):
env.vs_srcs += [basename + ".cpp"]
-def generate_vs_project(env, num_jobs, project_name="godot"):
+def generate_vs_project(env, original_args, project_name="godot"):
batch_file = find_visual_c_batch_file(env)
+ filtered_args = original_args.copy()
+ # Ignore the "vsproj" option to not regenerate the VS project on every build
+ filtered_args.pop("vsproj", None)
+ # The "platform" option is ignored because only the Windows platform is currently supported for VS projects
+ filtered_args.pop("platform", None)
+ # The "target" option is ignored due to the way how targets configuration is performed for VS projects (there is a separate project configuration for each target)
+ filtered_args.pop("target", None)
+ # The "progress" option is ignored as the current compilation progress indication doesn't work in VS
+ filtered_args.pop("progress", None)
+
if batch_file:
class ModuleConfigs(Mapping):
@@ -853,29 +863,10 @@ def generate_vs_project(env, num_jobs, project_name="godot"):
"platform=windows",
f"target={configuration_getter}",
"progress=no",
- "-j%s" % num_jobs,
]
- if env["dev_build"]:
- common_build_postfix.append("dev_build=yes")
-
- if env["dev_mode"]:
- common_build_postfix.append("dev_mode=yes")
-
- elif env["tests"]:
- common_build_postfix.append("tests=yes")
-
- if env["custom_modules"]:
- common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
-
- if env["windows_subsystem"] == "console":
- common_build_postfix.append("windows_subsystem=console")
-
- if env["precision"] == "double":
- common_build_postfix.append("precision=double")
-
- if env["incremental_link"]:
- common_build_postfix.append("incremental_link=yes")
+ for arg, value in filtered_args.items():
+ common_build_postfix.append(f"{arg}={value}")
result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
return result
diff --git a/misc/dist/uwp_template/AppxManifest.xml b/misc/dist/uwp_template/AppxManifest.xml
deleted file mode 100644
index c25be4add2..0000000000
--- a/misc/dist/uwp_template/AppxManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp build" xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build">
- <Identity Name="$identity_name$" Publisher="$publisher$" Version="$version_string$" ProcessorArchitecture="$architecture$" />
- <mp:PhoneIdentity PhoneProductId="$product_guid$" PhonePublisherId="$publisher_guid$" />
- <Properties>
- <DisplayName>$display_name$</DisplayName>
- <PublisherDisplayName>$publisher_display_name$</PublisherDisplayName>
- <Logo>Assets\StoreLogo.png</Logo>
- </Properties>
- <Dependencies>
- <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0" MaxVersionTested="10.0.14393.0" />
- <PackageDependency Name="Microsoft.VCLibs.140.00" MinVersion="14.0.24123.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
- </Dependencies>
- <Resources>
- <Resource Language="EN-US" />
- </Resources>
- <Applications>
- <Application Id="App" Executable="godot.uwp.exe" EntryPoint="GodotUWP.App">
- <uap:VisualElements DisplayName="$display_name$" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="$app_description$" BackgroundColor="$bg_color$">
- <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\Square310x310Logo.png" Square71x71Logo="Assets\Square71x71Logo.png" ShortName="$short_name$">
- $name_on_tiles$
- </uap:DefaultTile>
- <uap:SplashScreen Image="Assets\SplashScreen.png" />
- $rotation_preference$
- </uap:VisualElements>
- </Application>
- </Applications>
- $capabilities_place$
- <build:Metadata>
- <build:Item Name="GodotEngine" Version="$godot_version$" />
- </build:Metadata>
-</Package>
diff --git a/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png b/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png
deleted file mode 100644
index a4dd3d7175..0000000000
--- a/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png
deleted file mode 100644
index 96871f7413..0000000000
--- a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png
deleted file mode 100644
index 96494b1020..0000000000
--- a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png
deleted file mode 100644
index d21bc42009..0000000000
--- a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png
deleted file mode 100644
index 22a43cf95f..0000000000
--- a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png b/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png
deleted file mode 100644
index 3960b0424b..0000000000
--- a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png
deleted file mode 100644
index d836e113b1..0000000000
--- a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png
+++ /dev/null
Binary files differ
diff --git a/misc/extension_api_validation/4.1-stable.expected b/misc/extension_api_validation/4.1-stable.expected
index ff66f9d51d..39eba9642b 100644
--- a/misc/extension_api_validation/4.1-stable.expected
+++ b/misc/extension_api_validation/4.1-stable.expected
@@ -116,3 +116,63 @@ Validate extension JSON: API was removed: classes/GLTFDocumentExtensionPhysics
Validate extension JSON: API was removed: classes/GLTFDocumentExtensionTextureWebP
Excluded unexposed classes from extension_api.json.
+
+GH-79311
+--------
+
+Validate extension JSON: API was removed: classes/GraphEdit/signals/delete_nodes_request
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_color
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_count
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_height
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_position
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_slot
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_input_type
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_color
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_count
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_height
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_position
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_slot
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_connection_output_type
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_language
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_overlay
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_position_offset
+Validate extension JSON: API was removed: classes/GraphNode/methods/get_text_direction
+Validate extension JSON: API was removed: classes/GraphNode/methods/is_close_button_visible
+Validate extension JSON: API was removed: classes/GraphNode/methods/is_draggable
+Validate extension JSON: API was removed: classes/GraphNode/methods/is_resizable
+Validate extension JSON: API was removed: classes/GraphNode/methods/is_selectable
+Validate extension JSON: API was removed: classes/GraphNode/methods/is_selected
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_draggable
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_language
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_overlay
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_position_offset
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_resizable
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_selectable
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_selected
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_show_close_button
+Validate extension JSON: API was removed: classes/GraphNode/methods/set_text_direction
+Validate extension JSON: API was removed: classes/GraphNode/properties/draggable
+Validate extension JSON: API was removed: classes/GraphNode/properties/language
+Validate extension JSON: API was removed: classes/GraphNode/properties/overlay
+Validate extension JSON: API was removed: classes/GraphNode/properties/position_offset
+Validate extension JSON: API was removed: classes/GraphNode/properties/resizable
+Validate extension JSON: API was removed: classes/GraphNode/properties/selectable
+Validate extension JSON: API was removed: classes/GraphNode/properties/selected
+Validate extension JSON: API was removed: classes/GraphNode/properties/show_close
+Validate extension JSON: API was removed: classes/GraphNode/properties/text_direction
+Validate extension JSON: API was removed: classes/GraphNode/signals/close_request
+Validate extension JSON: API was removed: classes/GraphNode/signals/dragged
+Validate extension JSON: API was removed: classes/GraphNode/signals/node_deselected
+Validate extension JSON: API was removed: classes/GraphNode/signals/node_selected
+Validate extension JSON: API was removed: classes/GraphNode/signals/position_offset_changed
+Validate extension JSON: API was removed: classes/GraphNode/signals/raise_request
+Validate extension JSON: API was removed: classes/GraphNode/signals/resize_request
+
+Refactor GraphNode (splitup in GraphElement and GraphNode)
+GH-81070
+--------
+Validate extension JSON: API was removed: classes/TileMap/methods/get_quadrant_size
+Validate extension JSON: API was removed: classes/TileMap/methods/set_quadrant_size
+Validate extension JSON: API was removed: classes/TileMap/properties/cell_quadrant_size
+
+cell_quadrant_size/quadrant_size of the TileMap API was renamed to rendering_quadrant_size.
diff --git a/misc/scripts/validate_extension_api.sh b/misc/scripts/validate_extension_api.sh
index 75f03a7086..cde7a8574d 100755
--- a/misc/scripts/validate_extension_api.sh
+++ b/misc/scripts/validate_extension_api.sh
@@ -58,7 +58,7 @@ while read -r file; do
get_expected_output "$file"
# Download the reference extension_api.json
- wget -qcO "$reference_file" "https://raw.githubusercontent.com/godotengine/godot-cpp/godot-$reference_tag/gdextension/extension_api.json"
+ wget -nv --retry-on-http-error=503 --tries=5 --timeout=60 -cO "$reference_file" "https://raw.githubusercontent.com/godotengine/godot-cpp/godot-$reference_tag/gdextension/extension_api.json" || has_problems=1
# Validate the current API against the reference
"$1" --headless --validate-extension-api "$reference_file" 2>&1 | tee "$validate" | awk '!/^Validate extension JSON:/' - || true
# Collect the expected and actual validation errors
diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub
index 421f200f1a..2813eaecd5 100644
--- a/modules/freetype/SCsub
+++ b/modules/freetype/SCsub
@@ -61,12 +61,6 @@ if env["builtin_freetype"]:
if env["brotli"]:
env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
- if env["platform"] == "uwp":
- # Include header for UWP to fix build issues
- env_freetype.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
- # Globally too, as freetype is used in scene (see bottom)
- env.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
-
env_freetype.Prepend(CPPPATH=[thirdparty_dir + "/include"])
# Also needed in main env for scene/
env.Prepend(CPPPATH=[thirdparty_dir + "/include"])
diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp
index 265e624b6c..199ea81330 100644
--- a/modules/gdscript/gdscript_rpc_callable.cpp
+++ b/modules/gdscript/gdscript_rpc_callable.cpp
@@ -30,6 +30,7 @@
#include "gdscript_rpc_callable.h"
+#include "core/object/script_language.h"
#include "core/templates/hashfuncs.h"
#include "scene/main/node.h"
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index 91271da331..3787d0fe5e 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "main/main.h"
#include "scene/gui/line_edit.h"
@@ -366,10 +367,10 @@ void EditorFileSystemImportFormatSupportQueryBlend::_validate_path(String p_path
path_status->set_text(error);
if (success) {
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
configure_blender_dialog->get_ok_button()->set_disabled(false);
} else {
- path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
configure_blender_dialog->get_ok_button()->set_disabled(true);
}
}
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 74de40e901..984052d2ca 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -5802,10 +5802,14 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
if (!current_node) {
if (gltf_node->skin >= 0 && gltf_node->mesh >= 0 && !gltf_node->children.is_empty()) {
+ // GLTF specifies that skinned meshes should ignore their node transforms,
+ // only being controlled by the skeleton, so Godot will reparent a skinned
+ // mesh to its skeleton. However, we still need to ensure any child nodes
+ // keep their place in the tree, so if there are any child nodes, the skinned
+ // mesh must not be the base node, so generate an empty spatial base.
current_node = _generate_spatial(p_state, p_node_index);
Node3D *mesh_inst = _generate_mesh_instance(p_state, p_node_index);
mesh_inst->set_name(gltf_node->get_name());
-
current_node->add_child(mesh_inst, true);
} else if (gltf_node->mesh >= 0) {
current_node = _generate_mesh_instance(p_state, p_node_index);
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp
index 0c9f8fb3e0..f96cc86142 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
@@ -1059,10 +1060,10 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
}
void GridMapEditor::_update_theme() {
- options->set_icon(get_theme_icon(SNAME("GridMap"), SNAME("EditorIcons")));
- search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- mode_thumbnail->set_icon(get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons")));
- mode_list->set_icon(get_theme_icon(SNAME("FileList"), SNAME("EditorIcons")));
+ options->set_icon(get_theme_icon(SNAME("GridMap"), EditorStringName(EditorIcons)));
+ search_box->set_right_icon(get_theme_icon(SNAME("Search"), EditorStringName(EditorIcons)));
+ mode_thumbnail->set_icon(get_theme_icon(SNAME("FileThumbnail"), EditorStringName(EditorIcons)));
+ mode_list->set_icon(get_theme_icon(SNAME("FileList"), EditorStringName(EditorIcons)));
}
void GridMapEditor::_notification(int p_what) {
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 5cec8f41f5..e5469c4980 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -3,11 +3,11 @@ import os.path
def is_desktop(platform):
- return platform in ["windows", "macos", "linuxbsd", "uwp", "haiku"]
+ return platform in ["windows", "macos", "linuxbsd"]
def is_unix_like(platform):
- return platform in ["macos", "linuxbsd", "android", "haiku", "ios"]
+ return platform in ["macos", "linuxbsd", "android", "ios"]
def module_supports_tools_on(platform):
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 2b2a8d6235..9846d60c33 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -1,5 +1,5 @@
-# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "android", "haiku", "web", "ios"]
-# Eventually support for each them should be added back (except Haiku if not supported by .NET Core)
+# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "android", "web", "ios"]
+# Eventually support for each them should be added back.
supported_platforms = ["windows", "macos", "linuxbsd", "android"]
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index b0bee795f8..6677d77559 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -84,8 +84,6 @@
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'windows' ">GODOT_WINDOWS;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'linuxbsd' ">GODOT_LINUXBSD;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'macos' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants>
- <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'uwp' ">GODOT_UWP;GODOT_PC</GodotPlatformConstants>
- <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'haiku' ">GODOT_HAIKU;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'android' ">GODOT_ANDROID;GODOT_MOBILE</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'ios' ">GODOT_IPHONE;GODOT_IOS;GODOT_MOBILE</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'web' ">GODOT_JAVASCRIPT;GODOT_HTML5;GODOT_WASM;GODOT_WEB</GodotPlatformConstants>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 94efcba3f1..b16adb6f55 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -592,7 +592,6 @@ MONO_AOT_MODE_LAST = 1000,
switch (platform)
{
case OS.Platforms.Windows:
- case OS.Platforms.UWP:
{
return $"windows-{arch}";
}
@@ -604,10 +603,6 @@ MONO_AOT_MODE_LAST = 1000,
{
return $"linux-{arch}";
}
- case OS.Platforms.Haiku:
- {
- return $"{platform}-{arch}";
- }
default:
throw new NotSupportedException($"Platform not supported: {platform}");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index c16f803226..bff0c0df7c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -26,8 +26,6 @@ namespace GodotTools.Utils
public const string FreeBSD = "FreeBSD";
public const string NetBSD = "NetBSD";
public const string BSD = "BSD";
- public const string UWP = "UWP";
- public const string Haiku = "Haiku";
public const string Android = "Android";
public const string iOS = "iOS";
public const string Web = "Web";
@@ -41,8 +39,6 @@ namespace GodotTools.Utils
public const string Windows = "windows";
public const string MacOS = "macos";
public const string LinuxBSD = "linuxbsd";
- public const string UWP = "uwp";
- public const string Haiku = "haiku";
public const string Android = "android";
public const string iOS = "ios";
public const string Web = "web";
@@ -71,8 +67,6 @@ namespace GodotTools.Utils
["Windows"] = Platforms.Windows,
["macOS"] = Platforms.MacOS,
["Linux"] = Platforms.LinuxBSD,
- ["UWP"] = Platforms.UWP,
- ["Haiku"] = Platforms.Haiku,
["Android"] = Platforms.Android,
["iOS"] = Platforms.iOS,
["Web"] = Platforms.Web
@@ -86,8 +80,6 @@ namespace GodotTools.Utils
[Names.FreeBSD] = Platforms.LinuxBSD,
[Names.NetBSD] = Platforms.LinuxBSD,
[Names.BSD] = Platforms.LinuxBSD,
- [Names.UWP] = Platforms.UWP,
- [Names.Haiku] = Platforms.Haiku,
[Names.Android] = Platforms.Android,
[Names.iOS] = Platforms.iOS,
[Names.Web] = Platforms.Web
@@ -102,7 +94,6 @@ namespace GodotTools.Utils
// instead of `linux` in the runtime identifier. This would be a problem as
// Godot has a single export profile for both, named LinuxBSD.
[Platforms.LinuxBSD] = DotNetOS.Linux,
- [Platforms.UWP] = DotNetOS.Win10,
[Platforms.Android] = DotNetOS.Android,
[Platforms.iOS] = DotNetOS.iOS,
[Platforms.Web] = DotNetOS.Browser
@@ -132,29 +123,23 @@ namespace GodotTools.Utils
new[] { Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD };
private static readonly IEnumerable<string> UnixLikePlatforms =
- new[] { Names.MacOS, Names.Haiku, Names.Android, Names.iOS }
+ new[] { Names.MacOS, Names.Android, Names.iOS }
.Concat(LinuxBSDPlatforms).ToArray();
private static readonly Lazy<bool> _isWindows = new(() => IsOS(Names.Windows));
private static readonly Lazy<bool> _isMacOS = new(() => IsOS(Names.MacOS));
private static readonly Lazy<bool> _isLinuxBSD = new(() => IsAnyOS(LinuxBSDPlatforms));
- private static readonly Lazy<bool> _isUWP = new(() => IsOS(Names.UWP));
- private static readonly Lazy<bool> _isHaiku = new(() => IsOS(Names.Haiku));
private static readonly Lazy<bool> _isAndroid = new(() => IsOS(Names.Android));
private static readonly Lazy<bool> _isiOS = new(() => IsOS(Names.iOS));
private static readonly Lazy<bool> _isWeb = new(() => IsOS(Names.Web));
private static readonly Lazy<bool> _isUnixLike = new(() => IsAnyOS(UnixLikePlatforms));
- [SupportedOSPlatformGuard("windows")] public static bool IsWindows => _isWindows.Value || IsUWP;
+ [SupportedOSPlatformGuard("windows")] public static bool IsWindows => _isWindows.Value;
[SupportedOSPlatformGuard("osx")] public static bool IsMacOS => _isMacOS.Value;
[SupportedOSPlatformGuard("linux")] public static bool IsLinuxBSD => _isLinuxBSD.Value;
- [SupportedOSPlatformGuard("windows")] public static bool IsUWP => _isUWP.Value;
-
- public static bool IsHaiku => _isHaiku.Value;
-
[SupportedOSPlatformGuard("android")] public static bool IsAndroid => _isAndroid.Value;
[SupportedOSPlatformGuard("ios")] public static bool IsiOS => _isiOS.Value;
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index ae02e16256..ae914e71ef 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -31,6 +31,7 @@
#include "code_completion.h"
#include "core/config/project_settings.h"
+#include "core/object/script_language.h"
#include "editor/editor_file_system.h"
#include "editor/editor_settings.h"
#include "scene/gui/control.h"
diff --git a/modules/mono/editor/hostfxr_resolver.cpp b/modules/mono/editor/hostfxr_resolver.cpp
index e08823bbf7..04bd6a9207 100644
--- a/modules/mono/editor/hostfxr_resolver.cpp
+++ b/modules/mono/editor/hostfxr_resolver.cpp
@@ -80,7 +80,7 @@ SOFTWARE.
namespace {
String get_hostfxr_file_name() {
-#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
+#if defined(WINDOWS_ENABLED)
return "hostfxr.dll";
#elif defined(MACOS_ENABLED) || defined(IOS_ENABLED)
return "libhostfxr.dylib";
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index c84ecf4ceb..80e44011be 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -100,8 +100,6 @@ static const char *platform_name_map[][2] = {
{ "FreeBSD", "linuxbsd" },
{ "NetBSD", "linuxbsd" },
{ "BSD", "linuxbsd" },
- { "UWP", "uwp" },
- { "Haiku", "haiku" },
{ "Android", "android" },
{ "iOS", "ios" },
{ "Web", "web" },
diff --git a/modules/multiplayer/editor/editor_network_profiler.cpp b/modules/multiplayer/editor/editor_network_profiler.cpp
index c2cb0a3d1a..a53eefc452 100644
--- a/modules/multiplayer/editor/editor_network_profiler.cpp
+++ b/modules/multiplayer/editor/editor_network_profiler.cpp
@@ -33,6 +33,7 @@
#include "core/os/os.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
void EditorNetworkProfiler::_bind_methods() {
ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
@@ -62,19 +63,19 @@ void EditorNetworkProfiler::_notification(int p_what) {
void EditorNetworkProfiler::_update_theme_item_cache() {
VBoxContainer::_update_theme_item_cache();
- theme_cache.node_icon = get_theme_icon(SNAME("Node"), SNAME("EditorIcons"));
- theme_cache.stop_icon = get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"));
- theme_cache.play_icon = get_theme_icon(SNAME("Play"), SNAME("EditorIcons"));
- theme_cache.clear_icon = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
+ theme_cache.node_icon = get_theme_icon(SNAME("Node"), EditorStringName(EditorIcons));
+ theme_cache.stop_icon = get_theme_icon(SNAME("Stop"), EditorStringName(EditorIcons));
+ theme_cache.play_icon = get_theme_icon(SNAME("Play"), EditorStringName(EditorIcons));
+ theme_cache.clear_icon = get_theme_icon(SNAME("Clear"), EditorStringName(EditorIcons));
- theme_cache.multiplayer_synchronizer_icon = get_theme_icon("MultiplayerSynchronizer", SNAME("EditorIcons"));
- theme_cache.instance_options_icon = get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons"));
+ theme_cache.multiplayer_synchronizer_icon = get_theme_icon("MultiplayerSynchronizer", EditorStringName(EditorIcons));
+ theme_cache.instance_options_icon = get_theme_icon(SNAME("InstanceOptions"), EditorStringName(EditorIcons));
- theme_cache.incoming_bandwidth_icon = get_theme_icon(SNAME("ArrowDown"), SNAME("EditorIcons"));
- theme_cache.outgoing_bandwidth_icon = get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"));
+ theme_cache.incoming_bandwidth_icon = get_theme_icon(SNAME("ArrowDown"), EditorStringName(EditorIcons));
+ theme_cache.outgoing_bandwidth_icon = get_theme_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons));
- theme_cache.incoming_bandwidth_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- theme_cache.outgoing_bandwidth_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ theme_cache.incoming_bandwidth_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
+ theme_cache.outgoing_bandwidth_color = get_theme_color(SNAME("font_color"), EditorStringName(Editor));
}
void EditorNetworkProfiler::_refresh() {
@@ -128,7 +129,7 @@ void EditorNetworkProfiler::refresh_replication_data() {
const NodeInfo &cfg_info = node_data[E.value.config];
node->set_text(0, root_info.path.get_file());
- node->set_icon(0, has_theme_icon(root_info.type, SNAME("EditorIcons")) ? get_theme_icon(root_info.type, SNAME("EditorIcons")) : theme_cache.node_icon);
+ node->set_icon(0, has_theme_icon(root_info.type, EditorStringName(EditorIcons)) ? get_theme_icon(root_info.type, EditorStringName(EditorIcons)) : theme_cache.node_icon);
node->set_tooltip_text(0, root_info.path);
node->set_text(1, sync_info.path.get_file());
diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp
index cf1db9d43d..0051d82e99 100644
--- a/modules/multiplayer/editor/replication_editor.cpp
+++ b/modules/multiplayer/editor/replication_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/inspector_dock.h"
@@ -359,8 +360,8 @@ void ReplicationEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
- add_pick_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- pin->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
+ add_pick_button->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
+ pin->set_icon(get_theme_icon(SNAME("Pin"), EditorStringName(EditorIcons)));
} break;
}
}
@@ -524,10 +525,10 @@ void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) {
}
Ref<Texture2D> ReplicationEditor::_get_class_icon(const Node *p_node) {
- if (!p_node || !has_theme_icon(p_node->get_class(), "EditorIcons")) {
- return get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
+ if (!p_node || !has_theme_icon(p_node->get_class(), EditorStringName(EditorIcons))) {
+ return get_theme_icon(SNAME("ImportFail"), EditorStringName(EditorIcons));
}
- return get_theme_icon(p_node->get_class(), "EditorIcons");
+ return get_theme_icon(p_node->get_class(), EditorStringName(EditorIcons));
}
static bool can_sync(const Variant &p_var) {
@@ -571,7 +572,7 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn,
bool valid = false;
Variant value = node->get(subpath, &valid);
if (valid && !can_sync(value)) {
- item->set_icon(0, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")));
+ item->set_icon(0, get_theme_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons)));
item->set_tooltip_text(0, TTR("Property of this type not supported."));
} else {
item->set_icon(0, icon);
@@ -579,7 +580,7 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn,
} else {
item->set_icon(0, icon);
}
- item->add_button(3, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ item->add_button(3, get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
item->set_text_alignment(1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
item->set_checked(1, p_spawn);
diff --git a/modules/multiplayer/scene_cache_interface.h b/modules/multiplayer/scene_cache_interface.h
index 9400417cdb..7a7304fde8 100644
--- a/modules/multiplayer/scene_cache_interface.h
+++ b/modules/multiplayer/scene_cache_interface.h
@@ -33,6 +33,7 @@
#include "scene/main/multiplayer_api.h"
+class Node;
class SceneMultiplayer;
class SceneCacheInterface : public RefCounted {
diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
index 535091e5b6..85948e7547 100644
--- a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
+++ b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
@@ -35,6 +35,7 @@
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/gui/box_container.h"
@@ -54,8 +55,8 @@ void NavigationMeshEditor::_node_removed(Node *p_node) {
void NavigationMeshEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
- button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
+ button_bake->set_icon(get_theme_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
+ button_reset->set_icon(get_theme_icon(SNAME("Reload"), EditorStringName(EditorIcons)));
} break;
}
}
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index 40893bada6..c12605bc7a 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -56,7 +56,9 @@
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
class GodotNavigationServer;
+#ifndef _3D_DISABLED
class NavMeshGenerator3D;
+#endif // _3D_DISABLED
struct SetCommand {
virtual ~SetCommand() {}
@@ -80,7 +82,9 @@ class GodotNavigationServer : public NavigationServer3D {
LocalVector<NavMap *> active_maps;
LocalVector<uint32_t> active_maps_update_id;
+#ifndef _3D_DISABLED
NavMeshGenerator3D *navmesh_generator_3d = nullptr;
+#endif // _3D_DISABLED
// Performance Monitor
int pm_region_count = 0;
diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml
index f0ca649fe4..8d8cbf1a29 100644
--- a/modules/openxr/doc_classes/OpenXRInterface.xml
+++ b/modules/openxr/doc_classes/OpenXRInterface.xml
@@ -23,6 +23,53 @@
Returns display refresh rates supported by the current HMD. Only returned if this feature is supported by the OpenXR runtime and after the interface has been initialized.
</description>
</method>
+ <method name="get_hand_joint_angular_velocity" qualifiers="const">
+ <return type="Vector3" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
+ <description>
+ If handtracking is enabled, returns the angular velocity of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D]!
+ </description>
+ </method>
+ <method name="get_hand_joint_linear_velocity" qualifiers="const">
+ <return type="Vector3" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
+ <description>
+ If handtracking is enabled, returns the linear velocity of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D] without worldscale applied!
+ </description>
+ </method>
+ <method name="get_hand_joint_position" qualifiers="const">
+ <return type="Vector3" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
+ <description>
+ If handtracking is enabled, returns the position of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D] without worldscale applied!
+ </description>
+ </method>
+ <method name="get_hand_joint_radius" qualifiers="const">
+ <return type="float" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
+ <description>
+ If handtracking is enabled, returns the radius of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is without worldscale applied!
+ </description>
+ </method>
+ <method name="get_hand_joint_rotation" qualifiers="const">
+ <return type="Quaternion" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
+ <description>
+ If handtracking is enabled, returns the rotation of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR.
+ </description>
+ </method>
+ <method name="get_motion_range" qualifiers="const">
+ <return type="int" enum="OpenXRInterface.HandMotionRange" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <description>
+ If handtracking is enabled and motion range is supported, gets the currently configured motion range for [param hand].
+ </description>
+ </method>
<method name="is_action_set_active" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="String" />
@@ -38,6 +85,14 @@
Sets the given action set as active or inactive.
</description>
</method>
+ <method name="set_motion_range">
+ <return type="void" />
+ <param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
+ <param index="1" name="motion_range" type="int" enum="OpenXRInterface.HandMotionRange" />
+ <description>
+ If handtracking is enabled and motion range is supported, sets the currently configured motion range for [param hand] to [param motion_range].
+ </description>
+ </method>
</methods>
<members>
<member name="display_refresh_rate" type="float" setter="set_display_refresh_rate" getter="get_display_refresh_rate" default="0.0">
@@ -74,4 +129,102 @@
</description>
</signal>
</signals>
+ <constants>
+ <constant name="HAND_LEFT" value="0" enum="Hand">
+ Left hand.
+ </constant>
+ <constant name="HAND_RIGHT" value="1" enum="Hand">
+ Right hand.
+ </constant>
+ <constant name="HAND_MAX" value="2" enum="Hand">
+ Maximum value for the hand enum.
+ </constant>
+ <constant name="HAND_MOTION_RANGE_UNOBSTRUCTED" value="0" enum="HandMotionRange">
+ </constant>
+ <constant name="HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER" value="1" enum="HandMotionRange">
+ </constant>
+ <constant name="HAND_MOTION_RANGE_MAX" value="2" enum="HandMotionRange">
+ </constant>
+ <constant name="HAND_JOINT_PALM" value="0" enum="HandJoints">
+ Palm joint.
+ </constant>
+ <constant name="HAND_JOINT_WRIST" value="1" enum="HandJoints">
+ Wrist joint.
+ </constant>
+ <constant name="HAND_JOINT_THUMB_METACARPAL" value="2" enum="HandJoints">
+ Thumb metacarpal joint.
+ </constant>
+ <constant name="HAND_JOINT_THUMB_PROXIMAL" value="3" enum="HandJoints">
+ Thumb proximal joint.
+ </constant>
+ <constant name="HAND_JOINT_THUMB_DISTAL" value="4" enum="HandJoints">
+ Thumb distal joint.
+ </constant>
+ <constant name="HAND_JOINT_THUMB_TIP" value="5" enum="HandJoints">
+ Thumb tip joint.
+ </constant>
+ <constant name="HAND_JOINT_INDEX_METACARPAL" value="6" enum="HandJoints">
+ Index metacarpal joint.
+ </constant>
+ <constant name="HAND_JOINT_INDEX_PROXIMAL" value="7" enum="HandJoints">
+ Index proximal joint.
+ </constant>
+ <constant name="HAND_JOINT_INDEX_INTERMEDIATE" value="8" enum="HandJoints">
+ Index intermediate joint.
+ </constant>
+ <constant name="HAND_JOINT_INDEX_DISTAL" value="9" enum="HandJoints">
+ Index distal joint.
+ </constant>
+ <constant name="HAND_JOINT_INDEX_TIP" value="10" enum="HandJoints">
+ Index tip joint.
+ </constant>
+ <constant name="HAND_JOINT_MIDDLE_METACARPAL" value="11" enum="HandJoints">
+ Middle metacarpal joint.
+ </constant>
+ <constant name="HAND_JOINT_MIDDLE_PROXIMAL" value="12" enum="HandJoints">
+ Middle proximal joint.
+ </constant>
+ <constant name="HAND_JOINT_MIDDLE_INTERMEDIATE" value="13" enum="HandJoints">
+ Middle intermediate joint.
+ </constant>
+ <constant name="HAND_JOINT_MIDDLE_DISTAL" value="14" enum="HandJoints">
+ Middle distal joint.
+ </constant>
+ <constant name="HAND_JOINT_MIDDLE_TIP" value="15" enum="HandJoints">
+ Middle tip joint.
+ </constant>
+ <constant name="HAND_JOINT_RING_METACARPAL" value="16" enum="HandJoints">
+ Ring metacarpal joint.
+ </constant>
+ <constant name="HAND_JOINT_RING_PROXIMAL" value="17" enum="HandJoints">
+ Ring proximal joint.
+ </constant>
+ <constant name="HAND_JOINT_RING_INTERMEDIATE" value="18" enum="HandJoints">
+ Ring intermediate joint.
+ </constant>
+ <constant name="HAND_JOINT_RING_DISTAL" value="19" enum="HandJoints">
+ Ring distal joint.
+ </constant>
+ <constant name="HAND_JOINT_RING_TIP" value="20" enum="HandJoints">
+ Ring tip joint.
+ </constant>
+ <constant name="HAND_JOINT_LITTLE_METACARPAL" value="21" enum="HandJoints">
+ Little metacarpal joint.
+ </constant>
+ <constant name="HAND_JOINT_LITTLE_PROXIMAL" value="22" enum="HandJoints">
+ Little proximal joint.
+ </constant>
+ <constant name="HAND_JOINT_LITTLE_INTERMEDIATE" value="23" enum="HandJoints">
+ Little intermediate joint.
+ </constant>
+ <constant name="HAND_JOINT_LITTLE_DISTAL" value="24" enum="HandJoints">
+ Little distal joint.
+ </constant>
+ <constant name="HAND_JOINT_LITTLE_TIP" value="25" enum="HandJoints">
+ Little tip joint.
+ </constant>
+ <constant name="HAND_JOINT_MAX" value="26" enum="HandJoints">
+ Maximum value for the hand joint enum.
+ </constant>
+ </constants>
</class>
diff --git a/modules/openxr/editor/openxr_action_editor.cpp b/modules/openxr/editor/openxr_action_editor.cpp
index 586b0b0697..4b188471a0 100644
--- a/modules/openxr/editor/openxr_action_editor.cpp
+++ b/modules/openxr/editor/openxr_action_editor.cpp
@@ -30,6 +30,8 @@
#include "openxr_action_editor.h"
+#include "editor/editor_string_names.h"
+
void OpenXRActionEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_do_set_name", "name"), &OpenXRActionEditor::_do_set_name);
ClassDB::bind_method(D_METHOD("_do_set_localized_name", "name"), &OpenXRActionEditor::_do_set_localized_name);
@@ -39,7 +41,7 @@ void OpenXRActionEditor::_bind_methods() {
}
void OpenXRActionEditor::_theme_changed() {
- rem_action->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ rem_action->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
}
void OpenXRActionEditor::_notification(int p_what) {
diff --git a/modules/openxr/editor/openxr_action_set_editor.cpp b/modules/openxr/editor/openxr_action_set_editor.cpp
index 6a63720257..a9fc6c4db6 100644
--- a/modules/openxr/editor/openxr_action_set_editor.cpp
+++ b/modules/openxr/editor/openxr_action_set_editor.cpp
@@ -30,6 +30,7 @@
#include "openxr_action_set_editor.h"
+#include "editor/editor_string_names.h"
#include "openxr_action_editor.h"
void OpenXRActionSetEditor::_bind_methods() {
@@ -45,16 +46,16 @@ void OpenXRActionSetEditor::_bind_methods() {
void OpenXRActionSetEditor::_set_fold_icon() {
if (is_expanded) {
- fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")));
+ fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
} else {
- fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")));
+ fold_btn->set_icon(get_theme_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
}
}
void OpenXRActionSetEditor::_theme_changed() {
_set_fold_icon();
- add_action->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- rem_action_set->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ add_action->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
+ rem_action_set->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
}
void OpenXRActionSetEditor::_notification(int p_what) {
diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.cpp b/modules/openxr/editor/openxr_interaction_profile_editor.cpp
index 9998bb80e3..7bccabf936 100644
--- a/modules/openxr/editor/openxr_interaction_profile_editor.cpp
+++ b/modules/openxr/editor/openxr_interaction_profile_editor.cpp
@@ -30,6 +30,7 @@
#include "openxr_interaction_profile_editor.h"
+#include "editor/editor_string_names.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
@@ -220,7 +221,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
path_hb->add_child(type_label);
Button *path_add = memnew(Button);
- path_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ path_add->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
path_add->set_flat(true);
path_add->connect("pressed", callable_mp(this, &OpenXRInteractionProfileEditor::select_action_for).bind(String(p_io_path->openxr_path)));
path_hb->add_child(path_add);
@@ -248,7 +249,7 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
Button *action_rem = memnew(Button);
action_rem->set_flat(true);
- action_rem->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ action_rem->set_icon(get_theme_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
action_rem->connect("pressed", callable_mp((OpenXRInteractionProfileEditor *)this, &OpenXRInteractionProfileEditor::_on_remove_pressed).bind(action->get_name_with_set(), String(p_io_path->openxr_path)));
action_hb->add_child(action_rem);
}
diff --git a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp
index f730f2bd2c..3da0ffd9c7 100644
--- a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp
+++ b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp
@@ -71,7 +71,7 @@ Viewport *OpenXRFbPassthroughExtensionWrapper::get_main_viewport() {
return nullptr;
}
- auto *scene_tree = Object::cast_to<SceneTree>(main_loop);
+ SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
if (!scene_tree) {
print_error("Unable to retrieve scene tree");
return nullptr;
diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp
index 65559afed0..c92b2b08d0 100644
--- a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp
+++ b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp
@@ -276,3 +276,62 @@ void OpenXRHandTrackingExtension::set_motion_range(uint32_t p_hand, XrHandJoints
ERR_FAIL_UNSIGNED_INDEX(p_hand, MAX_OPENXR_TRACKED_HANDS);
hand_trackers[p_hand].motion_range = p_motion_range;
}
+
+Quaternion OpenXRHandTrackingExtension::get_hand_joint_rotation(uint32_t p_hand, XrHandJointEXT p_joint) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Quaternion());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Quaternion());
+
+ if (!hand_trackers[p_hand].is_initialized) {
+ return Quaternion();
+ }
+
+ const XrHandJointLocationEXT &location = hand_trackers[p_hand].joint_locations[p_joint];
+ return Quaternion(location.pose.orientation.x, location.pose.orientation.y, location.pose.orientation.z, location.pose.orientation.w);
+}
+
+Vector3 OpenXRHandTrackingExtension::get_hand_joint_position(uint32_t p_hand, XrHandJointEXT p_joint) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());
+
+ if (!hand_trackers[p_hand].is_initialized) {
+ return Vector3();
+ }
+
+ const XrHandJointLocationEXT &location = hand_trackers[p_hand].joint_locations[p_joint];
+ return Vector3(location.pose.position.x, location.pose.position.y, location.pose.position.z);
+}
+
+float OpenXRHandTrackingExtension::get_hand_joint_radius(uint32_t p_hand, XrHandJointEXT p_joint) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, 0.0);
+ ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, 0.0);
+
+ if (!hand_trackers[p_hand].is_initialized) {
+ return 0.0;
+ }
+
+ return hand_trackers[p_hand].joint_locations[p_joint].radius;
+}
+
+Vector3 OpenXRHandTrackingExtension::get_hand_joint_linear_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());
+
+ if (!hand_trackers[p_hand].is_initialized) {
+ return Vector3();
+ }
+
+ const XrHandJointVelocityEXT &velocity = hand_trackers[p_hand].joint_velocities[p_joint];
+ return Vector3(velocity.linearVelocity.x, velocity.linearVelocity.y, velocity.linearVelocity.z);
+}
+
+Vector3 OpenXRHandTrackingExtension::get_hand_joint_angular_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());
+
+ if (!hand_trackers[p_hand].is_initialized) {
+ return Vector3();
+ }
+
+ const XrHandJointVelocityEXT &velocity = hand_trackers[p_hand].joint_velocities[p_joint];
+ return Vector3(velocity.angularVelocity.x, velocity.angularVelocity.y, velocity.angularVelocity.z);
+}
diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.h b/modules/openxr/extensions/openxr_hand_tracking_extension.h
index e86831e71b..99d315c525 100644
--- a/modules/openxr/extensions/openxr_hand_tracking_extension.h
+++ b/modules/openxr/extensions/openxr_hand_tracking_extension.h
@@ -32,6 +32,7 @@
#define OPENXR_HAND_TRACKING_EXTENSION_H
#include "../util.h"
+#include "core/math/quaternion.h"
#include "openxr_extension_wrapper.h"
#define MAX_OPENXR_TRACKED_HANDS 2
@@ -73,6 +74,13 @@ public:
XrHandJointsMotionRangeEXT get_motion_range(uint32_t p_hand) const;
void set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range);
+ Quaternion get_hand_joint_rotation(uint32_t p_hand, XrHandJointEXT p_joint) const;
+ Vector3 get_hand_joint_position(uint32_t p_hand, XrHandJointEXT p_joint) const;
+ float get_hand_joint_radius(uint32_t p_hand, XrHandJointEXT p_joint) const;
+
+ Vector3 get_hand_joint_linear_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const;
+ Vector3 get_hand_joint_angular_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const;
+
private:
static OpenXRHandTrackingExtension *singleton;
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 17f1c3940c..a66afee1c5 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -300,32 +300,31 @@ bool OpenXRAPI::create_instance() {
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions();
- // requested_extensions.insert(wrapper_request_extensions.begin(), wrapper_request_extensions.end());
- for (auto &requested_extension : wrapper_request_extensions) {
+ for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
requested_extensions[requested_extension.key] = requested_extension.value;
}
}
- // Check which extensions are supported
+ // Check which extensions are supported.
enabled_extensions.clear();
- for (auto &requested_extension : requested_extensions) {
+ for (KeyValue<String, bool *> &requested_extension : requested_extensions) {
if (!is_extension_supported(requested_extension.key)) {
if (requested_extension.value == nullptr) {
- // nullptr means this is a manditory extension so we fail
+ // Null means this is a manditory extension so we fail.
ERR_FAIL_V_MSG(false, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.key + String(" extension!"));
} else {
- // set this extension as not supported
+ // Set this extension as not supported.
*requested_extension.value = false;
}
} else if (requested_extension.value != nullptr) {
- // set this extension as supported
+ // Set this extension as supported.
*requested_extension.value = true;
- // and record that we want to enable it
+ // And record that we want to enable it.
enabled_extensions.push_back(requested_extension.key.ascii());
} else {
- // record that we want to enable this
+ // Record that we want to enable this.
enabled_extensions.push_back(requested_extension.key.ascii());
}
}
@@ -2077,7 +2076,7 @@ XRPose::TrackingConfidence _transform_from_location(const T &p_location, Transfo
Basis basis;
Vector3 origin;
XRPose::TrackingConfidence confidence = XRPose::XR_TRACKING_CONFIDENCE_NONE;
- const auto &pose = p_location.pose;
+ const XrPosef &pose = p_location.pose;
// Check orientation
if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index cc2b4fa11b..4dda51147b 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -34,6 +34,8 @@
#include "core/io/resource_saver.h"
#include "servers/rendering/rendering_server_globals.h"
+#include "extensions/openxr_hand_tracking_extension.h"
+
void OpenXRInterface::_bind_methods() {
// lifecycle signals
ADD_SIGNAL(MethodInfo("session_begun"));
@@ -57,6 +59,53 @@ void OpenXRInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_action_sets"), &OpenXRInterface::get_action_sets);
ClassDB::bind_method(D_METHOD("get_available_display_refresh_rates"), &OpenXRInterface::get_available_display_refresh_rates);
+
+ // Hand tracking.
+ ClassDB::bind_method(D_METHOD("set_motion_range", "hand", "motion_range"), &OpenXRInterface::set_motion_range);
+ ClassDB::bind_method(D_METHOD("get_motion_range", "hand"), &OpenXRInterface::get_motion_range);
+
+ ClassDB::bind_method(D_METHOD("get_hand_joint_rotation", "hand", "joint"), &OpenXRInterface::get_hand_joint_rotation);
+ ClassDB::bind_method(D_METHOD("get_hand_joint_position", "hand", "joint"), &OpenXRInterface::get_hand_joint_position);
+ ClassDB::bind_method(D_METHOD("get_hand_joint_radius", "hand", "joint"), &OpenXRInterface::get_hand_joint_radius);
+
+ ClassDB::bind_method(D_METHOD("get_hand_joint_linear_velocity", "hand", "joint"), &OpenXRInterface::get_hand_joint_linear_velocity);
+ ClassDB::bind_method(D_METHOD("get_hand_joint_angular_velocity", "hand", "joint"), &OpenXRInterface::get_hand_joint_angular_velocity);
+
+ BIND_ENUM_CONSTANT(HAND_LEFT);
+ BIND_ENUM_CONSTANT(HAND_RIGHT);
+ BIND_ENUM_CONSTANT(HAND_MAX);
+
+ BIND_ENUM_CONSTANT(HAND_MOTION_RANGE_UNOBSTRUCTED);
+ BIND_ENUM_CONSTANT(HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER);
+ BIND_ENUM_CONSTANT(HAND_MOTION_RANGE_MAX);
+
+ BIND_ENUM_CONSTANT(HAND_JOINT_PALM);
+ BIND_ENUM_CONSTANT(HAND_JOINT_WRIST);
+ BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_METACARPAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_PROXIMAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_DISTAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_TIP);
+ BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_METACARPAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_PROXIMAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_INTERMEDIATE);
+ BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_DISTAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_TIP);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_METACARPAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_PROXIMAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_INTERMEDIATE);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_DISTAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_TIP);
+ BIND_ENUM_CONSTANT(HAND_JOINT_RING_METACARPAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_RING_PROXIMAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_RING_INTERMEDIATE);
+ BIND_ENUM_CONSTANT(HAND_JOINT_RING_DISTAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_RING_TIP);
+ BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_METACARPAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_PROXIMAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_INTERMEDIATE);
+ BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_DISTAL);
+ BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_TIP);
+ BIND_ENUM_CONSTANT(HAND_JOINT_MAX);
}
StringName OpenXRInterface::get_name() const {
@@ -978,6 +1027,96 @@ void OpenXRInterface::on_pose_recentered() {
emit_signal(SNAME("pose_recentered"));
}
+/** Hand tracking. */
+void OpenXRInterface::set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range) {
+ ERR_FAIL_INDEX(p_hand, HAND_MAX);
+ ERR_FAIL_INDEX(p_motion_range, HAND_MOTION_RANGE_MAX);
+
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ XrHandJointsMotionRangeEXT xr_motion_range;
+ switch (p_motion_range) {
+ case HAND_MOTION_RANGE_UNOBSTRUCTED:
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
+ break;
+ case HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER:
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
+ break;
+ default:
+ // Shouldn't get here, ERR_FAIL_INDEX should have caught this...
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
+ break;
+ }
+
+ hand_tracking_ext->set_motion_range(uint32_t(p_hand), xr_motion_range);
+ }
+}
+
+OpenXRInterface::HandMotionRange OpenXRInterface::get_motion_range(const Hand p_hand) const {
+ ERR_FAIL_INDEX_V(p_hand, HAND_MAX, HAND_MOTION_RANGE_MAX);
+
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ XrHandJointsMotionRangeEXT xr_motion_range = hand_tracking_ext->get_motion_range(uint32_t(p_hand));
+
+ switch (xr_motion_range) {
+ case XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT:
+ return HAND_MOTION_RANGE_UNOBSTRUCTED;
+ case XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT:
+ return HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER;
+ default:
+ ERR_FAIL_V_MSG(HAND_MOTION_RANGE_MAX, "Unknown motion range returned by OpenXR");
+ }
+ }
+
+ return HAND_MOTION_RANGE_MAX;
+}
+
+Quaternion OpenXRInterface::get_hand_joint_rotation(Hand p_hand, HandJoints p_joint) const {
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ return hand_tracking_ext->get_hand_joint_rotation(uint32_t(p_hand), XrHandJointEXT(p_joint));
+ }
+
+ return Quaternion();
+}
+
+Vector3 OpenXRInterface::get_hand_joint_position(Hand p_hand, HandJoints p_joint) const {
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ return hand_tracking_ext->get_hand_joint_position(uint32_t(p_hand), XrHandJointEXT(p_joint));
+ }
+
+ return Vector3();
+}
+
+float OpenXRInterface::get_hand_joint_radius(Hand p_hand, HandJoints p_joint) const {
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ return hand_tracking_ext->get_hand_joint_radius(uint32_t(p_hand), XrHandJointEXT(p_joint));
+ }
+
+ return 0.0;
+}
+
+Vector3 OpenXRInterface::get_hand_joint_linear_velocity(Hand p_hand, HandJoints p_joint) const {
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ return hand_tracking_ext->get_hand_joint_linear_velocity(uint32_t(p_hand), XrHandJointEXT(p_joint));
+ }
+
+ return Vector3();
+}
+
+Vector3 OpenXRInterface::get_hand_joint_angular_velocity(Hand p_hand, HandJoints p_joint) const {
+ OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+ if (hand_tracking_ext && hand_tracking_ext->get_active()) {
+ return hand_tracking_ext->get_hand_joint_angular_velocity(uint32_t(p_hand), XrHandJointEXT(p_joint));
+ }
+
+ return Vector3();
+}
+
OpenXRInterface::OpenXRInterface() {
openxr_api = OpenXRAPI::get_singleton();
if (openxr_api) {
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
index 39cc68ae9b..09e1c31728 100644
--- a/modules/openxr/openxr_interface.h
+++ b/modules/openxr/openxr_interface.h
@@ -161,8 +161,65 @@ public:
void on_pose_recentered();
void tracker_profile_changed(RID p_tracker, RID p_interaction_profile);
+ /** Hand tracking. */
+ enum Hand {
+ HAND_LEFT,
+ HAND_RIGHT,
+ HAND_MAX,
+ };
+
+ enum HandMotionRange {
+ HAND_MOTION_RANGE_UNOBSTRUCTED,
+ HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER,
+ HAND_MOTION_RANGE_MAX
+ };
+
+ void set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range);
+ HandMotionRange get_motion_range(const Hand p_hand) const;
+
+ enum HandJoints {
+ HAND_JOINT_PALM = 0,
+ HAND_JOINT_WRIST = 1,
+ HAND_JOINT_THUMB_METACARPAL = 2,
+ HAND_JOINT_THUMB_PROXIMAL = 3,
+ HAND_JOINT_THUMB_DISTAL = 4,
+ HAND_JOINT_THUMB_TIP = 5,
+ HAND_JOINT_INDEX_METACARPAL = 6,
+ HAND_JOINT_INDEX_PROXIMAL = 7,
+ HAND_JOINT_INDEX_INTERMEDIATE = 8,
+ HAND_JOINT_INDEX_DISTAL = 9,
+ HAND_JOINT_INDEX_TIP = 10,
+ HAND_JOINT_MIDDLE_METACARPAL = 11,
+ HAND_JOINT_MIDDLE_PROXIMAL = 12,
+ HAND_JOINT_MIDDLE_INTERMEDIATE = 13,
+ HAND_JOINT_MIDDLE_DISTAL = 14,
+ HAND_JOINT_MIDDLE_TIP = 15,
+ HAND_JOINT_RING_METACARPAL = 16,
+ HAND_JOINT_RING_PROXIMAL = 17,
+ HAND_JOINT_RING_INTERMEDIATE = 18,
+ HAND_JOINT_RING_DISTAL = 19,
+ HAND_JOINT_RING_TIP = 20,
+ HAND_JOINT_LITTLE_METACARPAL = 21,
+ HAND_JOINT_LITTLE_PROXIMAL = 22,
+ HAND_JOINT_LITTLE_INTERMEDIATE = 23,
+ HAND_JOINT_LITTLE_DISTAL = 24,
+ HAND_JOINT_LITTLE_TIP = 25,
+ HAND_JOINT_MAX = 26,
+ };
+
+ Quaternion get_hand_joint_rotation(Hand p_hand, HandJoints p_joint) const;
+ Vector3 get_hand_joint_position(Hand p_hand, HandJoints p_joint) const;
+ float get_hand_joint_radius(Hand p_hand, HandJoints p_joint) const;
+
+ Vector3 get_hand_joint_linear_velocity(Hand p_hand, HandJoints p_joint) const;
+ Vector3 get_hand_joint_angular_velocity(Hand p_hand, HandJoints p_joint) const;
+
OpenXRInterface();
~OpenXRInterface();
};
+VARIANT_ENUM_CAST(OpenXRInterface::Hand)
+VARIANT_ENUM_CAST(OpenXRInterface::HandMotionRange)
+VARIANT_ENUM_CAST(OpenXRInterface::HandJoints)
+
#endif // OPENXR_INTERFACE_H
diff --git a/modules/openxr/scene/openxr_hand.cpp b/modules/openxr/scene/openxr_hand.cpp
index 91571a556d..bedc8874d6 100644
--- a/modules/openxr/scene/openxr_hand.cpp
+++ b/modules/openxr/scene/openxr_hand.cpp
@@ -213,8 +213,8 @@ void OpenXRHand::_update_skeleton() {
quaternions[i] = Quaternion();
positions[i] = Vector3();
- const auto &location = hand_tracker->joint_locations[i];
- const auto &pose = location.pose;
+ const XrHandJointLocationEXT &location = hand_tracker->joint_locations[i];
+ const XrPosef &pose = location.pose;
if (location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
if (pose.orientation.x != 0 || pose.orientation.y != 0 || pose.orientation.z != 0 || pose.orientation.w != 0) {
diff --git a/modules/openxr/scene/openxr_hand.h b/modules/openxr/scene/openxr_hand.h
index 7bec3959d8..edfb474ac7 100644
--- a/modules/openxr/scene/openxr_hand.h
+++ b/modules/openxr/scene/openxr_hand.h
@@ -43,13 +43,13 @@ class OpenXRHand : public Node3D {
GDCLASS(OpenXRHand, Node3D);
public:
- enum Hands {
+ enum Hands { // Deprecated, need to change this to OpenXRInterface::Hands.
HAND_LEFT,
HAND_RIGHT,
HAND_MAX
};
- enum MotionRange {
+ enum MotionRange { // Deprecated, need to change this to OpenXRInterface::HandMotionRange.
MOTION_RANGE_UNOBSTRUCTED,
MOTION_RANGE_CONFORM_TO_CONTROLLER,
MOTION_RANGE_MAX
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index cbe48db494..3cbc300946 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -2383,9 +2383,9 @@ void TextServerAdvanced::_font_set_variation_coordinates(const RID &p_font_rid,
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->variation_coordinates != p_variation_coordinates) {
+ if (!fd->variation_coordinates.recursive_equal(p_variation_coordinates, 1)) {
_font_clear_cache(fd);
- fd->variation_coordinates = p_variation_coordinates;
+ fd->variation_coordinates = p_variation_coordinates.duplicate();
}
}
@@ -5882,8 +5882,11 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
sd->para_direction = (direction == UBIDI_RTL) ? DIRECTION_RTL : DIRECTION_LTR;
sd->base_para_direction = direction;
} else {
- sd->para_direction = DIRECTION_LTR;
- sd->base_para_direction = UBIDI_DEFAULT_LTR;
+ const String &lang = (sd->spans.is_empty() || sd->spans[0].language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : sd->spans[0].language;
+ bool lang_rtl = _is_locale_right_to_left(lang);
+
+ sd->para_direction = lang_rtl ? DIRECTION_RTL : DIRECTION_LTR;
+ sd->base_para_direction = lang_rtl ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR;
}
} break;
}
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index d0587bf6c0..26d16a1ec9 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -1376,9 +1376,9 @@ void TextServerFallback::_font_set_variation_coordinates(const RID &p_font_rid,
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->variation_coordinates != p_variation_coordinates) {
+ if (!fd->variation_coordinates.recursive_equal(p_variation_coordinates, 1)) {
_font_clear_cache(fd);
- fd->variation_coordinates = p_variation_coordinates;
+ fd->variation_coordinates = p_variation_coordinates.duplicate();
}
}
diff --git a/modules/webrtc/webrtc_data_channel_extension.h b/modules/webrtc/webrtc_data_channel_extension.h
index 462e089592..b7afbaf13a 100644
--- a/modules/webrtc/webrtc_data_channel_extension.h
+++ b/modules/webrtc/webrtc_data_channel_extension.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class WebRTCDataChannelExtension : public WebRTCDataChannel {
diff --git a/modules/webrtc/webrtc_peer_connection_extension.h b/modules/webrtc/webrtc_peer_connection_extension.h
index f3339f1eb4..05d88e0f65 100644
--- a/modules/webrtc/webrtc_peer_connection_extension.h
+++ b/modules/webrtc/webrtc_peer_connection_extension.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class WebRTCPeerConnectionExtension : public WebRTCPeerConnection {
diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub
index 3f834471e5..8b469fe5be 100644
--- a/modules/websocket/SCsub
+++ b/modules/websocket/SCsub
@@ -25,7 +25,7 @@ elif env["builtin_wslay"]:
env_ws.Prepend(CPPPATH=[thirdparty_dir])
env_ws.Append(CPPDEFINES=["HAVE_CONFIG_H"])
- if env["platform"] == "windows" or env["platform"] == "uwp":
+ if env["platform"] == "windows":
env_ws.Append(CPPDEFINES=["HAVE_WINSOCK2_H"])
else:
env_ws.Append(CPPDEFINES=["HAVE_NETINET_IN_H"])
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
index 9c1165bf8a..e115494cfd 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
@@ -907,6 +907,19 @@ class Godot(private val context: Context) : SensorEventListener {
return PermissionsUtil.getGrantedPermissions(getActivity())
}
+ /**
+ * Get the list of gdextension modules to register.
+ */
+ @Keep
+ private fun getGDExtensionConfigFiles(): Array<String> {
+ val configFiles = mutableSetOf<String>()
+ for (plugin in pluginRegistry.allPlugins) {
+ configFiles.addAll(plugin.pluginGDExtensionLibrariesPaths)
+ }
+
+ return configFiles.toTypedArray()
+ }
+
@Keep
private fun getCACertificates(): String {
return GodotNetUtils.getCACertificates()
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index 48aa231c7a..7f3a3ac7a3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -57,27 +57,28 @@ import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
- * Base class for the Godot Android plugins.
+ * Base class for Godot Android plugins.
* <p>
- * A Godot Android plugin is a regular Android library packaged as an aar archive file with the following caveats:
+ * A Godot Android plugin is an Android library with the following requirements:
* <p>
- * - The library must have a dependency on the Godot Android library (godot-lib.aar).
- * A stable version is available for each release.
+ * - The plugin must have a dependency on the Godot Android library: `implementation "org.godotengine:godot:<godotLibVersion>"`
+ * <p>
+ * - The plugin must include a <meta-data> tag in its Android manifest with the following format:
+ * <meta-data android:name="org.godotengine.plugin.v2.[PluginName]" android:value="[plugin.init.ClassFullName]" />
* <p>
- * - The library must include a <meta-data> tag in its manifest file setup as follow:
- * <meta-data android:name="org.godotengine.plugin.v1.[PluginName]" android:value="[plugin.init.ClassFullName]" />
* Where:
+ * <p>
* - 'PluginName' is the name of the plugin.
- * - 'plugin.init.ClassFullName' is the full name (package + class name) of the plugin class
+ * <p>
+ * - 'plugin.init.ClassFullName' is the full name (package + class name) of the plugin init class
* extending {@link GodotPlugin}.
+ * <p>
+ * A Godot Android plugin can also define and provide c/c++ gdextension libraries, which will be
+ * automatically bundled by the aar build system.
+ * GDExtension ('*.gdextension') config files must be located in the project 'assets' directory and
+ * their paths specified by {@link GodotPlugin#getPluginGDExtensionLibrariesPaths()}.
*
- * A plugin can also define and provide c/c++ gdextension libraries and nativescripts for the target
- * app/game to leverage.
- * The shared library for the gdextension library will be automatically bundled by the aar build
- * system.
- * Godot '*.gdextension' resource files must however be manually defined in the project
- * 'assets' directory. The recommended path for these resources in the 'assets' directory should be:
- * 'godot/plugin/v1/[PluginName]/'
+ * @see <a href="https://docs.godotengine.org/en/stable/tutorials/platform/android/index.html">Android plugins</a>
*/
public abstract class GodotPlugin {
private static final String TAG = GodotPlugin.class.getSimpleName();
@@ -85,6 +86,10 @@ public abstract class GodotPlugin {
private final Godot godot;
private final ConcurrentHashMap<String, SignalInfo> registeredSignals = new ConcurrentHashMap<>();
+ /**
+ * Base constructor passing a {@link Godot} instance through which the plugin can access Godot's
+ * APIs and lifecycle events.
+ */
public GodotPlugin(Godot godot) {
this.godot = godot;
}
@@ -97,7 +102,7 @@ public abstract class GodotPlugin {
}
/**
- * Provides access to the underlying {@link Activity}.
+ * Provides access to the hosting {@link Activity}.
*/
@Nullable
protected Activity getActivity() {
@@ -106,33 +111,16 @@ public abstract class GodotPlugin {
/**
* Register the plugin with Godot native code.
- *
- * This method is invoked on the render thread.
+ * <p>
+ * This method is invoked by the Godot Engine on the render thread.
*/
public final void onRegisterPluginWithGodotNative() {
registeredSignals.putAll(
- registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals(),
- getPluginGDExtensionLibrariesPaths()));
- }
-
- /**
- * Register the plugin with Godot native code.
- *
- * This method must be invoked on the render thread.
- */
- public static void registerPluginWithGodotNative(Object pluginObject,
- GodotPluginInfoProvider pluginInfoProvider) {
- registerPluginWithGodotNative(pluginObject, pluginInfoProvider.getPluginName(),
- Collections.emptyList(), pluginInfoProvider.getPluginSignals(),
- pluginInfoProvider.getPluginGDExtensionLibrariesPaths());
-
- // Notify that registration is complete.
- pluginInfoProvider.onPluginRegistered();
+ registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals()));
}
private static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject,
- String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals,
- Set<String> pluginGDExtensionLibrariesPaths) {
+ String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals) {
nativeRegisterSingleton(pluginName, pluginObject);
Set<Method> filteredMethods = new HashSet<>();
@@ -176,23 +164,18 @@ public abstract class GodotPlugin {
registeredSignals.put(signalName, signalInfo);
}
- // Get the list of gdextension libraries to register.
- if (!pluginGDExtensionLibrariesPaths.isEmpty()) {
- nativeRegisterGDExtensionLibraries(pluginGDExtensionLibrariesPaths.toArray(new String[0]));
- }
-
return registeredSignals;
}
/**
- * Invoked once during the Godot Android initialization process after creation of the
+ * Invoked once during the initialization process after creation of the
* {@link org.godotengine.godot.GodotRenderView} view.
* <p>
- * The plugin can return a non-null {@link View} layout in order to add it to the Godot view
+ * The plugin can return a non-null {@link View} layout which will be added to the Godot view
* hierarchy.
- *
- * Use shouldBeOnTop() to set whether the plugin's {@link View} should be added on top or behind
- * the main Godot view.
+ * <p>
+ * Use {@link GodotPlugin#shouldBeOnTop()} to specify whether the plugin's {@link View} should
+ * be added on top or behind the main Godot view.
*
* @see Activity#onCreate(Bundle)
* @return the plugin's view to be included; null if no views should be included.
@@ -235,44 +218,52 @@ public abstract class GodotPlugin {
public boolean onMainBackPressed() { return false; }
/**
- * Invoked on the render thread when the Godot setup is complete.
+ * Invoked on the render thread when set up of the Godot engine is complete.
+ * <p>
+ * This is invoked before {@link GodotPlugin#onGodotMainLoopStarted()}.
*/
public void onGodotSetupCompleted() {}
/**
* Invoked on the render thread when the Godot main loop has started.
+ *
+ * This is invoked after {@link GodotPlugin#onGodotSetupCompleted()}.
*/
public void onGodotMainLoopStarted() {}
/**
- * Invoked once per frame on the GL thread after the frame is drawn.
+ * When using the OpenGL renderer, this is invoked once per frame on the GL thread after the
+ * frame is drawn.
*/
public void onGLDrawFrame(GL10 gl) {}
/**
- * Called on the GL thread after the surface is created and whenever the OpenGL ES surface size
- * changes.
+ * When using the OpenGL renderer, this is called on the GL thread after the surface is created
+ * and whenever the OpenGL ES surface size changes.
*/
public void onGLSurfaceChanged(GL10 gl, int width, int height) {}
/**
- * Called on the GL thread when the surface is created or recreated.
+ * When using the OpenGL renderer, this is called on the GL thread when the surface is created
+ * or recreated.
*/
public void onGLSurfaceCreated(GL10 gl, EGLConfig config) {}
/**
- * Invoked once per frame on the Vulkan thread after the frame is drawn.
+ * When using the Vulkan renderer, this is invoked once per frame on the Vulkan thread after
+ * the frame is drawn.
*/
public void onVkDrawFrame() {}
/**
- * Called on the Vulkan thread after the surface is created and whenever the surface size
- * changes.
+ * When using the Vulkan renderer, this is called on the Vulkan thread after the surface is
+ * created and whenever the surface size changes.
*/
public void onVkSurfaceChanged(Surface surface, int width, int height) {}
/**
- * Called on the Vulkan thread when the surface is created or recreated.
+ * When using the Vulkan renderer, this is called on the Vulkan thread when the surface is
+ * created or recreated.
*/
public void onVkSurfaceCreated(Surface surface) {}
@@ -287,7 +278,7 @@ public abstract class GodotPlugin {
/**
* Returns the list of methods to be exposed to Godot.
*
- * @deprecated Used the {@link UsedByGodot} annotation instead.
+ * @deprecated Use the {@link UsedByGodot} annotation instead.
*/
@NonNull
@Deprecated
@@ -304,19 +295,19 @@ public abstract class GodotPlugin {
}
/**
- * Returns the paths for the plugin's gdextension libraries.
- *
- * The paths must be relative to the 'assets' directory and point to a '*.gdextension' file.
+ * Returns the paths for the plugin's gdextension libraries (if any).
+ * <p>
+ * Each returned path must be relative to the 'assets' directory and point to a '*.gdextension' file.
*/
@NonNull
- protected Set<String> getPluginGDExtensionLibrariesPaths() {
+ public Set<String> getPluginGDExtensionLibrariesPaths() {
return Collections.emptySet();
}
/**
- * Returns whether the plugin's {@link View} returned in onMainCreate() should be placed on
- * top of the main Godot view.
- *
+ * Returns whether the plugin's {@link View} returned in
+ * {@link GodotPlugin#onMainCreate(Activity)} should be placed on top of the main Godot view.
+ * <p>
* Returning false causes the plugin's {@link View} to be placed behind, which can be useful
* when used with transparency in order to let the Godot view handle inputs.
*/
@@ -359,7 +350,7 @@ public abstract class GodotPlugin {
}
emitSignal(getGodot(), getPluginName(), signalInfo, signalArgs);
} catch (IllegalArgumentException exception) {
- Log.w(TAG, exception.getMessage());
+ Log.w(TAG, exception);
if (BuildConfig.DEBUG) {
throw exception;
}
@@ -368,7 +359,7 @@ public abstract class GodotPlugin {
/**
* Emit a Godot signal.
- * @param godot
+ * @param godot Godot instance
* @param pluginName Name of the Godot plugin the signal will be emitted from. The plugin must already be registered with the Godot engine.
* @param signalInfo Information about the signal to emit.
* @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the given {@link SignalInfo} parameter.
@@ -397,7 +388,7 @@ public abstract class GodotPlugin {
godot.runOnRenderThread(() -> nativeEmitSignal(pluginName, signalInfo.getName(), signalArgs));
} catch (IllegalArgumentException exception) {
- Log.w(TAG, exception.getMessage());
+ Log.w(TAG, exception);
if (BuildConfig.DEBUG) {
throw exception;
}
@@ -420,13 +411,7 @@ public abstract class GodotPlugin {
private static native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params);
/**
- * Used to register gdextension libraries bundled by the plugin.
- * @param gdextensionPaths Paths to the libraries relative to the 'assets' directory.
- */
- private static native void nativeRegisterGDExtensionLibraries(String[] gdextensionPaths);
-
- /**
- * Used to complete registration of the {@link GodotPlugin} instance's methods.
+ * Used to complete registration of the {@link GodotPlugin} instance's signals.
* @param pluginName Name of the plugin
* @param signalName Name of the signal to register
* @param signalParamTypes Signal parameters types
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
index c2428de2e1..d338b72441 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
@@ -52,7 +52,14 @@ import java.util.concurrent.ConcurrentHashMap;
public final class GodotPluginRegistry {
private static final String TAG = GodotPluginRegistry.class.getSimpleName();
+ /**
+ * Prefix used for version 1 of the Godot plugin, mostly compatible with Godot 3.x
+ */
private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1.";
+ /**
+ * Prefix used for version 2 of the Godot plugin, compatible with Godot 4.2+
+ */
+ private static final String GODOT_PLUGIN_V2_NAME_PREFIX = "org.godotengine.plugin.v2.";
private static GodotPluginRegistry instance;
private final ConcurrentHashMap<String, GodotPlugin> registry;
@@ -123,11 +130,17 @@ public final class GodotPluginRegistry {
return;
}
- int godotPluginV1NamePrefixLength = GODOT_PLUGIN_V1_NAME_PREFIX.length();
for (String metaDataName : metaData.keySet()) {
// Parse the meta-data looking for entry with the Godot plugin name prefix.
- if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) {
- String pluginName = metaDataName.substring(godotPluginV1NamePrefixLength).trim();
+ String pluginName = null;
+ if (metaDataName.startsWith(GODOT_PLUGIN_V2_NAME_PREFIX)) {
+ pluginName = metaDataName.substring(GODOT_PLUGIN_V2_NAME_PREFIX.length()).trim();
+ } else if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) {
+ pluginName = metaDataName.substring(GODOT_PLUGIN_V1_NAME_PREFIX.length()).trim();
+ Log.w(TAG, "Godot v1 plugin are deprecated in Godot 4.2 and higher: " + pluginName);
+ }
+
+ if (!TextUtils.isEmpty(pluginName)) {
Log.i(TAG, "Initializing Godot plugin " + pluginName);
// Retrieve the plugin class full name.
@@ -149,15 +162,7 @@ public final class GodotPluginRegistry {
}
registry.put(pluginName, pluginHandle);
Log.i(TAG, "Completed initialization for Godot plugin " + pluginHandle.getPluginName());
- } catch (ClassNotFoundException e) {
- Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
- } catch (IllegalAccessException e) {
- Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
- } catch (InstantiationException e) {
- Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
- } catch (NoSuchMethodException e) {
- Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
- } catch (InvocationTargetException e) {
+ } catch (Exception e) {
Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
}
} else {
@@ -165,7 +170,7 @@ public final class GodotPluginRegistry {
}
}
}
- } catch (PackageManager.NameNotFoundException e) {
+ } catch (Exception e) {
Log.e(TAG, "Unable load Godot Android plugins from the manifest file.", e);
}
}
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 79ba2528ba..a01a74f1fd 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -79,6 +79,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
_begin_benchmark_measure = p_env->GetMethodID(godot_class, "nativeBeginBenchmarkMeasure", "(Ljava/lang/String;)V");
_end_benchmark_measure = p_env->GetMethodID(godot_class, "nativeEndBenchmarkMeasure", "(Ljava/lang/String;)V");
_dump_benchmark = p_env->GetMethodID(godot_class, "nativeDumpBenchmark", "(Ljava/lang/String;)V");
+ _get_gdextension_list_config_file = p_env->GetMethodID(godot_class, "getGDExtensionConfigFiles", "()[Ljava/lang/String;");
}
GodotJavaWrapper::~GodotJavaWrapper() {
@@ -264,6 +265,25 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const {
return permissions_list;
}
+Vector<String> GodotJavaWrapper::get_gdextension_list_config_file() const {
+ Vector<String> config_file_list;
+ if (_get_gdextension_list_config_file) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_NULL_V(env, config_file_list);
+ jobject config_file_list_object = env->CallObjectMethod(godot_instance, _get_gdextension_list_config_file);
+ jobjectArray *arr = reinterpret_cast<jobjectArray *>(&config_file_list_object);
+
+ jsize len = env->GetArrayLength(*arr);
+ for (int i = 0; i < len; i++) {
+ jstring j_config_file = (jstring)env->GetObjectArrayElement(*arr, i);
+ String config_file = jstring_to_string(j_config_file, env);
+ config_file_list.push_back(config_file);
+ env->DeleteLocalRef(j_config_file);
+ }
+ }
+ return config_file_list;
+}
+
String GodotJavaWrapper::get_ca_certificates() const {
if (_get_ca_certificates) {
JNIEnv *env = get_jni_env();
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index ba42d5dccd..2ce756807f 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -59,6 +59,7 @@ private:
jmethodID _request_permission = nullptr;
jmethodID _request_permissions = nullptr;
jmethodID _get_granted_permissions = nullptr;
+ jmethodID _get_gdextension_list_config_file = nullptr;
jmethodID _get_ca_certificates = nullptr;
jmethodID _init_input_devices = nullptr;
jmethodID _vibrate = nullptr;
@@ -102,6 +103,9 @@ public:
void begin_benchmark_measure(const String &p_label);
void end_benchmark_measure(const String &p_label);
void dump_benchmark(const String &benchmark_file);
+
+ // Return the list of gdextensions config file.
+ Vector<String> get_gdextension_list_config_file() const;
};
#endif // JAVA_GODOT_WRAPPER_H
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index c040d8c4c6..8f80516a9f 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -39,6 +39,8 @@
#include "net_socket_android.h"
#include "core/config/project_settings.h"
+#include "core/extension/gdextension_manager.h"
+#include "core/io/xml_parser.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "main/main.h"
@@ -162,11 +164,39 @@ Vector<String> OS_Android::get_granted_permissions() const {
Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = p_path;
+ bool so_file_exists = true;
if (!FileAccess::exists(path)) {
path = p_path.get_file();
+ so_file_exists = false;
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
+ if (!p_library_handle && so_file_exists) {
+ // The library may be on the sdcard and thus inaccessible. Try to copy it to the internal
+ // directory.
+ uint64_t so_modified_time = FileAccess::get_modified_time(p_path);
+ String dynamic_library_path = get_dynamic_libraries_path().path_join(String::num_uint64(so_modified_time));
+ String internal_path = dynamic_library_path.path_join(p_path.get_file());
+
+ bool internal_so_file_exists = FileAccess::exists(internal_path);
+ if (!internal_so_file_exists) {
+ Ref<DirAccess> da_ref = DirAccess::create_for_path(p_path);
+ if (da_ref.is_valid()) {
+ Error create_dir_result = da_ref->make_dir_recursive(dynamic_library_path);
+ if (create_dir_result == OK || create_dir_result == ERR_ALREADY_EXISTS) {
+ internal_so_file_exists = da_ref->copy(path, internal_path) == OK;
+ }
+ }
+ }
+
+ if (internal_so_file_exists) {
+ p_library_handle = dlopen(internal_path.utf8().get_data(), RTLD_NOW);
+ if (p_library_handle) {
+ path = internal_path;
+ }
+ }
+ }
+
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror()));
if (r_resolved_path != nullptr) {
@@ -584,6 +614,10 @@ String OS_Android::get_user_data_dir() const {
return ".";
}
+String OS_Android::get_dynamic_libraries_path() const {
+ return get_cache_path().path_join("dynamic_libraries");
+}
+
String OS_Android::get_cache_path() const {
if (!cache_dir_cache.is_empty()) {
return cache_dir_cache;
@@ -791,5 +825,13 @@ Error OS_Android::setup_remote_filesystem(const String &p_server_host, int p_por
return err;
}
+void OS_Android::load_platform_gdextensions() const {
+ Vector<String> extension_list_config_file = godot_java->get_gdextension_list_config_file();
+ for (String config_file_path : extension_list_config_file) {
+ GDExtensionManager::LoadStatus err = GDExtensionManager::get_singleton()->load_extension(config_file_path);
+ ERR_CONTINUE_MSG(err == GDExtensionManager::LOAD_STATUS_FAILED, "Error loading platform extension: " + config_file_path);
+ }
+}
+
OS_Android::~OS_Android() {
}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index abcc412588..f88f3e0518 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -169,9 +169,15 @@ public:
virtual void benchmark_end_measure(const String &p_what) override;
virtual void benchmark_dump() override;
+ virtual void load_platform_gdextensions() const override;
+
virtual bool _check_internal_feature_support(const String &p_feature) override;
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
~OS_Android();
+
+private:
+ // Location where we relocate external dynamic libraries to make them accessible.
+ String get_dynamic_libraries_path() const;
};
#endif // OS_ANDROID_H
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index 5d48c4e248..fd60ba4ae7 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -129,31 +129,4 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
singleton->emit_signalp(StringName(signal_name), args, count);
}
-
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDExtensionLibraries(JNIEnv *env, jclass clazz, jobjectArray gdextension_paths) {
- int gdextension_count = env->GetArrayLength(gdextension_paths);
- if (gdextension_count == 0) {
- return;
- }
-
- // Retrieve the current list of gdextension libraries.
- Array singletons;
- if (ProjectSettings::get_singleton()->has_setting("gdextension/singletons")) {
- singletons = GLOBAL_GET("gdextension/singletons");
- }
-
- // Insert the libraries provided by the plugin
- for (int i = 0; i < gdextension_count; i++) {
- jstring relative_path = (jstring)env->GetObjectArrayElement(gdextension_paths, i);
-
- String path = "res://" + jstring_to_string(relative_path, env);
- if (!singletons.has(path)) {
- singletons.push_back(path);
- }
- env->DeleteLocalRef(relative_path);
- }
-
- // Insert the updated list back into project settings.
- ProjectSettings::get_singleton()->set("gdextension/singletons", singletons);
-}
}
diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h
index 36a992246d..baa29a79ea 100644
--- a/platform/android/plugin/godot_plugin_jni.h
+++ b/platform/android/plugin/godot_plugin_jni.h
@@ -39,7 +39,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDExtensionLibraries(JNIEnv *env, jclass clazz, jobjectArray gdextension_paths);
}
#endif // GODOT_PLUGIN_JNI_H
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index b6320fb22b..a8596c30a6 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "editor/import/resource_importer_texture_settings.h"
#include "editor/plugins/script_editor_plugin.h"
@@ -2013,11 +2014,11 @@ Ref<ImageTexture> EditorExportPlatformIOS::get_option_icon(int p_index) const {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
if (devices[p_index].simulator) {
- icon = theme->get_icon("IOSSimulator", "EditorIcons");
+ icon = theme->get_icon("IOSSimulator", EditorStringName(EditorIcons));
} else if (devices[p_index].wifi) {
- icon = theme->get_icon("IOSDeviceWireless", "EditorIcons");
+ icon = theme->get_icon("IOSDeviceWireless", EditorStringName(EditorIcons));
} else {
- icon = theme->get_icon("IOSDeviceWired", "EditorIcons");
+ icon = theme->get_icon("IOSDeviceWired", EditorStringName(EditorIcons));
}
}
}
diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h
index 7de4c0b69d..27a4d73fcd 100644
--- a/platform/ios/export/export_plugin.h
+++ b/platform/ios/export/export_plugin.h
@@ -181,9 +181,17 @@ public:
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override {
List<String> list;
- list.push_back("ipa");
+ if (p_preset.is_valid()) {
+ bool project_only = p_preset->get("application/export_project_only");
+ if (project_only) {
+ list.push_back("xcodeproj");
+ } else {
+ list.push_back("ipa");
+ }
+ }
return list;
}
+
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp
index 40151b1a02..9d1e058b76 100644
--- a/platform/linuxbsd/export/export_plugin.cpp
+++ b/platform/linuxbsd/export/export_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "modules/modules_enabled.gen.h" // For svg.
@@ -530,7 +531,7 @@ EditorExportPlatformLinuxBSD::EditorExportPlatformLinuxBSD() {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
- stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons"));
+ stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
} else {
stop_icon.instantiate();
}
diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 6586fe7f82..559c2c4e62 100644
--- a/platform/macos/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -41,6 +41,7 @@
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/import/resource_importer_texture_settings.h"
#include "scene/resources/image_texture.h"
@@ -2460,7 +2461,7 @@ EditorExportPlatformMacOS::EditorExportPlatformMacOS() {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
- stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons"));
+ stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
} else {
stop_icon.instantiate();
}
diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h
index 0d18ac742a..c6060c96c6 100644
--- a/platform/macos/godot_content_view.h
+++ b/platform/macos/godot_content_view.h
@@ -47,9 +47,11 @@
@interface GodotContentLayerDelegate : NSObject <CALayerDelegate> {
DisplayServer::WindowID window_id;
+ bool need_redraw;
}
- (void)setWindowID:(DisplayServer::WindowID)wid;
+- (void)setNeedRedraw:(bool)redraw;
@end
diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm
index 231be83a03..8b6e1cdb79 100644
--- a/platform/macos/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -40,6 +40,7 @@
- (id)init {
self = [super init];
window_id = DisplayServer::INVALID_WINDOW_ID;
+ need_redraw = false;
return self;
}
@@ -47,13 +48,18 @@
window_id = wid;
}
+- (void)setNeedRedraw:(bool)redraw {
+ need_redraw = redraw;
+}
+
- (void)displayLayer:(CALayer *)layer {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
- if (OS::get_singleton()->get_main_loop() && ds->get_is_resizing()) {
+ if (OS::get_singleton()->get_main_loop() && ds->get_is_resizing() && need_redraw) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
Main::iteration();
}
+ need_redraw = false;
}
}
@@ -93,6 +99,7 @@
}
[super setFrameSize:newSize];
+ [layer_delegate setNeedRedraw:true];
[self.layer setNeedsDisplay]; // Force "drawRect" call.
}
diff --git a/platform/uwp/README.md b/platform/uwp/README.md
deleted file mode 100644
index d69a8a8850..0000000000
--- a/platform/uwp/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# UWP platform port
-
-> **Warning**
->
-> The UWP platform port is not currently in a working state for the `master`
-> branch, and may be dropped in the future.
-
-This folder contains the C++ code for the Universal Windows Platform (UWP)
-platform port. **This is not to be confused with the "standard" Win32 port**,
-which is available in [`platform/windows`](/platform/windows).
-
-See also [`misc/dist/uwp_template`](/misc/dist/uwp_template) folder for the UWP
-project template used for packaging the UWP export templates.
-
-## Documentation
-
-- [Compiling for Universal Windows Platform](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_uwp.html)
- - Instructions on building this platform port from source.
-- [Exporting for Universal Windows Platform](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_uwp.html)
- - Instructions on using the compiled export templates to export a project.
diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub
deleted file mode 100644
index 8726d32d61..0000000000
--- a/platform/uwp/SCsub
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-files = [
- "#platform/windows/key_mapping_windows.cpp",
- "#platform/windows/windows_terminal_logger.cpp",
- "joypad_uwp.cpp",
- "context_egl_uwp.cpp",
- "app_uwp.cpp",
- "os_uwp.cpp",
-]
-
-if "build_angle" in env and env["build_angle"]:
- cmd = env.AlwaysBuild(env.ANGLE("libANGLE.lib", None))
-
-prog = env.add_program("#bin/godot", files)
-
-if "build_angle" in env and env["build_angle"]:
- env.Depends(prog, [cmd])
diff --git a/platform/uwp/app_uwp.cpp b/platform/uwp/app_uwp.cpp
deleted file mode 100644
index 789adb5e5b..0000000000
--- a/platform/uwp/app_uwp.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-/**************************************************************************/
-/* app_uwp.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "app_uwp.h"
-
-#include "core/io/dir_access.h"
-#include "core/io/file_access.h"
-#include "core/os/keyboard.h"
-#include "main/main.h"
-#include "platform/windows/key_mapping_windows.h"
-
-#include <collection.h>
-
-using namespace Windows::ApplicationModel::Core;
-using namespace Windows::ApplicationModel::Activation;
-using namespace Windows::UI::Core;
-using namespace Windows::UI::Input;
-using namespace Windows::Devices::Input;
-using namespace Windows::UI::Xaml::Input;
-using namespace Windows::Foundation;
-using namespace Windows::Graphics::Display;
-using namespace Windows::System;
-using namespace Windows::System::Threading::Core;
-using namespace Microsoft::WRL;
-
-using namespace GodotUWP;
-
-// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
-inline float ConvertDipsToPixels(float dips, float dpi) {
- static const float dipsPerInch = 96.0f;
- return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
-}
-
-// Implementation of the IFrameworkViewSource interface, necessary to run our app.
-ref class GodotUWPViewSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource {
-public:
- virtual Windows::ApplicationModel::Core::IFrameworkView ^ CreateView() {
- return ref new App();
- }
-};
-
-// The main function creates an IFrameworkViewSource for our app, and runs the app.
-[Platform::MTAThread] int main(Platform::Array<Platform::String ^> ^) {
- auto godotApplicationSource = ref new GodotUWPViewSource();
- CoreApplication::Run(godotApplicationSource);
- return 0;
-}
-
-// The first method called when the IFrameworkView is being created.
-void App::Initialize(CoreApplicationView ^ applicationView) {
- // Register event handlers for app lifecycle. This example includes Activated, so that we
- // can make the CoreWindow active and start rendering on the window.
- applicationView->Activated +=
- ref new TypedEventHandler<CoreApplicationView ^, IActivatedEventArgs ^>(this, &App::OnActivated);
-
- // Logic for other event handlers could go here.
- // Information about the Suspending and Resuming event handlers can be found here:
- // http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
-
- os = new OS_UWP;
-}
-
-// Called when the CoreWindow object is created (or re-created).
-void App::SetWindow(CoreWindow ^ p_window) {
- window = p_window;
- window->VisibilityChanged +=
- ref new TypedEventHandler<CoreWindow ^, VisibilityChangedEventArgs ^>(this, &App::OnVisibilityChanged);
-
- window->Closed +=
- ref new TypedEventHandler<CoreWindow ^, CoreWindowEventArgs ^>(this, &App::OnWindowClosed);
-
- window->SizeChanged +=
- ref new TypedEventHandler<CoreWindow ^, WindowSizeChangedEventArgs ^>(this, &App::OnWindowSizeChanged);
-
-#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- // Disable all pointer visual feedback for better performance when touching.
- // This is not supported on Windows Phone applications.
- auto pointerVisualizationSettings = PointerVisualizationSettings::GetForCurrentView();
- pointerVisualizationSettings->IsContactFeedbackEnabled = false;
- pointerVisualizationSettings->IsBarrelButtonFeedbackEnabled = false;
-#endif
-
- window->PointerPressed +=
- ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerPressed);
- window->PointerMoved +=
- ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerMoved);
- window->PointerReleased +=
- ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerReleased);
- window->PointerWheelChanged +=
- ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerWheelChanged);
-
- mouseChangedNotifier = SignalNotifier::AttachToEvent(L"os_mouse_mode_changed", ref new SignalHandler(this, &App::OnMouseModeChanged));
-
- mouseChangedNotifier->Enable();
-
- window->CharacterReceived +=
- ref new TypedEventHandler<CoreWindow ^, CharacterReceivedEventArgs ^>(this, &App::OnCharacterReceived);
- window->KeyDown +=
- ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &App::OnKeyDown);
- window->KeyUp +=
- ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &App::OnKeyUp);
-
- os->set_window(window);
-
- unsigned int argc;
- char **argv = get_command_line(&argc);
-
- Main::setup("uwp", argc, argv, false);
-
- UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
-
- Main::setup2();
-}
-
-static MouseButton _get_button(Windows::UI::Input::PointerPoint ^ pt) {
- using namespace Windows::UI::Input;
-
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- return MOUSE_BUTTON_LEFT;
-#else
- switch (pt->Properties->PointerUpdateKind) {
- case PointerUpdateKind::LeftButtonPressed:
- case PointerUpdateKind::LeftButtonReleased:
- return MOUSE_BUTTON_LEFT;
-
- case PointerUpdateKind::RightButtonPressed:
- case PointerUpdateKind::RightButtonReleased:
- return MOUSE_BUTTON_RIGHT;
-
- case PointerUpdateKind::MiddleButtonPressed:
- case PointerUpdateKind::MiddleButtonReleased:
- return MOUSE_BUTTON_MIDDLE;
-
- case PointerUpdateKind::XButton1Pressed:
- case PointerUpdateKind::XButton1Released:
- return MOUSE_BUTTON_WHEEL_UP;
-
- case PointerUpdateKind::XButton2Pressed:
- case PointerUpdateKind::XButton2Released:
- return MOUSE_BUTTON_WHEEL_DOWN;
-
- default:
- break;
- }
-#endif
-
- return MOUSE_BUTTON_NONE;
-}
-
-static bool _is_touch(Windows::UI::Input::PointerPoint ^ pointerPoint) {
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- return true;
-#else
- using namespace Windows::Devices::Input;
- switch (pointerPoint->PointerDevice->PointerDeviceType) {
- case PointerDeviceType::Touch:
- case PointerDeviceType::Pen:
- return true;
- default:
- return false;
- }
-#endif
-}
-
-static Windows::Foundation::Point _get_pixel_position(CoreWindow ^ window, Windows::Foundation::Point rawPosition, OS *os) {
- Windows::Foundation::Point outputPosition;
-
-// Compute coordinates normalized from 0..1.
-// If the coordinates need to be sized to the SDL window,
-// we'll do that after.
-#if 1 || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
- outputPosition.X = rawPosition.X / window->Bounds.Width;
- outputPosition.Y = rawPosition.Y / window->Bounds.Height;
-#else
- switch (DisplayProperties::CurrentOrientation) {
- case DisplayOrientations::Portrait:
- outputPosition.X = rawPosition.X / window->Bounds.Width;
- outputPosition.Y = rawPosition.Y / window->Bounds.Height;
- break;
- case DisplayOrientations::PortraitFlipped:
- outputPosition.X = 1.0f - (rawPosition.X / window->Bounds.Width);
- outputPosition.Y = 1.0f - (rawPosition.Y / window->Bounds.Height);
- break;
- case DisplayOrientations::Landscape:
- outputPosition.X = rawPosition.Y / window->Bounds.Height;
- outputPosition.Y = 1.0f - (rawPosition.X / window->Bounds.Width);
- break;
- case DisplayOrientations::LandscapeFlipped:
- outputPosition.X = 1.0f - (rawPosition.Y / window->Bounds.Height);
- outputPosition.Y = rawPosition.X / window->Bounds.Width;
- break;
- default:
- break;
- }
-#endif
-
- OS::VideoMode vm = os->get_video_mode();
- outputPosition.X *= vm.width;
- outputPosition.Y *= vm.height;
-
- return outputPosition;
-}
-
-static int _get_finger(uint32_t p_touch_id) {
- return p_touch_id % 31; // for now
-}
-
-void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args, bool p_pressed, bool p_is_wheel) {
- Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
- Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
- MouseButton but = _get_button(point);
- if (_is_touch(point)) {
- Ref<InputEventScreenTouch> screen_touch;
- screen_touch.instantiate();
- screen_touch->set_device(0);
- screen_touch->set_pressed(p_pressed);
- screen_touch->set_position(Vector2(pos.X, pos.Y));
- screen_touch->set_index(_get_finger(point->PointerId));
-
- last_touch_x[screen_touch->get_index()] = pos.X;
- last_touch_y[screen_touch->get_index()] = pos.Y;
-
- os->input_event(screen_touch);
- } else {
- Ref<InputEventMouseButton> mouse_button;
- mouse_button.instantiate();
- mouse_button->set_device(0);
- mouse_button->set_pressed(p_pressed);
- mouse_button->set_button_index(but);
- mouse_button->set_position(Vector2(pos.X, pos.Y));
- mouse_button->set_global_position(Vector2(pos.X, pos.Y));
-
- if (p_is_wheel) {
- if (point->Properties->MouseWheelDelta > 0) {
- mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? MOUSE_BUTTON_WHEEL_RIGHT : MOUSE_BUTTON_WHEEL_UP);
- } else if (point->Properties->MouseWheelDelta < 0) {
- mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? MOUSE_BUTTON_WHEEL_LEFT : MOUSE_BUTTON_WHEEL_DOWN);
- }
- }
-
- last_touch_x[31] = pos.X;
- last_touch_y[31] = pos.Y;
-
- os->input_event(mouse_button);
-
- if (p_is_wheel) {
- // Send release for mouse wheel
- mouse_button->set_pressed(false);
- os->input_event(mouse_button);
- }
- }
-}
-
-void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- pointer_event(sender, args, true);
-}
-
-void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- pointer_event(sender, args, false);
-}
-
-void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- pointer_event(sender, args, true, true);
-}
-
-void App::OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier ^ signalNotifier, bool timedOut) {
- OS::MouseMode mode = os->get_mouse_mode();
- SignalNotifier ^ notifier = mouseChangedNotifier;
-
- window->Dispatcher->RunAsync(
- CoreDispatcherPriority::High,
- ref new DispatchedHandler(
- [mode, notifier, this]() {
- if (mode == OS::MOUSE_MODE_CAPTURED) {
- this->MouseMovedToken = MouseDevice::GetForCurrentView()->MouseMoved +=
- ref new TypedEventHandler<MouseDevice ^, MouseEventArgs ^>(this, &App::OnMouseMoved);
-
- } else {
- MouseDevice::GetForCurrentView()->MouseMoved -= MouseMovedToken;
- }
-
- notifier->Enable();
- }));
-
- ResetEvent(os->mouse_mode_changed);
-}
-
-void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
- Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
-
- if (_is_touch(point)) {
- Ref<InputEventScreenDrag> screen_drag;
- screen_drag.instantiate();
- screen_drag->set_device(0);
- screen_drag->set_position(Vector2(pos.X, pos.Y));
- screen_drag->set_index(_get_finger(point->PointerId));
- screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
-
- os->input_event(screen_drag);
- } else {
- // In case the mouse grabbed, MouseMoved will handle this
- if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) {
- return;
- }
-
- Ref<InputEventMouseMotion> mouse_motion;
- mouse_motion.instantiate();
- mouse_motion->set_device(0);
- mouse_motion->set_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
-
- last_mouse_pos = pos;
-
- os->input_event(mouse_motion);
- }
-}
-
-void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
- // In case the mouse isn't grabbed, PointerMoved will handle this
- if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED) {
- return;
- }
-
- Windows::Foundation::Point pos;
- pos.X = last_mouse_pos.X + args->MouseDelta.X;
- pos.Y = last_mouse_pos.Y + args->MouseDelta.Y;
-
- Ref<InputEventMouseMotion> mouse_motion;
- mouse_motion.instantiate();
- mouse_motion->set_device(0);
- mouse_motion->set_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_relative(Vector2(args->MouseDelta.X, args->MouseDelta.Y));
-
- last_mouse_pos = pos;
-
- os->input_event(mouse_motion);
-}
-
-void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) {
- OS_UWP::KeyEvent ke;
-
- ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
- ke.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
- ke.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
-
- ke.pressed = p_pressed;
-
- if (key_args != nullptr) {
- ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE;
- ke.unicode = 0;
- ke.keycode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey);
- ke.physical_keycode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode, key_args->KeyStatus.IsExtendedKey);
- ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown);
-
- } else {
- ke.type = OS_UWP::KeyEvent::MessageType::CHAR_EVENT_MESSAGE;
- ke.unicode = char_args->KeyCode;
- ke.keycode = 0;
- ke.physical_keycode = 0;
- ke.echo = (!p_pressed && !char_args->KeyStatus.IsKeyReleased) || (p_pressed && char_args->KeyStatus.WasKeyDown);
- }
-
- os->queue_key_event(ke);
-}
-
-void App::OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args) {
- key_event(sender, true, args);
-}
-
-void App::OnKeyUp(CoreWindow ^ sender, KeyEventArgs ^ args) {
- key_event(sender, false, args);
-}
-
-void App::OnCharacterReceived(CoreWindow ^ sender, CharacterReceivedEventArgs ^ args) {
- key_event(sender, true, nullptr, args);
-}
-
-// Initializes scene resources
-void App::Load(Platform::String ^ entryPoint) {
-}
-
-// This method is called after the window becomes active.
-void App::Run() {
- if (Main::start()) {
- os->run();
- }
-}
-
-// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
-// class is torn down while the app is in the foreground.
-void App::Uninitialize() {
- Main::cleanup();
- delete os;
-}
-
-// Application lifecycle event handler.
-void App::OnActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) {
- // Run() won't start until the CoreWindow is activated.
- CoreWindow::GetForCurrentThread()->Activate();
-}
-
-// Window event handlers.
-void App::OnVisibilityChanged(CoreWindow ^ sender, VisibilityChangedEventArgs ^ args) {
- mWindowVisible = args->Visible;
-}
-
-void App::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) {
- mWindowClosed = true;
-}
-
-void App::OnWindowSizeChanged(CoreWindow ^ sender, WindowSizeChangedEventArgs ^ args) {
-#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
- // On Windows 8.1, apps are resized when they are snapped alongside other apps, or when the device is rotated.
- // The default framebuffer will be automatically resized when either of these occur.
- // In particular, on a 90 degree rotation, the default framebuffer's width and height will switch.
- UpdateWindowSize(args->Size);
-#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- // On Windows Phone 8.1, the window size changes when the device is rotated.
- // The default framebuffer will not be automatically resized when this occurs.
- // It is therefore up to the app to handle rotation-specific logic in its rendering code.
- //os->screen_size_changed();
- UpdateWindowSize(args->Size);
-#endif
-}
-
-void App::UpdateWindowSize(Size size) {
- float dpi;
-#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
- DisplayInformation ^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
- dpi = currentDisplayInformation->LogicalDpi;
-#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- dpi = DisplayProperties::LogicalDpi;
-#endif
- Size pixelSize(ConvertDipsToPixels(size.Width, dpi), ConvertDipsToPixels(size.Height, dpi));
-
- mWindowWidth = static_cast<GLsizei>(pixelSize.Width);
- mWindowHeight = static_cast<GLsizei>(pixelSize.Height);
-
- OS::VideoMode vm;
- vm.width = mWindowWidth;
- vm.height = mWindowHeight;
- vm.fullscreen = true;
- vm.resizable = false;
- os->set_video_mode(vm);
-}
-
-char **App::get_command_line(unsigned int *out_argc) {
- static char *fail_cl[] = { "--path", "game", nullptr };
- *out_argc = 2;
-
- FILE *f = _wfopen(L"__cl__.cl", L"rb");
-
- if (f == nullptr) {
- wprintf(L"Couldn't open command line file.\n");
- return fail_cl;
- }
-
-#define READ_LE_4(v) ((int)(##v[3] & 0xFF) << 24) | ((int)(##v[2] & 0xFF) << 16) | ((int)(##v[1] & 0xFF) << 8) | ((int)(##v[0] & 0xFF))
-#define CMD_MAX_LEN 65535
-
- uint8_t len[4];
- int r = fread(len, sizeof(uint8_t), 4, f);
-
- Platform::Collections::Vector<Platform::String ^> cl;
-
- if (r < 4) {
- fclose(f);
- wprintf(L"Wrong cmdline length.\n");
- return (fail_cl);
- }
-
- int argc = READ_LE_4(len);
-
- for (int i = 0; i < argc; i++) {
- r = fread(len, sizeof(uint8_t), 4, f);
-
- if (r < 4) {
- fclose(f);
- wprintf(L"Wrong cmdline param length.\n");
- return (fail_cl);
- }
-
- int strlen = READ_LE_4(len);
-
- if (strlen > CMD_MAX_LEN) {
- fclose(f);
- wprintf(L"Wrong command length.\n");
- return (fail_cl);
- }
-
- char *arg = new char[strlen + 1];
- r = fread(arg, sizeof(char), strlen, f);
- arg[strlen] = '\0';
-
- if (r == strlen) {
- int warg_size = MultiByteToWideChar(CP_UTF8, 0, arg, -1, nullptr, 0);
- wchar_t *warg = new wchar_t[warg_size];
-
- MultiByteToWideChar(CP_UTF8, 0, arg, -1, warg, warg_size);
-
- cl.Append(ref new Platform::String(warg, warg_size));
-
- } else {
- delete[] arg;
- fclose(f);
- wprintf(L"Error reading command.\n");
- return (fail_cl);
- }
- }
-
-#undef READ_LE_4
-#undef CMD_MAX_LEN
-
- fclose(f);
-
- char **ret = new char *[cl.Size + 1];
-
- for (int i = 0; i < cl.Size; i++) {
- int arg_size = WideCharToMultiByte(CP_UTF8, 0, cl.GetAt(i)->Data(), -1, nullptr, 0, nullptr, nullptr);
- char *arg = new char[arg_size];
-
- WideCharToMultiByte(CP_UTF8, 0, cl.GetAt(i)->Data(), -1, arg, arg_size, nullptr, nullptr);
-
- ret[i] = arg;
- }
- ret[cl.Size] = nullptr;
- *out_argc = cl.Size;
-
- return ret;
-}
diff --git a/platform/uwp/app_uwp.h b/platform/uwp/app_uwp.h
deleted file mode 100644
index 87c66bd679..0000000000
--- a/platform/uwp/app_uwp.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/**************************************************************************/
-/* app_uwp.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef APP_UWP_H
-#define APP_UWP_H
-
-#include "os_uwp.h"
-
-#include <GLES2/gl2.h>
-#include <wrl.h>
-#include <string>
-
-/** clang-format does not play nice with this C++/CX hybrid, needs investigation. */
-/* clang-format off */
-
-namespace GodotUWP
-{
- ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
- {
- public:
- App() {}
-
- // IFrameworkView Methods.
- virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
- virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
- virtual void Load(Platform::String^ entryPoint);
- virtual void Run();
- virtual void Uninitialize();
-
- property Windows::Foundation::EventRegistrationToken MouseMovedToken {
- Windows::Foundation::EventRegistrationToken get() { return this->mouseMovedToken; }
- void set(Windows::Foundation::EventRegistrationToken p_token) { this->mouseMovedToken = p_token; }
- }
-
- private:
- void RecreateRenderer();
-
- // Application lifecycle event handlers.
- void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
-
- // Window event handlers.
- void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
- void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
- void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
-
- void pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args, bool p_pressed, bool p_is_wheel = false);
- void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
- void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
- void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
- void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouse_device, Windows::Devices::Input::MouseEventArgs^ args);
- void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
-
- Windows::System::Threading::Core::SignalNotifier^ mouseChangedNotifier;
- Windows::Foundation::EventRegistrationToken mouseMovedToken;
- void OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier^ signalNotifier, bool timedOut);
-
- void key_event(Windows::UI::Core::CoreWindow^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs^ key_args = nullptr, Windows::UI::Core::CharacterReceivedEventArgs^ char_args = nullptr);
- void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
- void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
- void OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args);
-
- void UpdateWindowSize(Windows::Foundation::Size size);
- void InitializeEGL(Windows::UI::Core::CoreWindow^ window);
- void CleanupEGL();
-
- char** get_command_line(unsigned int* out_argc);
-
- bool mWindowClosed = false;
- bool mWindowVisible = true;
- GLsizei mWindowWidth = 0;
- GLsizei mWindowHeight = 0;
-
- EGLDisplay mEglDisplay = EGL_NO_DISPLAY;
- EGLContext mEglContext = EGL_NO_CONTEXT;
- EGLSurface mEglSurface = EGL_NO_SURFACE;
-
- CoreWindow^ window;
- OS_UWP* os;
-
- int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
- int last_touch_y[32];
- Windows::Foundation::Point last_mouse_pos;
- };
-}
-
-/* clang-format on */
-
-#endif // APP_UWP_H
diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp
deleted file mode 100644
index aa8cfb4d49..0000000000
--- a/platform/uwp/context_egl_uwp.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/**************************************************************************/
-/* context_egl_uwp.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "context_egl_uwp.h"
-
-#include <EGL/eglext.h>
-
-using Platform::Exception;
-
-void ContextEGL_UWP::release_current() {
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext);
-}
-
-void ContextEGL_UWP::make_current() {
- eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
-}
-
-int ContextEGL_UWP::get_window_width() {
- return width;
-}
-
-int ContextEGL_UWP::get_window_height() {
- return height;
-}
-
-void ContextEGL_UWP::reset() {
- cleanup();
-
- window = CoreWindow::GetForCurrentThread();
- initialize();
-}
-
-void ContextEGL_UWP::swap_buffers() {
- if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE) {
- cleanup();
-
- window = CoreWindow::GetForCurrentThread();
- initialize();
-
- // tell rasterizer to reload textures and stuff?
- }
-}
-
-Error ContextEGL_UWP::initialize() {
- EGLint configAttribList[] = {
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 8,
- EGL_STENCIL_SIZE, 8,
- EGL_SAMPLE_BUFFERS, 0,
- EGL_NONE
- };
-
- EGLint surfaceAttribList[] = {
- EGL_NONE, EGL_NONE
- };
-
- EGLint numConfigs = 0;
- EGLint majorVersion = 1;
- EGLint minorVersion;
- if (driver == GLES_2_0) {
- minorVersion = 0;
- } else {
- minorVersion = 5;
- }
- EGLDisplay display = EGL_NO_DISPLAY;
- EGLContext context = EGL_NO_CONTEXT;
- EGLSurface surface = EGL_NO_SURFACE;
- EGLConfig config = nullptr;
- EGLint contextAttribs[3];
- if (driver == GLES_2_0) {
- contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
- contextAttribs[1] = 2;
- contextAttribs[2] = EGL_NONE;
- } else {
- contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
- contextAttribs[1] = 3;
- contextAttribs[2] = EGL_NONE;
- }
-
- try {
- const EGLint displayAttributes[] = {
- /*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
- EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
- EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
- EGL_NONE,*/
- // These are the default display attributes, used to request ANGLE's D3D11 renderer.
- // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
- EGL_PLATFORM_ANGLE_TYPE_ANGLE,
- EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
-
- // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
- // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
- EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
- EGL_TRUE,
-
- // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
- // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
- // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
- EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
- EGL_TRUE,
- EGL_NONE,
- };
-
- PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
-
- if (!eglGetPlatformDisplayEXT) {
- throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT");
- }
-
- display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
-
- if (display == EGL_NO_DISPLAY) {
- throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display");
- }
-
- if (eglInitialize(display, &majorVersion, &minorVersion) == EGL_FALSE) {
- throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL");
- }
-
- if (eglGetConfigs(display, nullptr, 0, &numConfigs) == EGL_FALSE) {
- throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count");
- }
-
- if (eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) == EGL_FALSE) {
- throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig count");
- }
-
- surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable *>(window), surfaceAttribList);
- if (surface == EGL_NO_SURFACE) {
- throw Exception::CreateException(E_FAIL, L"Failed to create EGL fullscreen surface");
- }
-
- context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
- if (context == EGL_NO_CONTEXT) {
- throw Exception::CreateException(E_FAIL, L"Failed to create EGL context");
- }
-
- if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
- throw Exception::CreateException(E_FAIL, L"Failed to make fullscreen EGLSurface current");
- }
- } catch (...) {
- return FAILED;
- }
-
- mEglDisplay = display;
- mEglSurface = surface;
- mEglContext = context;
-
- eglQuerySurface(display, surface, EGL_WIDTH, &width);
- eglQuerySurface(display, surface, EGL_HEIGHT, &height);
-
- return OK;
-}
-
-void ContextEGL_UWP::cleanup() {
- if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mEglSurface);
- mEglSurface = EGL_NO_SURFACE;
- }
-
- if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mEglContext);
- mEglContext = EGL_NO_CONTEXT;
- }
-
- if (mEglDisplay != EGL_NO_DISPLAY) {
- eglTerminate(mEglDisplay);
- mEglDisplay = EGL_NO_DISPLAY;
- }
-}
-
-ContextEGL_UWP::ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver) :
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE),
- driver(p_driver),
- window(p_window),
- vsync(false) {}
-
-ContextEGL_UWP::~ContextEGL_UWP() {
- cleanup();
-}
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
deleted file mode 100644
index 604f5e48e3..0000000000
--- a/platform/uwp/detect.py
+++ /dev/null
@@ -1,216 +0,0 @@
-import methods
-import os
-import sys
-from platform_methods import detect_arch
-
-from typing import TYPE_CHECKING
-
-if TYPE_CHECKING:
- from SCons import Environment
-
-
-def get_name():
- return "UWP"
-
-
-def can_build():
- if os.name == "nt":
- # building natively on windows!
- if os.getenv("VSINSTALLDIR"):
- if os.getenv("ANGLE_SRC_PATH") is None:
- return False
-
- return True
- return False
-
-
-def get_opts():
- return [
- ("msvc_version", "MSVC version to use (ignored if the VCINSTALLDIR environment variable is set)", None),
- ]
-
-
-def get_flags():
- return [
- ("arch", detect_arch()),
- ("tools", False),
- ("xaudio2", True),
- ("builtin_pcre2_with_jit", False),
- ]
-
-
-def configure(env: "Environment"):
- # Validate arch.
- supported_arches = ["x86_32", "x86_64", "arm32"]
- if env["arch"] not in supported_arches:
- print(
- 'Unsupported CPU architecture "%s" for UWP. Supported architectures are: %s.'
- % (env["arch"], ", ".join(supported_arches))
- )
- sys.exit()
-
- env.msvc = True
-
- ## Build type
-
- if env["target"] == "release":
- env.Append(CCFLAGS=["/MD"])
- env.Append(LINKFLAGS=["/SUBSYSTEM:WINDOWS"])
- if env["optimize"] != "none":
- env.Append(CCFLAGS=["/O2", "/GL"])
- env.Append(LINKFLAGS=["/LTCG"])
-
- elif env["target"] == "release_debug":
- env.Append(CCFLAGS=["/MD"])
- env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
- env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
- if env["optimize"] != "none":
- env.Append(CCFLAGS=["/O2", "/Zi"])
-
- elif env["target"] == "debug":
- env.Append(CCFLAGS=["/Zi"])
- env.Append(CCFLAGS=["/MDd"])
- env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
- env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
- env.Append(LINKFLAGS=["/DEBUG"])
-
- ## Compiler configuration
-
- env["ENV"] = os.environ
- vc_base_path = os.environ["VCTOOLSINSTALLDIR"] if "VCTOOLSINSTALLDIR" in os.environ else os.environ["VCINSTALLDIR"]
-
- # Force to use Unicode encoding
- env.AppendUnique(CCFLAGS=["/utf-8"])
-
- # ANGLE
- angle_root = os.environ["ANGLE_SRC_PATH"]
- env.Prepend(CPPPATH=[angle_root + "/include"])
- jobs = str(env.GetOption("num_jobs"))
- angle_build_cmd = (
- "msbuild.exe "
- + angle_root
- + "/winrt/10/src/angle.sln /nologo /v:m /m:"
- + jobs
- + " /p:Configuration=Release /p:Platform="
- )
-
- if os.path.isfile(f"{angle_root}/winrt/10/src/angle.sln"):
- env["build_angle"] = True
-
- ## Architecture
-
- arch = ""
- if str(os.getenv("Platform")).lower() == "arm":
- print("Compiled program architecture will be an ARM executable (forcing arch=arm32).")
-
- arch = "arm"
- env["arch"] = "arm32"
- env.Append(LINKFLAGS=["/MACHINE:ARM"])
- env.Append(LIBPATH=[vc_base_path + "lib/store/arm"])
-
- angle_build_cmd += "ARM"
-
- env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_ARM/lib"])
-
- else:
- compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
-
- if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
- env["arch"] = "x86_64"
- print("Compiled program architecture will be a x64 executable (forcing arch=x86_64).")
- elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
- env["arch"] = "x86_32"
- print("Compiled program architecture will be a x86 executable (forcing arch=x86_32).")
- else:
- print(
- "Failed to detect MSVC compiler architecture version... Defaulting to x86 32-bit executable settings"
- " (forcing arch=x86_32). Compilation attempt will continue, but SCons can not detect for what architecture"
- " this build is compiled for. You should check your settings/compilation setup."
- )
- env["arch"] = "x86_32"
-
- if env["arch"] == "x86_32":
- arch = "x86"
-
- angle_build_cmd += "Win32"
-
- env.Append(LINKFLAGS=["/MACHINE:X86"])
- env.Append(LIBPATH=[vc_base_path + "lib/store"])
- env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_Win32/lib"])
-
- else:
- arch = "x64"
-
- angle_build_cmd += "x64"
-
- env.Append(LINKFLAGS=["/MACHINE:X64"])
- env.Append(LIBPATH=[os.environ["VCINSTALLDIR"] + "lib/store/amd64"])
- env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_x64/lib"])
-
- env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"]
- env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"]
- env["LIBSUFFIX"] = "." + arch + env["LIBSUFFIX"]
-
- ## Compile flags
-
- env.Prepend(CPPPATH=["#platform/uwp", "#drivers/windows"])
- env.Append(CPPDEFINES=["UWP_ENABLED", "WINDOWS_ENABLED", "TYPED_METHOD_BIND"])
- env.Append(CPPDEFINES=["GLES_ENABLED", "GL_GLEXT_PROTOTYPES", "EGL_EGLEXT_PROTOTYPES", "ANGLE_ENABLED"])
- winver = "0x0602" # Windows 8 is the minimum target for UWP build
- env.Append(CPPDEFINES=[("WINVER", winver), ("_WIN32_WINNT", winver), "WIN32"])
-
- env.Append(CPPDEFINES=["__WRL_NO_DEFAULT_LIB__", ("PNG_ABORT", "abort")])
-
- env.Append(CPPFLAGS=["/AI", vc_base_path + "lib/store/references"])
- env.Append(CPPFLAGS=["/AI", vc_base_path + "lib/x86/store/references"])
-
- env.Append(
- CCFLAGS=(
- '/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /errorReport:prompt /WX-'
- " /Zc:forScope /Gd /EHsc /nologo".split()
- )
- )
- env.Append(CPPDEFINES=["_UNICODE", "UNICODE", ("WINAPI_FAMILY", "WINAPI_FAMILY_APP")])
- env.Append(CXXFLAGS=["/ZW"])
- env.Append(
- CCFLAGS=[
- "/AI",
- vc_base_path + "\\vcpackages",
- "/AI",
- os.environ["WINDOWSSDKDIR"] + "\\References\\CommonConfiguration\\Neutral",
- ]
- )
-
- ## Link flags
-
- env.Append(
- LINKFLAGS=[
- "/MANIFEST:NO",
- "/NXCOMPAT",
- "/DYNAMICBASE",
- "/WINMD",
- "/APPCONTAINER",
- "/ERRORREPORT:PROMPT",
- "/NOLOGO",
- "/TLBID:1",
- '/NODEFAULTLIB:"kernel32.lib"',
- '/NODEFAULTLIB:"ole32.lib"',
- ]
- )
-
- LIBS = [
- "WindowsApp",
- "mincore",
- "ws2_32",
- "libANGLE",
- "libEGL",
- "libGLESv2",
- "bcrypt",
- ]
- env.Append(LINKFLAGS=[p + ".lib" for p in LIBS])
-
- # Incremental linking fix
- env["BUILDERS"]["ProgramOriginal"] = env["BUILDERS"]["Program"]
- env["BUILDERS"]["Program"] = methods.precious_program
-
- env.Append(BUILDERS={"ANGLE": env.Builder(action=angle_build_cmd)})
diff --git a/platform/uwp/export/app_packager.cpp b/platform/uwp/export/app_packager.cpp
deleted file mode 100644
index ffb5e31851..0000000000
--- a/platform/uwp/export/app_packager.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/**************************************************************************/
-/* app_packager.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "app_packager.h"
-
-#include "editor/editor_node.h"
-#include "editor/editor_paths.h"
-
-String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) {
- unsigned char hash[32];
- char base64[45];
-
- CryptoCore::sha256(p_block_data, p_block_len, hash);
- size_t len = 0;
- CryptoCore::b64_encode((unsigned char *)base64, 45, &len, (unsigned char *)hash, 32);
- base64[44] = '\0';
-
- return String(base64);
-}
-
-void AppxPackager::make_block_map(const String &p_path) {
- Ref<FileAccess> tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
-
- tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
- tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">");
-
- for (int i = 0; i < file_metadata.size(); i++) {
- FileMeta file = file_metadata[i];
-
- tmp_file->store_string(
- "<File Name=\"" + file.name.replace("/", "\\") + "\" Size=\"" + itos(file.uncompressed_size) + "\" LfhSize=\"" + itos(file.lfh_size) + "\">");
-
- for (int j = 0; j < file.hashes.size(); j++) {
- tmp_file->store_string("<Block Hash=\"" + file.hashes[j].base64_hash + "\" ");
- if (file.compressed) {
- tmp_file->store_string("Size=\"" + itos(file.hashes[j].compressed_size) + "\" ");
- }
- tmp_file->store_string("/>");
- }
-
- tmp_file->store_string("</File>");
- }
-
- tmp_file->store_string("</BlockMap>");
-}
-
-String AppxPackager::content_type(String p_extension) {
- if (p_extension == "png") {
- return "image/png";
- } else if (p_extension == "jpg") {
- return "image/jpg";
- } else if (p_extension == "xml") {
- return "application/xml";
- } else if (p_extension == "exe" || p_extension == "dll") {
- return "application/x-msdownload";
- } else {
- return "application/octet-stream";
- }
-}
-
-void AppxPackager::make_content_types(const String &p_path) {
- Ref<FileAccess> tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
-
- tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
-
- HashMap<String, String> types;
-
- for (int i = 0; i < file_metadata.size(); i++) {
- String ext = file_metadata[i].name.get_extension().to_lower();
-
- if (types.has(ext)) {
- continue;
- }
-
- types[ext] = content_type(ext);
-
- tmp_file->store_string("<Default Extension=\"" + ext + "\" ContentType=\"" + types[ext] + "\" />");
- }
-
- // Appx signature file
- tmp_file->store_string("<Default Extension=\"p7x\" ContentType=\"application/octet-stream\" />");
-
- // Override for package files
- tmp_file->store_string("<Override PartName=\"/AppxManifest.xml\" ContentType=\"application/vnd.ms-appx.manifest+xml\" />");
- tmp_file->store_string("<Override PartName=\"/AppxBlockMap.xml\" ContentType=\"application/vnd.ms-appx.blockmap+xml\" />");
- tmp_file->store_string("<Override PartName=\"/AppxSignature.p7x\" ContentType=\"application/vnd.ms-appx.signature\" />");
- tmp_file->store_string("<Override PartName=\"/AppxMetadata/CodeIntegrity.cat\" ContentType=\"application/vnd.ms-pkiseccat\" />");
-
- tmp_file->store_string("</Types>");
-}
-
-Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) {
- Vector<uint8_t> buf;
- buf.resize(BASE_FILE_HEADER_SIZE + p_file_meta.name.length());
-
- int offs = 0;
- // Write magic
- offs += buf_put_int32(FILE_HEADER_MAGIC, &buf.write[offs]);
-
- // Version
- offs += buf_put_int16(ZIP_VERSION, &buf.write[offs]);
-
- // Special flag
- offs += buf_put_int16(GENERAL_PURPOSE, &buf.write[offs]);
-
- // Compression
- offs += buf_put_int16(p_file_meta.compressed ? Z_DEFLATED : 0, &buf.write[offs]);
-
- // File date and time
- offs += buf_put_int32(0, &buf.write[offs]);
-
- // CRC-32
- offs += buf_put_int32(p_file_meta.file_crc32, &buf.write[offs]);
-
- // Compressed size
- offs += buf_put_int32(p_file_meta.compressed_size, &buf.write[offs]);
-
- // Uncompressed size
- offs += buf_put_int32(p_file_meta.uncompressed_size, &buf.write[offs]);
-
- // File name length
- offs += buf_put_int16(p_file_meta.name.length(), &buf.write[offs]);
-
- // Extra data length
- offs += buf_put_int16(0, &buf.write[offs]);
-
- // File name
- offs += buf_put_string(p_file_meta.name, &buf.write[offs]);
-
- // Done!
- return buf;
-}
-
-void AppxPackager::store_central_dir_header(const FileMeta &p_file, bool p_do_hash) {
- Vector<uint8_t> &buf = central_dir_data;
- int offs = buf.size();
- buf.resize(buf.size() + BASE_CENTRAL_DIR_SIZE + p_file.name.length());
-
- // Write magic
- offs += buf_put_int32(CENTRAL_DIR_MAGIC, &buf.write[offs]);
-
- // ZIP versions
- offs += buf_put_int16(ZIP_ARCHIVE_VERSION, &buf.write[offs]);
- offs += buf_put_int16(ZIP_VERSION, &buf.write[offs]);
-
- // General purpose flag
- offs += buf_put_int16(GENERAL_PURPOSE, &buf.write[offs]);
-
- // Compression
- offs += buf_put_int16(p_file.compressed ? Z_DEFLATED : 0, &buf.write[offs]);
-
- // Modification date/time
- offs += buf_put_int32(0, &buf.write[offs]);
-
- // Crc-32
- offs += buf_put_int32(p_file.file_crc32, &buf.write[offs]);
-
- // File sizes
- offs += buf_put_int32(p_file.compressed_size, &buf.write[offs]);
- offs += buf_put_int32(p_file.uncompressed_size, &buf.write[offs]);
-
- // File name length
- offs += buf_put_int16(p_file.name.length(), &buf.write[offs]);
-
- // Extra field length
- offs += buf_put_int16(0, &buf.write[offs]);
-
- // Comment length
- offs += buf_put_int16(0, &buf.write[offs]);
-
- // Disk number start, internal/external file attributes
- for (int i = 0; i < 8; i++) {
- buf.write[offs++] = 0;
- }
-
- // Relative offset
- offs += buf_put_int32(p_file.zip_offset, &buf.write[offs]);
-
- // File name
- offs += buf_put_string(p_file.name, &buf.write[offs]);
-
- // Done!
-}
-
-Vector<uint8_t> AppxPackager::make_end_of_central_record() {
- Vector<uint8_t> buf;
- buf.resize(ZIP64_END_OF_CENTRAL_DIR_SIZE + 12 + END_OF_CENTRAL_DIR_SIZE); // Size plus magic
-
- int offs = 0;
-
- // Write magic
- offs += buf_put_int32(ZIP64_END_OF_CENTRAL_DIR_MAGIC, &buf.write[offs]);
-
- // Size of this record
- offs += buf_put_int64(ZIP64_END_OF_CENTRAL_DIR_SIZE, &buf.write[offs]);
-
- // Version (yes, twice)
- offs += buf_put_int16(ZIP_ARCHIVE_VERSION, &buf.write[offs]);
- offs += buf_put_int16(ZIP_ARCHIVE_VERSION, &buf.write[offs]);
-
- // Disk number
- for (int i = 0; i < 8; i++) {
- buf.write[offs++] = 0;
- }
-
- // Number of entries (total and per disk)
- offs += buf_put_int64(file_metadata.size(), &buf.write[offs]);
- offs += buf_put_int64(file_metadata.size(), &buf.write[offs]);
-
- // Size of central dir
- offs += buf_put_int64(central_dir_data.size(), &buf.write[offs]);
-
- // Central dir offset
- offs += buf_put_int64(central_dir_offset, &buf.write[offs]);
-
- ////// ZIP64 locator
-
- // Write magic for zip64 central dir locator
- offs += buf_put_int32(ZIP64_END_DIR_LOCATOR_MAGIC, &buf.write[offs]);
-
- // Disk number
- for (int i = 0; i < 4; i++) {
- buf.write[offs++] = 0;
- }
-
- // Relative offset
- offs += buf_put_int64(end_of_central_dir_offset, &buf.write[offs]);
-
- // Number of disks
- offs += buf_put_int32(1, &buf.write[offs]);
-
- /////// End of zip directory
-
- // Write magic for end central dir
- offs += buf_put_int32(END_OF_CENTRAL_DIR_MAGIC, &buf.write[offs]);
-
- // Dummy stuff for Zip64
- for (int i = 0; i < 4; i++) {
- buf.write[offs++] = 0x0;
- }
- for (int i = 0; i < 12; i++) {
- buf.write[offs++] = 0xFF;
- }
-
- // Size of comments
- for (int i = 0; i < 2; i++) {
- buf.write[offs++] = 0;
- }
-
- // Done!
- return buf;
-}
-
-void AppxPackager::init(Ref<FileAccess> p_fa) {
- package = p_fa;
- central_dir_offset = 0;
- end_of_central_dir_offset = 0;
-}
-
-Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) {
- if (p_file_no >= 1 && p_total_files >= 1) {
- if (EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files)) {
- return ERR_SKIP;
- }
- }
-
- FileMeta meta;
- meta.name = p_file_name;
- meta.uncompressed_size = p_len;
- meta.compressed = p_compress;
- meta.zip_offset = package->get_position();
-
- Vector<uint8_t> file_buffer;
-
- // Data for compression
- z_stream strm{};
- Vector<uint8_t> strm_in;
- strm_in.resize(BLOCK_SIZE);
- Vector<uint8_t> strm_out;
-
- if (p_compress) {
- strm.zalloc = zipio_alloc;
- strm.zfree = zipio_free;
- strm.opaque = Z_NULL;
-
- strm_out.resize(BLOCK_SIZE + 8);
-
- deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
- }
-
- int step = 0;
-
- while (p_len - step > 0) {
- size_t block_size = (p_len - step) > BLOCK_SIZE ? (size_t)BLOCK_SIZE : (p_len - step);
-
- for (uint64_t i = 0; i < block_size; i++) {
- strm_in.write[i] = p_buffer[step + i];
- }
-
- BlockHash bh;
- bh.base64_hash = hash_block(strm_in.ptr(), block_size);
-
- if (p_compress) {
- strm.avail_in = block_size;
- strm.avail_out = strm_out.size();
- strm.next_in = (uint8_t *)strm_in.ptr();
- strm.next_out = strm_out.ptrw();
-
- int total_out_before = strm.total_out;
-
- int err = deflate(&strm, Z_FULL_FLUSH);
- ERR_FAIL_COND_V(err < 0, ERR_BUG); // Negative means bug
-
- bh.compressed_size = strm.total_out - total_out_before;
-
- //package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
- int start = file_buffer.size();
- file_buffer.resize(file_buffer.size() + bh.compressed_size);
- for (uint64_t i = 0; i < bh.compressed_size; i++) {
- file_buffer.write[start + i] = strm_out[i];
- }
- } else {
- bh.compressed_size = block_size;
- //package->store_buffer(strm_in.ptr(), block_size);
- int start = file_buffer.size();
- file_buffer.resize(file_buffer.size() + block_size);
- for (uint64_t i = 0; i < bh.compressed_size; i++) {
- file_buffer.write[start + i] = strm_in[i];
- }
- }
-
- meta.hashes.push_back(bh);
-
- step += block_size;
- }
-
- if (p_compress) {
- strm.avail_in = 0;
- strm.avail_out = strm_out.size();
- strm.next_in = (uint8_t *)strm_in.ptr();
- strm.next_out = strm_out.ptrw();
-
- int total_out_before = strm.total_out;
-
- deflate(&strm, Z_FINISH);
-
- //package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
- int start = file_buffer.size();
- file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before));
- for (uint64_t i = 0; i < (strm.total_out - total_out_before); i++) {
- file_buffer.write[start + i] = strm_out[i];
- }
-
- deflateEnd(&strm);
- meta.compressed_size = strm.total_out;
-
- } else {
- meta.compressed_size = p_len;
- }
-
- // Calculate file CRC-32
- uLong crc = crc32(0L, Z_NULL, 0);
- crc = crc32(crc, p_buffer, p_len);
- meta.file_crc32 = crc;
-
- // Create file header
- Vector<uint8_t> file_header = make_file_header(meta);
- meta.lfh_size = file_header.size();
-
- // Store the header and file;
- package->store_buffer(file_header.ptr(), file_header.size());
- package->store_buffer(file_buffer.ptr(), file_buffer.size());
-
- file_metadata.push_back(meta);
-
- return OK;
-}
-
-void AppxPackager::finish() {
- // Create and add block map file
- EditorNode::progress_task_step("export", "Creating block map...", 4);
-
- const String &tmp_blockmap_file_path = EditorPaths::get_singleton()->get_cache_dir().path_join("tmpblockmap.xml");
- make_block_map(tmp_blockmap_file_path);
-
- {
- Ref<FileAccess> blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ);
- Vector<uint8_t> blockmap_buffer;
- blockmap_buffer.resize(blockmap_file->get_length());
-
- blockmap_file->get_buffer(blockmap_buffer.ptrw(), blockmap_buffer.size());
-
- add_file("AppxBlockMap.xml", blockmap_buffer.ptr(), blockmap_buffer.size(), -1, -1, true);
- }
-
- // Add content types
-
- EditorNode::progress_task_step("export", "Setting content types...", 5);
-
- const String &tmp_content_types_file_path = EditorPaths::get_singleton()->get_cache_dir().path_join("tmpcontenttypes.xml");
- make_content_types(tmp_content_types_file_path);
-
- {
- Ref<FileAccess> types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ);
- Vector<uint8_t> types_buffer;
- types_buffer.resize(types_file->get_length());
-
- types_file->get_buffer(types_buffer.ptrw(), types_buffer.size());
-
- add_file("[Content_Types].xml", types_buffer.ptr(), types_buffer.size(), -1, -1, true);
- }
-
- // Cleanup generated files.
- DirAccess::remove_file_or_error(tmp_blockmap_file_path);
- DirAccess::remove_file_or_error(tmp_content_types_file_path);
-
- // Pre-process central directory before signing
- for (int i = 0; i < file_metadata.size(); i++) {
- store_central_dir_header(file_metadata[i]);
- }
-
- // Write central directory
- EditorNode::progress_task_step("export", "Finishing package...", 6);
- central_dir_offset = package->get_position();
- package->store_buffer(central_dir_data.ptr(), central_dir_data.size());
-
- // End record
- end_of_central_dir_offset = package->get_position();
- Vector<uint8_t> end_record = make_end_of_central_record();
- package->store_buffer(end_record.ptr(), end_record.size());
-
- package.unref();
-}
-
-AppxPackager::AppxPackager() {}
-
-AppxPackager::~AppxPackager() {}
diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h
deleted file mode 100644
index e989ba9b90..0000000000
--- a/platform/uwp/export/app_packager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/**************************************************************************/
-/* app_packager.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef UWP_APP_PACKAGER_H
-#define UWP_APP_PACKAGER_H
-
-#include "core/config/project_settings.h"
-#include "core/core_bind.h"
-#include "core/crypto/crypto_core.h"
-#include "core/io/dir_access.h"
-#include "core/io/file_access.h"
-#include "core/io/marshalls.h"
-#include "core/io/zip_io.h"
-#include "core/object/class_db.h"
-#include "core/version.h"
-#include "editor/export/editor_export_platform.h"
-
-#include "thirdparty/minizip/unzip.h"
-#include "thirdparty/minizip/zip.h"
-
-#include <zlib.h>
-
-class AppxPackager {
- enum {
- FILE_HEADER_MAGIC = 0x04034b50,
- DATA_DESCRIPTOR_MAGIC = 0x08074b50,
- CENTRAL_DIR_MAGIC = 0x02014b50,
- END_OF_CENTRAL_DIR_MAGIC = 0x06054b50,
- ZIP64_END_OF_CENTRAL_DIR_MAGIC = 0x06064b50,
- ZIP64_END_DIR_LOCATOR_MAGIC = 0x07064b50,
- P7X_SIGNATURE = 0x58434b50,
- ZIP64_HEADER_ID = 0x0001,
- ZIP_VERSION = 20,
- ZIP_ARCHIVE_VERSION = 45,
- GENERAL_PURPOSE = 0x00,
- BASE_FILE_HEADER_SIZE = 30,
- DATA_DESCRIPTOR_SIZE = 24,
- BASE_CENTRAL_DIR_SIZE = 46,
- EXTRA_FIELD_LENGTH = 28,
- ZIP64_HEADER_SIZE = 24,
- ZIP64_END_OF_CENTRAL_DIR_SIZE = (56 - 12),
- END_OF_CENTRAL_DIR_SIZE = 42,
- BLOCK_SIZE = 65536,
- };
-
- struct BlockHash {
- String base64_hash;
- size_t compressed_size = 0;
- };
-
- struct FileMeta {
- String name;
- int lfh_size = 0;
- bool compressed = false;
- size_t compressed_size = 0;
- size_t uncompressed_size = 0;
- Vector<BlockHash> hashes;
- uLong file_crc32 = 0;
- ZPOS64_T zip_offset = 0;
- };
-
- String progress_task;
- Ref<FileAccess> package;
-
- HashSet<String> mime_types;
-
- Vector<FileMeta> file_metadata;
-
- ZPOS64_T central_dir_offset = 0;
- ZPOS64_T end_of_central_dir_offset = 0;
- Vector<uint8_t> central_dir_data;
-
- String hash_block(const uint8_t *p_block_data, size_t p_block_len);
-
- void make_block_map(const String &p_path);
- void make_content_types(const String &p_path);
-
- _FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) {
- for (int i = 0; i < 2; i++) {
- *p_buf++ = (p_val >> (i * 8)) & 0xFF;
- }
- return 2;
- }
-
- _FORCE_INLINE_ unsigned int buf_put_int32(uint32_t p_val, uint8_t *p_buf) {
- for (int i = 0; i < 4; i++) {
- *p_buf++ = (p_val >> (i * 8)) & 0xFF;
- }
- return 4;
- }
-
- _FORCE_INLINE_ unsigned int buf_put_int64(uint64_t p_val, uint8_t *p_buf) {
- for (int i = 0; i < 8; i++) {
- *p_buf++ = (p_val >> (i * 8)) & 0xFF;
- }
- return 8;
- }
-
- _FORCE_INLINE_ unsigned int buf_put_string(String p_val, uint8_t *p_buf) {
- for (int i = 0; i < p_val.length(); i++) {
- *p_buf++ = p_val.utf8().get(i);
- }
- return p_val.length();
- }
-
- Vector<uint8_t> make_file_header(FileMeta p_file_meta);
- void store_central_dir_header(const FileMeta &p_file, bool p_do_hash = true);
- Vector<uint8_t> make_end_of_central_record();
-
- String content_type(String p_extension);
-
-public:
- void set_progress_task(String p_task) { progress_task = p_task; }
- void init(Ref<FileAccess> p_fa);
- Error add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress = false);
- void finish();
-
- AppxPackager();
- ~AppxPackager();
-};
-
-#endif // UWP_APP_PACKAGER_H
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
deleted file mode 100644
index 3e229c7419..0000000000
--- a/platform/uwp/export/export.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/**************************************************************************/
-/* export.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "export.h"
-
-#include "export_plugin.h"
-
-#include "editor/editor_settings.h"
-#include "editor/export/editor_export.h"
-
-void register_uwp_exporter_types() {
- // GDREGISTER_VIRTUAL_CLASS(EditorExportPlatformUWP);
-}
-
-void register_uwp_exporter() {
-#ifdef WINDOWS_ENABLED
- EDITOR_DEF("export/uwp/signtool", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/signtool", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
- EDITOR_DEF("export/uwp/debug_certificate", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/debug_certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx"));
- EDITOR_DEF("export/uwp/debug_password", "");
- EDITOR_DEF("export/uwp/debug_algorithm", 2); // SHA256 is the default
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "export/uwp/debug_algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256"));
-#endif // WINDOWS_ENABLED
-
- Ref<EditorExportPlatformUWP> exporter;
- exporter.instantiate();
- EditorExport::get_singleton()->add_export_platform(exporter);
-}
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
deleted file mode 100644
index c92520b755..0000000000
--- a/platform/uwp/export/export_plugin.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/**************************************************************************/
-/* export_plugin.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "export_plugin.h"
-
-#include "logo_svg.gen.h"
-
-#include "editor/editor_scale.h"
-#include "editor/editor_settings.h"
-#include "scene/resources/image_texture.h"
-
-#include "modules/modules_enabled.gen.h" // For svg and regex.
-#ifdef MODULE_SVG_ENABLED
-#include "modules/svg/image_loader_svg.h"
-#endif
-
-String EditorExportPlatformUWP::get_name() const {
- return "UWP";
-}
-String EditorExportPlatformUWP::get_os_name() const {
- return "UWP";
-}
-
-List<String> EditorExportPlatformUWP::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
- List<String> list;
- list.push_back("appx");
- return list;
-}
-
-Ref<Texture2D> EditorExportPlatformUWP::get_logo() const {
- return logo;
-}
-
-void EditorExportPlatformUWP::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
- r_features->push_back("s3tc");
- r_features->push_back("etc");
- r_features->push_back(p_preset->get("binary_format/architecture"));
-}
-
-void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options) const {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm32"), "x86_64"));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/display_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/short_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game.Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/description"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/publisher", PROPERTY_HINT_PLACEHOLDER_TEXT, "CN=CompanyName"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/publisher_display_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/product_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/publisher_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "signing/algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256"), 2));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/major"), 1));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/minor"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/build"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/revision"), 0));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_flipped"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_flipped"), true));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "images/background_color"), "transparent"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/store_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square44x44_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square71x71_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square150x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square310x310_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/wide310x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/splash_screen", PROPERTY_HINT_RESOURCE_TYPE, "CompressedTexture2D"), Variant()));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square150x150"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square310x310"), false));
-
- // Capabilities
- const char **basic = uwp_capabilities;
- while (*basic) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*basic)), false));
- basic++;
- }
-
- const char **uap = uwp_uap_capabilities;
- while (*uap) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*uap)), false));
- uap++;
- }
-
- const char **device = uwp_device_capabilities;
- while (*device) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*device)), false));
- device++;
- }
-}
-
-bool EditorExportPlatformUWP::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
-#ifndef DEV_ENABLED
- // We don't provide export templates for the UWP platform currently as it
- // has not been ported for Godot 4. This is skipped in DEV_ENABLED so that
- // contributors can still test the pipeline if/when we can build it again.
- r_error = "The UWP platform is currently not supported in Godot 4.\n";
- return false;
-#else
-
- String err;
- bool valid = false;
-
- // Look for export templates (first official, and if defined custom templates).
- String arch = p_preset->get("binary_format/architecture");
- String arch_infix;
- if (arch == "arm32") {
- arch_infix = "arm";
- } else if (arch == "x86_32") {
- arch_infix = "x86";
- } else if (arch == "x86_64") {
- arch_infix = "x64";
- }
-
- bool dvalid = exists_export_template("uwp_" + arch_infix + "_debug.zip", &err);
- bool rvalid = exists_export_template("uwp_" + arch_infix + "_release.zip", &err);
-
- if (p_preset->get("custom_template/debug") != "") {
- dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
- if (!dvalid) {
- err += TTR("Custom debug template not found.") + "\n";
- }
- }
- if (p_preset->get("custom_template/release") != "") {
- rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
- if (!rvalid) {
- err += TTR("Custom release template not found.") + "\n";
- }
- }
-
- valid = dvalid || rvalid;
- r_missing_templates = !valid;
-
- if (!err.is_empty()) {
- r_error = err;
- }
-
- return valid;
-#endif // DEV_ENABLED
-}
-
-bool EditorExportPlatformUWP::has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const {
-#ifndef DEV_ENABLED
- // We don't provide export templates for the UWP platform currently as it
- // has not been ported for Godot 4. This is skipped in DEV_ENABLED so that
- // contributors can still test the pipeline if/when we can build it again.
- r_error = "The UWP platform is currently not supported in Godot 4.\n";
- return false;
-#else
-
- String err;
- bool valid = true;
-
- // Validate the project configuration.
-
- if (!_valid_resource_name(p_preset->get("package/short_name"))) {
- valid = false;
- err += TTR("Invalid package short name.") + "\n";
- }
-
- if (!_valid_resource_name(p_preset->get("package/unique_name"))) {
- valid = false;
- err += TTR("Invalid package unique name.") + "\n";
- }
-
- if (!_valid_resource_name(p_preset->get("package/publisher_display_name"))) {
- valid = false;
- err += TTR("Invalid package publisher display name.") + "\n";
- }
-
- if (!_valid_guid(p_preset->get("identity/product_guid"))) {
- valid = false;
- err += TTR("Invalid product GUID.") + "\n";
- }
-
- if (!_valid_guid(p_preset->get("identity/publisher_guid"))) {
- valid = false;
- err += TTR("Invalid publisher GUID.") + "\n";
- }
-
- if (!_valid_bgcolor(p_preset->get("images/background_color"))) {
- valid = false;
- err += TTR("Invalid background color.") + "\n";
- }
-
- if (!p_preset->get("images/store_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/store_logo"))), 50, 50)) {
- valid = false;
- err += TTR("Invalid Store Logo image dimensions (should be 50x50).") + "\n";
- }
-
- if (!p_preset->get("images/square44x44_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/square44x44_logo"))), 44, 44)) {
- valid = false;
- err += TTR("Invalid square 44x44 logo image dimensions (should be 44x44).") + "\n";
- }
-
- if (!p_preset->get("images/square71x71_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/square71x71_logo"))), 71, 71)) {
- valid = false;
- err += TTR("Invalid square 71x71 logo image dimensions (should be 71x71).") + "\n";
- }
-
- if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/square150x150_logo"))), 150, 150)) {
- valid = false;
- err += TTR("Invalid square 150x150 logo image dimensions (should be 150x150).") + "\n";
- }
-
- if (!p_preset->get("images/square310x310_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/square310x310_logo"))), 310, 310)) {
- valid = false;
- err += TTR("Invalid square 310x310 logo image dimensions (should be 310x310).") + "\n";
- }
-
- if (!p_preset->get("images/wide310x150_logo").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/wide310x150_logo"))), 310, 150)) {
- valid = false;
- err += TTR("Invalid wide 310x150 logo image dimensions (should be 310x150).") + "\n";
- }
-
- if (!p_preset->get("images/splash_screen").is_zero() && !_valid_image((Object::cast_to<CompressedTexture2D>((Object *)p_preset->get("images/splash_screen"))), 620, 300)) {
- valid = false;
- err += TTR("Invalid splash screen image dimensions (should be 620x300).") + "\n";
- }
-
- r_error = err;
- return valid;
-#endif // DEV_ENABLED
-}
-
-Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
- ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
-
- String src_appx;
-
- EditorProgress ep("export", TTR("Exporting for UWP"), 7, true);
-
- if (p_debug) {
- src_appx = p_preset->get("custom_template/debug");
- } else {
- src_appx = p_preset->get("custom_template/release");
- }
-
- src_appx = src_appx.strip_edges();
-
- String arch = p_preset->get("binary_format/architecture");
-
- if (src_appx.is_empty()) {
- String err, arch_infix;
- if (arch == "arm32") {
- arch_infix = "arm";
- } else if (arch == "x86_32") {
- arch_infix = "x86";
- } else if (arch == "x86_64") {
- arch_infix = "x64";
- }
- if (p_debug) {
- src_appx = find_export_template("uwp_" + arch_infix + "_debug.zip", &err);
- } else {
- src_appx = find_export_template("uwp_" + arch_infix + "_release.zip", &err);
- }
- if (src_appx.is_empty()) {
- EditorNode::add_io_error(err);
- return ERR_FILE_NOT_FOUND;
- }
- }
-
- if (!DirAccess::exists(p_path.get_base_dir())) {
- return ERR_FILE_BAD_PATH;
- }
-
- Error err = OK;
-
- Ref<FileAccess> fa_pack = FileAccess::open(p_path, FileAccess::WRITE, &err);
- ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_CREATE, "Cannot create file '" + p_path + "'.");
-
- AppxPackager packager;
- packager.init(fa_pack);
-
- Ref<FileAccess> io_fa;
- zlib_filefunc_def io = zipio_create_io(&io_fa);
-
- if (ep.step("Creating package...", 0)) {
- return ERR_SKIP;
- }
-
- unzFile pkg = unzOpen2(src_appx.utf8().get_data(), &io);
-
- if (!pkg) {
- EditorNode::add_io_error("Could not find template appx to export:\n" + src_appx);
- return ERR_FILE_NOT_FOUND;
- }
-
- int ret = unzGoToFirstFile(pkg);
-
- if (ep.step("Copying template files...", 1)) {
- return ERR_SKIP;
- }
-
- EditorNode::progress_add_task("template_files", "Template files", 100);
- packager.set_progress_task("template_files");
-
- int template_files_amount = 9;
- int template_file_no = 1;
-
- while (ret == UNZ_OK) {
- // get file name
- unz_file_info info;
- char fname[16834];
- ret = unzGetCurrentFileInfo(pkg, &info, fname, 16834, nullptr, 0, nullptr, 0);
- if (ret != UNZ_OK) {
- break;
- }
-
- String path = String::utf8(fname);
-
- if (path.ends_with("/")) {
- // Ignore directories
- ret = unzGoToNextFile(pkg);
- continue;
- }
-
- Vector<uint8_t> data;
- bool do_read = true;
-
- if (path.begins_with("Assets/")) {
- path = path.replace(".scale-100", "");
-
- data = _get_image_data(p_preset, path);
- if (data.size() > 0) {
- do_read = false;
- }
- }
-
- //read
- if (do_read) {
- data.resize(info.uncompressed_size);
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptrw(), data.size());
- unzCloseCurrentFile(pkg);
- }
-
- if (path == "AppxManifest.xml") {
- data = _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG));
- }
-
- print_line("ADDING: " + path);
-
- err = packager.add_file(path, data.ptr(), data.size(), template_file_no++, template_files_amount, _should_compress_asset(path, data));
- if (err != OK) {
- return err;
- }
-
- ret = unzGoToNextFile(pkg);
- }
-
- EditorNode::progress_end_task("template_files");
-
- if (ep.step("Creating command line...", 2)) {
- return ERR_SKIP;
- }
-
- Vector<String> cl = ((String)p_preset->get("command_line/extra_args")).strip_edges().split(" ");
- for (int i = 0; i < cl.size(); i++) {
- if (cl[i].strip_edges().length() == 0) {
- cl.remove_at(i);
- i--;
- }
- }
-
- if (!(p_flags & DEBUG_FLAG_DUMB_CLIENT)) {
- cl.push_back("--path");
- cl.push_back("game");
- }
-
- gen_export_flags(cl, p_flags);
-
- // Command line file
- Vector<uint8_t> clf;
-
- // Argc
- clf.resize(4);
- encode_uint32(cl.size(), clf.ptrw());
-
- for (int i = 0; i < cl.size(); i++) {
- CharString txt = cl[i].utf8();
- int base = clf.size();
- clf.resize(base + 4 + txt.length());
- encode_uint32(txt.length(), &clf.write[base]);
- memcpy(&clf.write[base + 4], txt.ptr(), txt.length());
- print_line(itos(i) + " param: " + cl[i]);
- }
-
- err = packager.add_file("__cl__.cl", clf.ptr(), clf.size(), -1, -1, false);
- if (err != OK) {
- return err;
- }
-
- if (ep.step("Adding project files...", 3)) {
- return ERR_SKIP;
- }
-
- EditorNode::progress_add_task("project_files", "Project Files", 100);
- packager.set_progress_task("project_files");
-
- err = export_project_files(p_preset, p_debug, save_appx_file, &packager);
-
- EditorNode::progress_end_task("project_files");
-
- if (ep.step("Closing package...", 7)) {
- return ERR_SKIP;
- }
-
- unzClose(pkg);
-
- packager.finish();
-
-#ifdef WINDOWS_ENABLED
- // Sign with signtool
- String signtool_path = EDITOR_GET("export/uwp/signtool");
- if (signtool_path.is_empty()) {
- return OK;
- }
-
- if (!FileAccess::exists(signtool_path)) {
- ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
- }
-
- static String algs[] = { "MD5", "SHA1", "SHA256" };
-
- String cert_path = EDITOR_GET("export/uwp/debug_certificate");
- String cert_pass = EDITOR_GET("export/uwp/debug_password");
- int cert_alg = EDITOR_GET("export/uwp/debug_algorithm");
-
- if (!p_debug) {
- cert_path = p_preset->get_or_env("signing/certificate", ENV_UWP_SIGNING_CERT);
- cert_pass = p_preset->get_or_env("signing/password", ENV_UWP_SIGNING_PASS);
- cert_alg = p_preset->get("signing/algorithm");
- }
-
- if (cert_path.is_empty()) {
- return OK; // Certificate missing, don't try to sign
- }
-
- if (!FileAccess::exists(cert_path)) {
- ERR_PRINT("Could not find certificate file at " + cert_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
- }
-
- if (cert_alg < 0 || cert_alg > 2) {
- ERR_PRINT("Invalid certificate algorithm " + itos(cert_alg) + ", aborting.");
- return ERR_INVALID_DATA;
- }
-
- List<String> args;
- args.push_back("sign");
- args.push_back("/fd");
- args.push_back(algs[cert_alg]);
- args.push_back("/a");
- args.push_back("/f");
- args.push_back(cert_path);
- args.push_back("/p");
- args.push_back(cert_pass);
- args.push_back(p_path);
-
- OS::get_singleton()->execute(signtool_path, args);
-#endif // WINDOWS_ENABLED
-
- return OK;
-}
-
-void EditorExportPlatformUWP::get_platform_features(List<String> *r_features) const {
- r_features->push_back("pc");
- r_features->push_back("uwp");
-}
-
-void EditorExportPlatformUWP::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) {
-}
-
-EditorExportPlatformUWP::EditorExportPlatformUWP() {
-#ifdef MODULE_SVG_ENABLED
- Ref<Image> img = memnew(Image);
- const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE);
-
- ImageLoaderSVG::create_image_from_string(img, _uwp_logo_svg, EDSCALE, upsample, false);
-
- logo = ImageTexture::create_from_image(img);
-#endif
-}
diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h
deleted file mode 100644
index 147279e5c5..0000000000
--- a/platform/uwp/export/export_plugin.h
+++ /dev/null
@@ -1,450 +0,0 @@
-/**************************************************************************/
-/* export_plugin.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef UWP_EXPORT_PLUGIN_H
-#define UWP_EXPORT_PLUGIN_H
-
-#include "app_packager.h"
-
-#include "core/config/project_settings.h"
-#include "core/crypto/crypto_core.h"
-#include "core/io/dir_access.h"
-#include "core/io/file_access.h"
-#include "core/io/marshalls.h"
-#include "core/io/zip_io.h"
-#include "core/object/class_db.h"
-#include "core/version.h"
-#include "editor/editor_node.h"
-#include "editor/editor_paths.h"
-#include "editor/export/editor_export_platform.h"
-#include "scene/resources/compressed_texture.h"
-
-#include "thirdparty/minizip/unzip.h"
-#include "thirdparty/minizip/zip.h"
-
-#include <zlib.h>
-
-// Capabilities
-static const char *uwp_capabilities[] = {
- "allJoyn",
- "codeGeneration",
- "internetClient",
- "internetClientServer",
- "privateNetworkClientServer",
- nullptr
-};
-static const char *uwp_uap_capabilities[] = {
- "appointments",
- "blockedChatMessages",
- "chat",
- "contacts",
- "enterpriseAuthentication",
- "musicLibrary",
- "objects3D",
- "picturesLibrary",
- "phoneCall",
- "removableStorage",
- "sharedUserCertificates",
- "userAccountInformation",
- "videosLibrary",
- "voipCall",
- nullptr
-};
-static const char *uwp_device_capabilities[] = {
- "bluetooth",
- "location",
- "microphone",
- "proximity",
- "webcam",
- nullptr
-};
-
-// Optional environment variables for defining confidential information. If any
-// of these is set, they will override the values set in the credentials file.
-const String ENV_UWP_SIGNING_CERT = "GODOT_UWP_SIGNING_CERTIFICATE";
-const String ENV_UWP_SIGNING_PASS = "GODOT_UWP_SIGNING_PASSWORD";
-
-class EditorExportPlatformUWP : public EditorExportPlatform {
- GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);
-
- Ref<ImageTexture> logo;
-
- bool _valid_resource_name(const String &p_name) const {
- if (p_name.is_empty()) {
- return false;
- }
- if (p_name.ends_with(".")) {
- return false;
- }
-
- static const char *invalid_names[] = {
- "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
- "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
- nullptr
- };
-
- const char **t = invalid_names;
- while (*t) {
- if (p_name == *t) {
- return false;
- }
- t++;
- }
-
- return true;
- }
-
- bool _valid_guid(const String &p_guid) const {
- Vector<String> parts = p_guid.split("-");
-
- if (parts.size() != 5) {
- return false;
- }
- if (parts[0].length() != 8) {
- return false;
- }
- for (int i = 1; i < 4; i++) {
- if (parts[i].length() != 4) {
- return false;
- }
- }
- if (parts[4].length() != 12) {
- return false;
- }
-
- return true;
- }
-
- bool _valid_bgcolor(const String &p_color) const {
- if (p_color.is_empty()) {
- return true;
- }
- if (p_color.begins_with("#") && p_color.is_valid_html_color()) {
- return true;
- }
-
- // Colors from https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
- static const char *valid_colors[] = {
- "aliceBlue", "antiqueWhite", "aqua", "aquamarine", "azure", "beige",
- "bisque", "black", "blanchedAlmond", "blue", "blueViolet", "brown",
- "burlyWood", "cadetBlue", "chartreuse", "chocolate", "coral", "cornflowerBlue",
- "cornsilk", "crimson", "cyan", "darkBlue", "darkCyan", "darkGoldenrod",
- "darkGray", "darkGreen", "darkKhaki", "darkMagenta", "darkOliveGreen", "darkOrange",
- "darkOrchid", "darkRed", "darkSalmon", "darkSeaGreen", "darkSlateBlue", "darkSlateGray",
- "darkTurquoise", "darkViolet", "deepPink", "deepSkyBlue", "dimGray", "dodgerBlue",
- "firebrick", "floralWhite", "forestGreen", "fuchsia", "gainsboro", "ghostWhite",
- "gold", "goldenrod", "gray", "green", "greenYellow", "honeydew",
- "hotPink", "indianRed", "indigo", "ivory", "khaki", "lavender",
- "lavenderBlush", "lawnGreen", "lemonChiffon", "lightBlue", "lightCoral", "lightCyan",
- "lightGoldenrodYellow", "lightGreen", "lightGray", "lightPink", "lightSalmon", "lightSeaGreen",
- "lightSkyBlue", "lightSlateGray", "lightSteelBlue", "lightYellow", "lime", "limeGreen",
- "linen", "magenta", "maroon", "mediumAquamarine", "mediumBlue", "mediumOrchid",
- "mediumPurple", "mediumSeaGreen", "mediumSlateBlue", "mediumSpringGreen", "mediumTurquoise", "mediumVioletRed",
- "midnightBlue", "mintCream", "mistyRose", "moccasin", "navajoWhite", "navy",
- "oldLace", "olive", "oliveDrab", "orange", "orangeRed", "orchid",
- "paleGoldenrod", "paleGreen", "paleTurquoise", "paleVioletRed", "papayaWhip", "peachPuff",
- "peru", "pink", "plum", "powderBlue", "purple", "red",
- "rosyBrown", "royalBlue", "saddleBrown", "salmon", "sandyBrown", "seaGreen",
- "seaShell", "sienna", "silver", "skyBlue", "slateBlue", "slateGray",
- "snow", "springGreen", "steelBlue", "tan", "teal", "thistle",
- "tomato", "transparent", "turquoise", "violet", "wheat", "white",
- "whiteSmoke", "yellow", "yellowGreen",
- nullptr
- };
-
- const char **color = valid_colors;
-
- while (*color) {
- if (p_color == *color) {
- return true;
- }
- color++;
- }
-
- return false;
- }
-
- bool _valid_image(const CompressedTexture2D *p_image, int p_width, int p_height) const {
- if (!p_image) {
- return false;
- }
-
- // TODO: Add resource creation or image rescaling to enable other scales:
- // 1.25, 1.5, 2.0
- return p_width == p_image->get_width() && p_height == p_image->get_height();
- }
-
- Vector<uint8_t> _fix_manifest(const Ref<EditorExportPreset> &p_preset, const Vector<uint8_t> &p_template, bool p_give_internet) const {
- String result = String::utf8((const char *)p_template.ptr(), p_template.size());
-
- result = result.replace("$godot_version$", VERSION_FULL_NAME);
-
- result = result.replace("$identity_name$", p_preset->get("package/unique_name"));
- result = result.replace("$publisher$", p_preset->get("package/publisher"));
-
- result = result.replace("$product_guid$", p_preset->get("identity/product_guid"));
- result = result.replace("$publisher_guid$", p_preset->get("identity/publisher_guid"));
-
- String version = itos(p_preset->get("version/major")) + "." + itos(p_preset->get("version/minor")) + "." + itos(p_preset->get("version/build")) + "." + itos(p_preset->get("version/revision"));
- result = result.replace("$version_string$", version);
-
- String arch = p_preset->get("binary_format/architecture");
- String architecture = arch == "arm32" ? "arm" : (arch == "x86_32" ? "x86" : "x64");
- result = result.replace("$architecture$", architecture);
-
- result = result.replace("$display_name$", String(p_preset->get("package/display_name")).is_empty() ? (String)GLOBAL_GET("application/config/name") : String(p_preset->get("package/display_name")));
-
- result = result.replace("$publisher_display_name$", p_preset->get("package/publisher_display_name"));
- result = result.replace("$app_description$", p_preset->get("package/description"));
- result = result.replace("$bg_color$", p_preset->get("images/background_color"));
- result = result.replace("$short_name$", p_preset->get("package/short_name"));
-
- String name_on_tiles = "";
- if ((bool)p_preset->get("tiles/show_name_on_square150x150")) {
- name_on_tiles += " <uap:ShowOn Tile=\"square150x150Logo\" />\n";
- }
- if ((bool)p_preset->get("tiles/show_name_on_wide310x150")) {
- name_on_tiles += " <uap:ShowOn Tile=\"wide310x150Logo\" />\n";
- }
- if ((bool)p_preset->get("tiles/show_name_on_square310x310")) {
- name_on_tiles += " <uap:ShowOn Tile=\"square310x310Logo\" />\n";
- }
-
- String show_name_on_tiles = "";
- if (!name_on_tiles.is_empty()) {
- show_name_on_tiles = "<uap:ShowNameOnTiles>\n" + name_on_tiles + " </uap:ShowNameOnTiles>";
- }
-
- result = result.replace("$name_on_tiles$", name_on_tiles);
-
- String rotations = "";
- if ((bool)p_preset->get("orientation/landscape")) {
- rotations += " <uap:Rotation Preference=\"landscape\" />\n";
- }
- if ((bool)p_preset->get("orientation/portrait")) {
- rotations += " <uap:Rotation Preference=\"portrait\" />\n";
- }
- if ((bool)p_preset->get("orientation/landscape_flipped")) {
- rotations += " <uap:Rotation Preference=\"landscapeFlipped\" />\n";
- }
- if ((bool)p_preset->get("orientation/portrait_flipped")) {
- rotations += " <uap:Rotation Preference=\"portraitFlipped\" />\n";
- }
-
- String rotation_preference = "";
- if (!rotations.is_empty()) {
- rotation_preference = "<uap:InitialRotationPreference>\n" + rotations + " </uap:InitialRotationPreference>";
- }
-
- result = result.replace("$rotation_preference$", rotation_preference);
-
- String capabilities_elements = "";
- const char **basic = uwp_capabilities;
- while (*basic) {
- if ((bool)p_preset->get("capabilities/" + String(*basic))) {
- capabilities_elements += " <Capability Name=\"" + String(*basic) + "\" />\n";
- }
- basic++;
- }
- const char **uap = uwp_uap_capabilities;
- while (*uap) {
- if ((bool)p_preset->get("capabilities/" + String(*uap))) {
- capabilities_elements += " <uap:Capability Name=\"" + String(*uap) + "\" />\n";
- }
- uap++;
- }
- const char **device = uwp_device_capabilities;
- while (*device) {
- if ((bool)p_preset->get("capabilities/" + String(*device))) {
- capabilities_elements += " <DeviceCapability Name=\"" + String(*device) + "\" />\n";
- }
- device++;
- }
-
- if (!((bool)p_preset->get("capabilities/internetClient")) && p_give_internet) {
- capabilities_elements += " <Capability Name=\"internetClient\" />\n";
- }
-
- String capabilities_string = "<Capabilities />";
- if (!capabilities_elements.is_empty()) {
- capabilities_string = "<Capabilities>\n" + capabilities_elements + " </Capabilities>";
- }
-
- result = result.replace("$capabilities_place$", capabilities_string);
-
- Vector<uint8_t> r_ret;
- r_ret.resize(result.length());
-
- for (int i = 0; i < result.length(); i++) {
- r_ret.write[i] = result.utf8().get(i);
- }
-
- return r_ret;
- }
-
- Vector<uint8_t> _get_image_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
- Vector<uint8_t> data;
- CompressedTexture2D *texture = nullptr;
-
- if (p_path.find("StoreLogo") != -1) {
- texture = p_preset->get("images/store_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/store_logo")));
- } else if (p_path.find("Square44x44Logo") != -1) {
- texture = p_preset->get("images/square44x44_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/square44x44_logo")));
- } else if (p_path.find("Square71x71Logo") != -1) {
- texture = p_preset->get("images/square71x71_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/square71x71_logo")));
- } else if (p_path.find("Square150x150Logo") != -1) {
- texture = p_preset->get("images/square150x150_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/square150x150_logo")));
- } else if (p_path.find("Square310x310Logo") != -1) {
- texture = p_preset->get("images/square310x310_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/square310x310_logo")));
- } else if (p_path.find("Wide310x150Logo") != -1) {
- texture = p_preset->get("images/wide310x150_logo").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/wide310x150_logo")));
- } else if (p_path.find("SplashScreen") != -1) {
- texture = p_preset->get("images/splash_screen").is_zero() ? nullptr : Object::cast_to<CompressedTexture2D>(((Object *)p_preset->get("images/splash_screen")));
- } else {
- ERR_PRINT("Unable to load logo");
- }
-
- if (!texture) {
- return data;
- }
-
- String tmp_path = EditorPaths::get_singleton()->get_cache_dir().path_join("uwp_tmp_logo.png");
-
- Error err = texture->get_image()->save_png(tmp_path);
-
- if (err != OK) {
- String err_string = "Couldn't save temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_FAIL_V_MSG(data, err_string);
- }
-
- {
- Ref<FileAccess> f = FileAccess::open(tmp_path, FileAccess::READ, &err);
-
- if (err != OK) {
- String err_string = "Couldn't open temp logo file.";
- // Cleanup generated file.
- DirAccess::remove_file_or_error(tmp_path);
- EditorNode::add_io_error(err_string);
- ERR_FAIL_V_MSG(data, err_string);
- }
-
- data.resize(f->get_length());
- f->get_buffer(data.ptrw(), data.size());
- }
-
- DirAccess::remove_file_or_error(tmp_path);
-
- return data;
- }
-
- static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
- /* TODO: This was copied verbatim from Android export. It should be
- * refactored to the parent class and also be used for .zip export.
- */
-
- /*
- * By not compressing files with little or not benefit in doing so,
- * a performance gain is expected at runtime. Moreover, if the APK is
- * zip-aligned, assets stored as they are can be efficiently read by
- * Android by memory-mapping them.
- */
-
- // -- Unconditional uncompress to mimic AAPT plus some other
-
- static const char *unconditional_compress_ext[] = {
- // From https://github.com/android/platform_frameworks_base/blob/master/tools/aapt/Package.cpp
- // These formats are already compressed, or don't compress well:
- ".jpg", ".jpeg", ".png", ".gif",
- ".wav", ".mp2", ".mp3", ".ogg", ".aac",
- ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
- ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
- ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
- ".amr", ".awb", ".wma", ".wmv",
- // Godot-specific:
- ".webp", // Same reasoning as .png
- ".cfb", // Don't let small config files slow-down startup
- ".scn", // Binary scenes are usually already compressed
- ".ctex", // Streamable textures are usually already compressed
- // Trailer for easier processing
- nullptr
- };
-
- for (const char **ext = unconditional_compress_ext; *ext; ++ext) {
- if (p_path.to_lower().ends_with(String(*ext))) {
- return false;
- }
- }
-
- // -- Compressed resource?
-
- if (p_data.size() >= 4 && p_data[0] == 'R' && p_data[1] == 'S' && p_data[2] == 'C' && p_data[3] == 'C') {
- // Already compressed
- return false;
- }
-
- // --- TODO: Decide on texture resources according to their image compression setting
-
- return true;
- }
-
- static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
- AppxPackager *packager = static_cast<AppxPackager *>(p_userdata);
- String dst_path = p_path.replace_first("res://", "game/");
-
- return packager->add_file(dst_path, p_data.ptr(), p_data.size(), p_file, p_total, _should_compress_asset(p_path, p_data));
- }
-
-public:
- virtual String get_name() const override;
- virtual String get_os_name() const override;
-
- virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override;
-
- virtual Ref<Texture2D> get_logo() const override;
-
- virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
-
- virtual void get_export_options(List<ExportOption> *r_options) const override;
-
- virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
- virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
-
- virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
-
- virtual void get_platform_features(List<String> *r_features) const override;
-
- virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override;
-
- EditorExportPlatformUWP();
-};
-
-#endif // UWP_EXPORT_PLUGIN_H
diff --git a/platform/uwp/export/logo.svg b/platform/uwp/export/logo.svg
deleted file mode 100644
index 5bcbdcfcd4..0000000000
--- a/platform/uwp/export/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="32" width="32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="translate(8.981 1.816)"><circle style="fill:#2f75bb;fill-opacity:1;stroke:none;stroke-width:.815427" cx="7.019" cy="14.184" r="13.825"/><path d="m-1.192 8.234 6.73-.927v6.503h-6.73Zm0 11.899 6.73.927v-6.422h-6.73Zm7.47 1.026 8.952 1.236v-7.757H6.278Zm0-13.951v6.602h8.952V5.973Z" fill="#00abed" style="fill:#fff;fill-opacity:1"/></g></svg>
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
deleted file mode 100644
index e6a923c0c5..0000000000
--- a/platform/uwp/joypad_uwp.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/**************************************************************************/
-/* joypad_uwp.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "joypad_uwp.h"
-
-#include "core/os/os.h"
-
-using namespace Windows::Gaming::Input;
-using namespace Windows::Foundation;
-
-void JoypadUWP::register_events() {
- Gamepad::GamepadAdded +=
- ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadAdded);
- Gamepad::GamepadRemoved +=
- ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadRemoved);
-}
-
-void JoypadUWP::process_controllers() {
- for (int i = 0; i < MAX_CONTROLLERS; i++) {
- ControllerDevice &joy = controllers[i];
-
- if (!joy.connected) {
- break;
- }
-
- switch (joy.type) {
- case ControllerType::GAMEPAD_CONTROLLER: {
- GamepadReading reading = ((Gamepad ^) joy.controller_reference)->GetCurrentReading();
-
- int button_mask = (int)GamepadButtons::Menu;
- for (int j = 0; j < 14; j++) {
- input->joy_button(joy.id, j, (int)reading.Buttons & button_mask);
- button_mask *= 2;
- }
-
- input->joy_axis(joy.id, JoyAxis::LEFT_X, axis_correct(reading.LeftThumbstickX));
- input->joy_axis(joy.id, JoyAxis::LEFT_Y, axis_correct(reading.LeftThumbstickY, true));
- input->joy_axis(joy.id, JoyAxis::RIGHT_X, axis_correct(reading.RightThumbstickX));
- input->joy_axis(joy.id, JoyAxis::RIGHT_Y, axis_correct(reading.RightThumbstickY, true));
- input->joy_axis(joy.id, JoyAxis::TRIGGER_LEFT, axis_correct(reading.LeftTrigger, false, true));
- input->joy_axis(joy.id, JoyAxis::TRIGGER_RIGHT, axis_correct(reading.RightTrigger, false, true));
-
- uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
- if (timestamp > joy.ff_timestamp) {
- Vector2 strength = input->get_joy_vibration_strength(joy.id);
- float duration = input->get_joy_vibration_duration(joy.id);
- if (strength.x == 0 && strength.y == 0) {
- joypad_vibration_stop(i, timestamp);
- } else {
- joypad_vibration_start(i, strength.x, strength.y, duration, timestamp);
- }
- } else if (joy.vibrating && joy.ff_end_timestamp != 0) {
- uint64_t current_time = OS::get_singleton()->get_ticks_usec();
- if (current_time >= joy.ff_end_timestamp) {
- joypad_vibration_stop(i, current_time);
- }
- }
-
- break;
- }
- }
- }
-}
-
-JoypadUWP::JoypadUWP() {
- for (int i = 0; i < MAX_CONTROLLERS; i++) {
- controllers[i].id = i;
- }
-}
-
-JoypadUWP::JoypadUWP(InputDefault *p_input) {
- input = p_input;
-
- JoypadUWP();
-}
-
-void JoypadUWP::OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
- short idx = -1;
-
- for (int i = 0; i < MAX_CONTROLLERS; i++) {
- if (!controllers[i].connected) {
- idx = i;
- break;
- }
- }
-
- ERR_FAIL_COND(idx == -1);
-
- controllers[idx].connected = true;
- controllers[idx].controller_reference = value;
- controllers[idx].id = idx;
- controllers[idx].type = ControllerType::GAMEPAD_CONTROLLER;
-
- input->joy_connection_changed(controllers[idx].id, true, "Xbox Controller", "__UWP_GAMEPAD__");
-}
-
-void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
- short idx = -1;
-
- for (int i = 0; i < MAX_CONTROLLERS; i++) {
- if (controllers[i].controller_reference == value) {
- idx = i;
- break;
- }
- }
-
- ERR_FAIL_COND(idx == -1);
-
- controllers[idx] = ControllerDevice();
-
- input->joy_connection_changed(idx, false, "Xbox Controller");
-}
-
-float JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
- if (p_trigger) {
- // Convert to a value between -1.0f and 1.0f.
- return 2.0f * p_val - 1.0f;
- }
- return (float)(p_negate ? -p_val : p_val);
-}
-
-void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) {
- ControllerDevice &joy = controllers[p_device];
- if (joy.connected) {
- GamepadVibration vibration;
- vibration.LeftMotor = p_strong_magnitude;
- vibration.RightMotor = p_weak_magnitude;
- ((Gamepad ^) joy.controller_reference)->Vibration = vibration;
-
- joy.ff_timestamp = p_timestamp;
- joy.ff_end_timestamp = p_duration == 0 ? 0 : p_timestamp + (uint64_t)(p_duration * 1000000.0);
- joy.vibrating = true;
- }
-}
-
-void JoypadUWP::joypad_vibration_stop(int p_device, uint64_t p_timestamp) {
- ControllerDevice &joy = controllers[p_device];
- if (joy.connected) {
- GamepadVibration vibration;
- vibration.LeftMotor = 0.0;
- vibration.RightMotor = 0.0;
- ((Gamepad ^) joy.controller_reference)->Vibration = vibration;
-
- joy.ff_timestamp = p_timestamp;
- joy.vibrating = false;
- }
-}
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
deleted file mode 100644
index e9be647dd4..0000000000
--- a/platform/uwp/joypad_uwp.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**************************************************************************/
-/* joypad_uwp.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef JOYPAD_UWP_H
-#define JOYPAD_UWP_H
-
-#include "core/input/input.h"
-
-ref class JoypadUWP sealed {
- /** clang-format breaks this, it does not understand this token. */
- /* clang-format off */
-internal:
- void register_events();
- void process_controllers();
- /* clang-format on */
-
- JoypadUWP();
- JoypadUWP(InputDefault *p_input);
-
-private:
- enum {
- MAX_CONTROLLERS = 4,
- };
-
- enum ControllerType {
- GAMEPAD_CONTROLLER,
- ARCADE_STICK_CONTROLLER,
- RACING_WHEEL_CONTROLLER,
- };
-
- struct ControllerDevice {
- Windows::Gaming::Input::IGameController ^ controller_reference;
-
- int id = -1;
- bool connected = false;
- ControllerType type = ControllerType::GAMEPAD_CONTROLLER;
- float ff_timestamp = 0;
- float ff_end_timestamp = 0;
- bool vibrating = false;
- };
-
- ControllerDevice controllers[MAX_CONTROLLERS];
-
- InputDefault *input = nullptr;
-
- void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
- void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
-
- float axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const;
- void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
- void joypad_vibration_stop(int p_device, uint64_t p_timestamp);
-};
-
-#endif // JOYPAD_UWP_H
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
deleted file mode 100644
index b9cd9d0baa..0000000000
--- a/platform/uwp/os_uwp.cpp
+++ /dev/null
@@ -1,845 +0,0 @@
-/**************************************************************************/
-/* os_uwp.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "os_uwp.h"
-
-#include "core/config/project_settings.h"
-#include "core/io/marshalls.h"
-#include "drivers/unix/ip_unix.h"
-#include "drivers/unix/net_socket_posix.h"
-#include "drivers/windows/dir_access_windows.h"
-#include "drivers/windows/file_access_windows.h"
-#include "drivers/windows/mutex_windows.h"
-#include "drivers/windows/semaphore_windows.h"
-#include "main/main.h"
-#include "platform/windows/windows_terminal_logger.h"
-#include "servers/audio_server.h"
-#include "servers/rendering/rendering_server_default.h"
-
-#include <ppltasks.h>
-#include <wrl.h>
-
-using namespace Windows::ApplicationModel::Core;
-using namespace Windows::ApplicationModel::Activation;
-using namespace Windows::UI::Core;
-using namespace Windows::UI::Input;
-using namespace Windows::UI::Popups;
-using namespace Windows::Foundation;
-using namespace Windows::Graphics::Display;
-using namespace Microsoft::WRL;
-using namespace Windows::UI::ViewManagement;
-using namespace Windows::Devices::Input;
-using namespace Windows::Devices::Sensors;
-using namespace Windows::ApplicationModel::DataTransfer;
-using namespace concurrency;
-
-static const float earth_gravity = 9.80665;
-
-int OS_UWP::get_video_driver_count() const {
- return 2;
-}
-
-Size2 OS_UWP::get_window_size() const {
- Size2 size;
- size.width = video_mode.width;
- size.height = video_mode.height;
- return size;
-}
-
-int OS_UWP::get_current_video_driver() const {
- return video_driver_index;
-}
-
-void OS_UWP::set_window_size(const Size2 p_size) {
- Windows::Foundation::Size new_size;
- new_size.Width = p_size.width;
- new_size.Height = p_size.height;
-
- ApplicationView ^ view = ApplicationView::GetForCurrentView();
-
- if (view->TryResizeView(new_size)) {
- video_mode.width = p_size.width;
- video_mode.height = p_size.height;
- }
-}
-
-void OS_UWP::set_window_fullscreen(bool p_enabled) {
- ApplicationView ^ view = ApplicationView::GetForCurrentView();
-
- video_mode.fullscreen = view->IsFullScreenMode;
-
- if (video_mode.fullscreen == p_enabled) {
- return;
- }
-
- if (p_enabled) {
- video_mode.fullscreen = view->TryEnterFullScreenMode();
- } else {
- view->ExitFullScreenMode();
- video_mode.fullscreen = false;
- }
-}
-
-bool OS_UWP::is_window_fullscreen() const {
- return ApplicationView::GetForCurrentView()->IsFullScreenMode;
-}
-
-void OS_UWP::set_keep_screen_on(bool p_enabled) {
- if (is_keep_screen_on() == p_enabled) {
- return;
- }
-
- if (p_enabled) {
- display_request->RequestActive();
- } else {
- display_request->RequestRelease();
- }
-
- OS::set_keep_screen_on(p_enabled);
-}
-
-void OS_UWP::initialize_core() {
- //RedirectIOToConsole();
-
- FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
- FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
- FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
- DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
- DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
- DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
-
- NetSocketPosix::make_default();
-
- // We need to know how often the clock is updated
- QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
- QueryPerformanceCounter((LARGE_INTEGER *)&ticks_start);
-
- IPUnix::make_default();
-
- cursor_shape = CURSOR_ARROW;
-}
-
-void OS_UWP::set_window(Windows::UI::Core::CoreWindow ^ p_window) {
- window = p_window;
-}
-
-void OS_UWP::screen_size_changed() {
- gl_context->reset();
-}
-
-Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
- main_loop = nullptr;
- outside = true;
-
- // FIXME: Hardcoded for now, add Vulkan support.
- p_video_driver = RENDERING_DRIVER_OPENGL3;
- ContextEGL_UWP::Driver opengl_api_type = ContextEGL_UWP::GLES_2_0;
-
- bool gl_initialization_error = false;
-
- gl_context = memnew(ContextEGL_UWP(window, opengl_api_type));
-
- if (gl_context->initialize() != OK) {
- memdelete(gl_context);
- gl_context = nullptr;
- gl_initialization_error = true;
- }
-
- if (opengl_api_type == ContextEGL_UWP::GLES_2_0) {
- if (RasterizerGLES3::is_viable() == OK) {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- } else {
- gl_initialization_error = true;
- }
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
- "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
- "Unable to initialize video driver");
- return ERR_UNAVAILABLE;
- }
-
- video_driver_index = p_video_driver;
- gl_context->make_current();
- gl_context->set_use_vsync(video_mode.use_vsync);
-
- VideoMode vm;
- vm.width = gl_context->get_window_width();
- vm.height = gl_context->get_window_height();
- vm.resizable = false;
-
- ApplicationView ^ view = ApplicationView::GetForCurrentView();
- vm.fullscreen = view->IsFullScreenMode;
-
- view->SetDesiredBoundsMode(ApplicationViewBoundsMode::UseVisible);
- view->PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
-
- if (p_desired.fullscreen != view->IsFullScreenMode) {
- if (p_desired.fullscreen) {
- vm.fullscreen = view->TryEnterFullScreenMode();
-
- } else {
- view->ExitFullScreenMode();
- vm.fullscreen = false;
- }
- }
-
- Windows::Foundation::Size desired;
- desired.Width = p_desired.width;
- desired.Height = p_desired.height;
-
- view->PreferredLaunchViewSize = desired;
-
- if (view->TryResizeView(desired)) {
- vm.width = view->VisibleBounds.Width;
- vm.height = view->VisibleBounds.Height;
- }
-
- set_video_mode(vm);
-
- rendering_server = memnew(RenderingServerDefault);
- // FIXME: Reimplement threaded rendering
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- rendering_server = memnew(RenderingServerWrapMT(rendering_server, false));
- }
-
- rendering_server->init();
-
- input = memnew(InputDefault);
-
- joypad = ref new JoypadUWP(input);
- joypad->register_events();
-
- AudioDriverManager::initialize(p_audio_driver);
-
- managed_object->update_clipboard();
-
- Clipboard::ContentChanged += ref new EventHandler<Platform::Object ^>(managed_object, &ManagedType::on_clipboard_changed);
-
- accelerometer = Accelerometer::GetDefault();
- if (accelerometer != nullptr) {
- // 60 FPS
- accelerometer->ReportInterval = (1.0f / 60.0f) * 1000;
- accelerometer->ReadingChanged +=
- ref new TypedEventHandler<Accelerometer ^, AccelerometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_accelerometer_reading_changed);
- }
-
- magnetometer = Magnetometer::GetDefault();
- if (magnetometer != nullptr) {
- // 60 FPS
- magnetometer->ReportInterval = (1.0f / 60.0f) * 1000;
- magnetometer->ReadingChanged +=
- ref new TypedEventHandler<Magnetometer ^, MagnetometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_magnetometer_reading_changed);
- }
-
- gyrometer = Gyrometer::GetDefault();
- if (gyrometer != nullptr) {
- // 60 FPS
- gyrometer->ReportInterval = (1.0f / 60.0f) * 1000;
- gyrometer->ReadingChanged +=
- ref new TypedEventHandler<Gyrometer ^, GyrometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_gyroscope_reading_changed);
- }
-
- _ensure_user_data_dir();
-
- if (is_keep_screen_on()) {
- display_request->RequestActive();
- }
-
- set_keep_screen_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
-
- return OK;
-}
-
-void OS_UWP::set_clipboard(const String &p_text) {
- DataPackage ^ clip = ref new DataPackage();
- clip->RequestedOperation = DataPackageOperation::Copy;
- clip->SetText(ref new Platform::String((LPCWSTR)(p_text.utf16().get_data())));
-
- Clipboard::SetContent(clip);
-}
-
-String OS_UWP::get_clipboard() const {
- if (managed_object->clipboard != nullptr) {
- return managed_object->clipboard->Data();
- } else {
- return "";
- }
-}
-
-void OS_UWP::input_event(const Ref<InputEvent> &p_event) {
- input->parse_input_event(p_event);
-}
-
-void OS_UWP::delete_main_loop() {
- if (main_loop) {
- memdelete(main_loop);
- }
- main_loop = nullptr;
-}
-
-void OS_UWP::set_main_loop(MainLoop *p_main_loop) {
- input->set_main_loop(p_main_loop);
- main_loop = p_main_loop;
-}
-
-void OS_UWP::finalize() {
- if (main_loop) {
- memdelete(main_loop);
- }
-
- main_loop = nullptr;
-
- rendering_server->finish();
- memdelete(rendering_server);
-#ifdef GLES3_ENABLED
- if (gl_context) {
- memdelete(gl_context);
- }
-#endif
-
- memdelete(input);
-
- joypad = nullptr;
-}
-
-void OS_UWP::finalize_core() {
- NetSocketPosix::cleanup();
-}
-
-void OS_UWP::alert(const String &p_alert, const String &p_title) {
- Platform::String ^ alert = ref new Platform::String((LPCWSTR)(p_alert.utf16().get_data()));
- Platform::String ^ title = ref new Platform::String((LPCWSTR)(p_title.utf16().get_data()));
-
- MessageDialog ^ msg = ref new MessageDialog(alert, title);
-
- UICommand ^ close = ref new UICommand("Close", ref new UICommandInvokedHandler(managed_object, &OS_UWP::ManagedType::alert_close));
- msg->Commands->Append(close);
- msg->DefaultCommandIndex = 0;
-
- managed_object->alert_close_handle = true;
-
- msg->ShowAsync();
-}
-
-void OS_UWP::ManagedType::alert_close(IUICommand ^ command) {
- alert_close_handle = false;
-}
-
-void OS_UWP::ManagedType::on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev) {
- update_clipboard();
-}
-
-void OS_UWP::ManagedType::update_clipboard() {
- DataPackageView ^ data = Clipboard::GetContent();
-
- if (data->Contains(StandardDataFormats::Text)) {
- create_task(data->GetTextAsync()).then([this](Platform::String ^ clipboard_content) {
- this->clipboard = clipboard_content;
- });
- }
-}
-
-void OS_UWP::ManagedType::on_accelerometer_reading_changed(Accelerometer ^ sender, AccelerometerReadingChangedEventArgs ^ args) {
- AccelerometerReading ^ reading = args->Reading;
-
- os->input->set_accelerometer(Vector3(
- reading->AccelerationX * earth_gravity,
- reading->AccelerationY * earth_gravity,
- reading->AccelerationZ * earth_gravity));
-}
-
-void OS_UWP::ManagedType::on_magnetometer_reading_changed(Magnetometer ^ sender, MagnetometerReadingChangedEventArgs ^ args) {
- MagnetometerReading ^ reading = args->Reading;
-
- os->input->set_magnetometer(Vector3(
- reading->MagneticFieldX,
- reading->MagneticFieldY,
- reading->MagneticFieldZ));
-}
-
-void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, GyrometerReadingChangedEventArgs ^ args) {
- GyrometerReading ^ reading = args->Reading;
-
- os->input->set_magnetometer(Vector3(
- reading->AngularVelocityX,
- reading->AngularVelocityY,
- reading->AngularVelocityZ));
-}
-
-void OS_UWP::set_mouse_mode(MouseMode p_mode) {
- if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) {
- CoreWindow::GetForCurrentThread()->SetPointerCapture();
- } else {
- CoreWindow::GetForCurrentThread()->ReleasePointerCapture();
- }
-
- if (p_mode == MouseMode::MOUSE_MODE_HIDDEN || p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_CONFINED_HIDDEN) {
- CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
- } else {
- CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
- }
-
- mouse_mode = p_mode;
-
- SetEvent(mouse_mode_changed);
-}
-
-OS_UWP::MouseMode OS_UWP::get_mouse_mode() const {
- return mouse_mode;
-}
-
-Point2 OS_UWP::get_mouse_position() const {
- return Point2(old_x, old_y);
-}
-
-MouseButton OS_UWP::get_mouse_button_state() const {
- return last_button_state;
-}
-
-void OS_UWP::set_window_title(const String &p_title) {
-}
-
-void OS_UWP::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
- video_mode = p_video_mode;
-}
-
-OS::VideoMode OS_UWP::get_video_mode(int p_screen) const {
- return video_mode;
-}
-
-void OS_UWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-}
-
-String OS_UWP::get_name() const {
- return "UWP";
-}
-
-String OS_UWP::get_distribution_name() const {
- return get_name();
-}
-
-String OS_UWP::get_version() const {
- winrt::hstring df_version = VersionInfo().DeviceFamilyVersion();
- return String(winrt::to_string(df_version).c_str());
-}
-
-OS::DateTime OS_UWP::get_datetime(bool p_utc) const {
- SYSTEMTIME systemtime;
- if (p_utc) {
- GetSystemTime(&systemtime);
- } else {
- GetLocalTime(&systemtime);
- }
-
- //Get DST information from Windows, but only if p_utc is false.
- TIME_ZONE_INFORMATION info;
- bool daylight = false;
- if (!p_utc && GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) {
- daylight = true;
- }
-
- DateTime dt;
- dt.year = systemtime.wYear;
- dt.month = Month(systemtime.wMonth);
- dt.day = systemtime.wDay;
- dt.weekday = Weekday(systemtime.wDayOfWeek);
- dt.hour = systemtime.wHour;
- dt.minute = systemtime.wMinute;
- dt.second = systemtime.wSecond;
- dt.dst = daylight;
- return dt;
-}
-
-OS::TimeZoneInfo OS_UWP::get_time_zone_info() const {
- TIME_ZONE_INFORMATION info;
- bool daylight = false;
- if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) {
- daylight = true;
- }
-
- TimeZoneInfo ret;
- if (daylight) {
- ret.name = info.DaylightName;
- } else {
- ret.name = info.StandardName;
- }
-
- // Bias value returned by GetTimeZoneInformation is inverted of what we expect
- // For example on GMT-3 GetTimeZoneInformation return a Bias of 180, so invert the value to get -180
- ret.bias = -info.Bias;
- return ret;
-}
-
-uint64_t OS_UWP::get_unix_time() const {
- FILETIME ft;
- SYSTEMTIME st;
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
-
- SYSTEMTIME ep;
- ep.wYear = 1970;
- ep.wMonth = 1;
- ep.wDayOfWeek = 4;
- ep.wDay = 1;
- ep.wHour = 0;
- ep.wMinute = 0;
- ep.wSecond = 0;
- ep.wMilliseconds = 0;
- FILETIME fep;
- SystemTimeToFileTime(&ep, &fep);
-
- return (*(uint64_t *)&ft - *(uint64_t *)&fep) / 10000000;
-}
-
-void OS_UWP::delay_usec(uint32_t p_usec) const {
- int msec = p_usec < 1000 ? 1 : p_usec / 1000;
-
- // no Sleep()
- WaitForSingleObjectEx(GetCurrentThread(), msec, false);
-}
-
-uint64_t OS_UWP::get_ticks_usec() const {
- uint64_t ticks;
-
- // This is the number of clock ticks since start
- QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
- // Subtract the ticks at game start to get
- // the ticks since the game started
- ticks -= ticks_start;
-
- // Divide by frequency to get the time in seconds
- // original calculation shown below is subject to overflow
- // with high ticks_per_second and a number of days since the last reboot.
- // time = ticks * 1000000L / ticks_per_second;
-
- // we can prevent this by either using 128 bit math
- // or separating into a calculation for seconds, and the fraction
- uint64_t seconds = ticks / ticks_per_second;
-
- // compiler will optimize these two into one divide
- uint64_t leftover = ticks % ticks_per_second;
-
- // remainder
- uint64_t time = (leftover * 1000000L) / ticks_per_second;
-
- // seconds
- time += seconds * 1000000L;
-
- return time;
-}
-
-void OS_UWP::process_events() {
- joypad->process_controllers();
- process_key_events();
- input->flush_buffered_events();
-}
-
-void OS_UWP::process_key_events() {
- for (int i = 0; i < key_event_pos; i++) {
- KeyEvent &kev = key_event_buffer[i];
-
- Ref<InputEventKey> key_event;
- key_event.instantiate();
- key_event->set_alt_pressed(kev.alt);
- key_event->set_shift_pressed(kev.shift);
- key_event->set_ctrl_pressed(kev.control);
- key_event->set_echo(kev.echo);
- key_event->set_keycode(kev.keycode);
- key_event->set_physical_keycode((Key)kev.physical_keycode);
- key_event->set_unicode(kev.unicode);
- key_event->set_pressed(kev.pressed);
-
- input_event(key_event);
- }
- key_event_pos = 0;
-}
-
-void OS_UWP::queue_key_event(KeyEvent &p_event) {
- // This merges Char events with the previous Key event, so
- // the unicode can be retrieved without sending duplicate events.
- if (p_event.type == KeyEvent::MessageType::CHAR_EVENT_MESSAGE && key_event_pos > 0) {
- KeyEvent &old = key_event_buffer[key_event_pos - 1];
- ERR_FAIL_COND(old.type != KeyEvent::MessageType::KEY_EVENT_MESSAGE);
-
- key_event_buffer[key_event_pos - 1].unicode = p_event.unicode;
- return;
- }
-
- ERR_FAIL_COND(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
-
- key_event_buffer[key_event_pos++] = p_event;
-}
-
-void OS_UWP::set_cursor_shape(CursorShape p_shape) {
- ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
-
- if (cursor_shape == p_shape) {
- return;
- }
-
- static const CoreCursorType uwp_cursors[CURSOR_MAX] = {
- CoreCursorType::Arrow,
- CoreCursorType::IBeam,
- CoreCursorType::Hand,
- CoreCursorType::Cross,
- CoreCursorType::Wait,
- CoreCursorType::Wait,
- CoreCursorType::Arrow,
- CoreCursorType::Arrow,
- CoreCursorType::UniversalNo,
- CoreCursorType::SizeNorthSouth,
- CoreCursorType::SizeWestEast,
- CoreCursorType::SizeNortheastSouthwest,
- CoreCursorType::SizeNorthwestSoutheast,
- CoreCursorType::SizeAll,
- CoreCursorType::SizeNorthSouth,
- CoreCursorType::SizeWestEast,
- CoreCursorType::Help
- };
-
- CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(uwp_cursors[p_shape], 0);
-
- cursor_shape = p_shape;
-}
-
-OS::CursorShape OS_UWP::get_cursor_shape() const {
- return cursor_shape;
-}
-
-void OS_UWP::set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
- // TODO
-}
-
-Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
- return FAILED;
-}
-
-Error OS_UWP::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) {
- return FAILED;
-}
-
-Error OS_UWP::kill(const ProcessID &p_pid) {
- return FAILED;
-}
-
-bool OS_UWP::is_process_running(const ProcessID &p_pid) const {
- return false;
-}
-
-Error OS_UWP::set_cwd(const String &p_cwd) {
- return FAILED;
-}
-
-String OS_UWP::get_executable_path() const {
- return "";
-}
-
-void OS_UWP::set_icon(const Ref<Image> &p_icon) {
-}
-
-bool OS_UWP::has_environment(const String &p_var) const {
- return false;
-}
-
-String OS_UWP::get_environment(const String &p_var) const {
- return "";
-}
-
-bool OS_UWP::set_environment(const String &p_var, const String &p_value) const {
- return false;
-}
-
-String OS_UWP::get_stdin_string() {
- return String();
-}
-
-void OS_UWP::move_window_to_foreground() {
-}
-
-Error OS_UWP::shell_open(String p_uri) {
- return FAILED;
-}
-
-String OS_UWP::get_locale() const {
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // this should work on phone 8.1, but it doesn't
- return "en";
-#else
- Platform::String ^ language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
- return String(language->Data()).replace("-", "_");
-#endif
-}
-
-void OS_UWP::release_rendering_thread() {
- gl_context->release_current();
-}
-
-void OS_UWP::make_rendering_thread() {
- gl_context->make_current();
-}
-
-void OS_UWP::swap_buffers() {
- gl_context->swap_buffers();
-}
-
-bool OS_UWP::has_touchscreen_ui_hint() const {
- TouchCapabilities ^ tc = ref new TouchCapabilities();
- return tc->TouchPresent != 0 || UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
-}
-
-bool OS_UWP::has_virtual_keyboard() const {
- return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
-}
-
-void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
- InputPane ^ pane = InputPane::GetForCurrentView();
- pane->TryShow();
-}
-
-void OS_UWP::hide_virtual_keyboard() {
- InputPane ^ pane = InputPane::GetForCurrentView();
- pane->TryHide();
-}
-
-static String format_error_message(DWORD id) {
- LPWSTR messageBuffer = nullptr;
- size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
-
- String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
-
- LocalFree(messageBuffer);
-
- return msg;
-}
-
-Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
- String full_path = "game/" + p_path;
- p_library_handle = (void *)LoadPackagedLibrary((LPCWSTR)(full_path.utf16().get_data()), 0);
- ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", full_path, format_error_message(GetLastError())));
-
- if (r_resolved_path != nullptr) {
- *r_resolved_path = full_path;
- }
-
- return OK;
-}
-
-Error OS_UWP::close_dynamic_library(void *p_library_handle) {
- if (!FreeLibrary((HMODULE)p_library_handle)) {
- return FAILED;
- }
- return OK;
-}
-
-Error OS_UWP::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
- p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
- if (!p_symbol_handle) {
- if (!p_optional) {
- ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
- } else {
- return ERR_CANT_RESOLVE;
- }
- }
- return OK;
-}
-
-void OS_UWP::run() {
- if (!main_loop) {
- return;
- }
-
- main_loop->init();
-
- uint64_t last_ticks = get_ticks_usec();
-
- int frames = 0;
- uint64_t frame = 0;
-
- while (true) {
- CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
- if (managed_object->alert_close_handle) {
- continue;
- }
- process_events(); // get rid of pending events
- if (Main::iteration()) {
- break;
- }
- }
-
- main_loop->finish();
-}
-
-MainLoop *OS_UWP::get_main_loop() const {
- return main_loop;
-}
-
-String OS_UWP::get_user_data_dir() const {
- Windows::Storage::StorageFolder ^ data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
-
- return String(data_folder->Path->Data()).replace("\\", "/");
-}
-
-bool OS_UWP::_check_internal_feature_support(const String &p_feature) {
- return p_feature == "pc";
-}
-
-OS_UWP::OS_UWP() {
- key_event_pos = 0;
- alt_mem = false;
- gr_mem = false;
- shift_mem = false;
- control_mem = false;
- meta_mem = false;
- minimized = false;
-
- pressrc = 0;
- old_invalid = true;
- mouse_mode = MOUSE_MODE_VISIBLE;
- gl_context = nullptr;
-
- display_request = ref new Windows::System::Display::DisplayRequest();
-
- managed_object = ref new ManagedType;
- managed_object->os = this;
-
- mouse_mode_changed = CreateEvent(nullptr, TRUE, FALSE, L"os_mouse_mode_changed");
-
- AudioDriverManager::add_driver(&audio_driver);
-
- Vector<Logger *> loggers;
- loggers.push_back(memnew(WindowsTerminalLogger));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
-OS_UWP::~OS_UWP() {
-}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
deleted file mode 100644
index 7f2195e4fd..0000000000
--- a/platform/uwp/os_uwp.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/**************************************************************************/
-/* os_uwp.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef OS_UWP_H
-#define OS_UWP_H
-
-#include "context_egl_uwp.h"
-#include "joypad_uwp.h"
-
-#include "core/input/input.h"
-#include "core/math/transform_2d.h"
-#include "core/os/os.h"
-#include "core/string/ustring.h"
-#include "drivers/xaudio2/audio_driver_xaudio2.h"
-#include "servers/audio_server.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering_server.h"
-
-#include <io.h>
-#include <stdio.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-class OS_UWP : public OS {
-public:
- struct KeyEvent {
- enum MessageType {
- KEY_EVENT_MESSAGE,
- CHAR_EVENT_MESSAGE
- };
-
- bool alt = false, shift = false, control = false;
- MessageType type = KEY_EVENT_MESSAGE;
- bool pressed = false;
- Key keycode = Key::NONE;
- unsigned int physical_keycode = 0;
- unsigned int unicode = 0;
- bool echo = false;
- CorePhysicalKeyStatus status;
- };
-
-private:
- enum {
- JOYPADS_MAX = 8,
- JOY_AXIS_COUNT = 6,
- MAX_JOY_AXIS = 32768, // I've no idea
- KEY_EVENT_BUFFER_SIZE = 512
- };
-
- FILE *stdo = nullptr;
-
- KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE];
- int key_event_pos;
-
- uint64_t ticks_start;
- uint64_t ticks_per_second;
-
- bool minimized;
- bool old_invalid;
- bool outside;
- int old_x, old_y;
- Point2i center;
- RenderingServer *rendering_server = nullptr;
- int pressrc;
-
- ContextEGL_UWP *gl_context = nullptr;
- Windows::UI::Core::CoreWindow ^ window;
-
- VideoMode video_mode;
- int video_driver_index;
-
- MainLoop *main_loop = nullptr;
-
- AudioDriverXAudio2 audio_driver;
-
- MouseMode mouse_mode;
- bool alt_mem;
- bool gr_mem;
- bool shift_mem;
- bool control_mem;
- bool meta_mem;
- MouseButton last_button_state = MouseButton::NONE;
-
- CursorShape cursor_shape;
-
- InputDefault *input = nullptr;
-
- JoypadUWP ^ joypad;
-
- Windows::System::Display::DisplayRequest ^ display_request;
-
- ref class ManagedType {
- public:
- property bool alert_close_handle;
- property Platform::String ^ clipboard;
- void alert_close(Windows::UI::Popups::IUICommand ^ command);
- void on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev);
- void update_clipboard();
- void on_accelerometer_reading_changed(Windows::Devices::Sensors::Accelerometer ^ sender, Windows::Devices::Sensors::AccelerometerReadingChangedEventArgs ^ args);
- void on_magnetometer_reading_changed(Windows::Devices::Sensors::Magnetometer ^ sender, Windows::Devices::Sensors::MagnetometerReadingChangedEventArgs ^ args);
- void on_gyroscope_reading_changed(Windows::Devices::Sensors::Gyrometer ^ sender, Windows::Devices::Sensors::GyrometerReadingChangedEventArgs ^ args);
-
- /** clang-format breaks this, it does not understand this token. */
- /* clang-format off */
- internal:
- ManagedType() { alert_close_handle = false; }
- property OS_UWP* os;
- /* clang-format on */
- };
- ManagedType ^ managed_object;
- Windows::Devices::Sensors::Accelerometer ^ accelerometer;
- Windows::Devices::Sensors::Magnetometer ^ magnetometer;
- Windows::Devices::Sensors::Gyrometer ^ gyrometer;
-
- // functions used by main to initialize/deinitialize the OS
-protected:
- virtual int get_video_driver_count() const;
- virtual int get_current_video_driver() const;
-
- virtual void initialize_core();
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
-
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
-
- virtual void finalize();
- virtual void finalize_core();
-
- void process_events();
-
- void process_key_events();
-
-public:
- // Event to send to the app wrapper
- HANDLE mouse_mode_changed;
-
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- String get_stdin_string();
-
- void set_mouse_mode(MouseMode p_mode);
- MouseMode get_mouse_mode() const;
-
- virtual Point2 get_mouse_position() const;
- virtual MouseButton get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
- virtual Size2 get_window_size() const;
- virtual void set_window_size(const Size2 p_size);
- virtual void set_window_fullscreen(bool p_enabled);
- virtual bool is_window_fullscreen() const;
- virtual void set_keep_screen_on(bool p_enabled);
-
- virtual MainLoop *get_main_loop() const;
-
- virtual String get_name() const;
- virtual String get_distribution_name() const;
- virtual String get_version() const;
-
- virtual DateTime get_datetime(bool p_utc) const;
- virtual TimeZoneInfo get_time_zone_info() const;
- virtual uint64_t get_unix_time() const;
-
- virtual Error set_cwd(const String &p_cwd);
-
- virtual void delay_usec(uint32_t p_usec) const;
- virtual uint64_t get_ticks_usec() const;
-
- virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false);
- virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false);
- virtual Error kill(const ProcessID &p_pid);
- virtual bool is_process_running(const ProcessID &p_pid) const;
-
- virtual bool has_environment(const String &p_var) const;
- virtual String get_environment(const String &p_var) const;
- virtual bool set_environment(const String &p_var, const String &p_value) const;
-
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
-
- void set_cursor_shape(CursorShape p_shape);
- CursorShape get_cursor_shape() const;
- virtual void set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
- void set_icon(const Ref<Image> &p_icon);
-
- virtual String get_executable_path() const;
-
- virtual String get_locale() const;
-
- virtual void move_window_to_foreground();
- virtual String get_user_data_dir() const;
-
- virtual bool _check_internal_feature_support(const String &p_feature);
-
- void set_window(Windows::UI::Core::CoreWindow ^ p_window);
- void screen_size_changed();
-
- virtual void release_rendering_thread();
- virtual void make_rendering_thread();
- virtual void swap_buffers();
-
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
- virtual void hide_virtual_keyboard();
-
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr);
- virtual Error close_dynamic_library(void *p_library_handle);
- virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
-
- virtual Error shell_open(String p_uri);
-
- void run();
-
- virtual bool get_swap_cancel_ok() { return true; }
-
- void input_event(const Ref<InputEvent> &p_event);
-
- void queue_key_event(KeyEvent &p_event);
-
- OS_UWP();
- ~OS_UWP();
-};
-
-#endif // OS_UWP_H
diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h
deleted file mode 100644
index 964e341ce4..0000000000
--- a/platform/uwp/platform_config.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/**************************************************************************/
-/* platform_config.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include <malloc.h>
diff --git a/platform/web/detect.py b/platform/web/detect.py
index 4015c8ff16..7b2e5646d6 100644
--- a/platform/web/detect.py
+++ b/platform/web/detect.py
@@ -118,6 +118,11 @@ def configure(env: "Environment"):
else:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
+ # Workaround https://github.com/emscripten-core/emscripten/issues/19781.
+ cc_version = get_compiler_version(env)
+ cc_semver = (int(cc_version["major"]), int(cc_version["minor"]), int(cc_version["patch"]))
+ if cc_semver >= (3, 1, 42):
+ env.Append(LINKFLAGS=["-Wl,-u,scalbnf"])
# Sanitizers
if env["use_ubsan"]:
diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp
index 993abd2cee..a62ccdc2aa 100644
--- a/platform/web/export/export_plugin.cpp
+++ b/platform/web/export/export_plugin.cpp
@@ -36,6 +36,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "editor/import/resource_importer_texture_settings.h"
#include "scene/resources/image_texture.h"
@@ -683,7 +684,7 @@ EditorExportPlatformWeb::EditorExportPlatformWeb() {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
- stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons"));
+ stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
} else {
stop_icon.instantiate();
}
diff --git a/platform/web/export/export_plugin.h b/platform/web/export/export_plugin.h
index 2de4a4c153..887000ac45 100644
--- a/platform/web/export/export_plugin.h
+++ b/platform/web/export/export_plugin.h
@@ -39,6 +39,7 @@
#include "core/io/tcp_server.h"
#include "core/io/zip_io.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export_platform.h"
#include "main/splash.gen.h"
@@ -73,7 +74,7 @@ class EditorExportPlatformWeb : public EditorExportPlatform {
icon.instantiate();
const String icon_path = String(GLOBAL_GET("application/config/icon")).strip_edges();
if (icon_path.is_empty() || ImageLoader::load_image(icon_path, icon) != OK) {
- return EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("DefaultProjectIcon"), SNAME("EditorIcons"))->get_image();
+ return EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("DefaultProjectIcon"), EditorStringName(EditorIcons))->get_image();
}
return icon;
}
diff --git a/platform/web/js/libs/library_godot_javascript_singleton.js b/platform/web/js/libs/library_godot_javascript_singleton.js
index 1f3633461b..cbe59230ee 100644
--- a/platform/web/js/libs/library_godot_javascript_singleton.js
+++ b/platform/web/js/libs/library_godot_javascript_singleton.js
@@ -210,7 +210,9 @@ const GodotJSWrapper = {
// This is safe! JavaScript is single threaded (and using it in threads is not a good idea anyway).
GodotJSWrapper.cb_ret = null;
const args = Array.from(arguments);
- func(p_ref, GodotJSWrapper.get_proxied(args), args.length);
+ const argsProxy = GodotJSWrapper.MyProxy(args);
+ func(p_ref, argsProxy.get_id(), args.length);
+ argsProxy.unref();
const ret = GodotJSWrapper.cb_ret;
GodotJSWrapper.cb_ret = null;
return ret;
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index c4be1821bd..d2d4d78113 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
+#include "editor/editor_string_names.h"
#include "editor/export/editor_export.h"
#include "modules/modules_enabled.gen.h" // For svg.
@@ -1020,7 +1021,7 @@ EditorExportPlatformWindows::EditorExportPlatformWindows() {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
- stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons"));
+ stop_icon = theme->get_icon(SNAME("Stop"), EditorStringName(EditorIcons));
} else {
stop_icon.instantiate();
}
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index bb223628a8..6881a75596 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -81,12 +81,9 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
return;
}
-#ifndef UWP_ENABLED
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
if (!hCon || hCon == INVALID_HANDLE_VALUE) {
-#endif
StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
-#ifndef UWP_ENABLED
} else {
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
GetConsoleScreenBufferInfo(hCon, &sbi);
@@ -159,7 +156,6 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
SetConsoleTextAttribute(hCon, sbi.wAttributes);
}
-#endif
}
WindowsTerminalLogger::~WindowsTerminalLogger() {}
diff --git a/scene/2d/tile_map.compat.inc b/scene/2d/tile_map.compat.inc
index c7786ecced..ed216173c7 100644
--- a/scene/2d/tile_map.compat.inc
+++ b/scene/2d/tile_map.compat.inc
@@ -34,8 +34,18 @@ Rect2i TileMap::_get_used_rect_bind_compat_78328() {
return get_used_rect();
}
+void TileMap::_set_quadrant_size_compat_81070(int p_quadrant_size) {
+ set_rendering_quadrant_size(p_quadrant_size);
+}
+
+int TileMap::_get_quadrant_size_compat_81070() const {
+ return get_rendering_quadrant_size();
+}
+
void TileMap::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_used_rect"), &TileMap::_get_used_rect_bind_compat_78328);
+ ClassDB::bind_compatibility_method(D_METHOD("set_quadrant_size", "quadrant_size"), &TileMap::_set_quadrant_size_compat_81070);
+ ClassDB::bind_compatibility_method(D_METHOD("get_quadrant_size"), &TileMap::_get_quadrant_size_compat_81070);
}
#endif
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c86bedbead..6938358994 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -40,175 +40,291 @@
#include "servers/navigation_server_3d.h"
#endif // DEBUG_ENABLED
-Vector2i TileMapLayer::_coords_to_quadrant_coords(const Vector2i &p_coords) const {
- int quad_size = get_effective_quadrant_size();
+#ifdef DEBUG_ENABLED
+/////////////////////////////// Debug //////////////////////////////////////////
+constexpr int TILE_MAP_DEBUG_QUADRANT_SIZE = 16;
- // Rounding down, instead of simply rounding towards zero (truncating).
+Vector2i TileMapLayer::_coords_to_debug_quadrant_coords(const Vector2i &p_coords) const {
return Vector2i(
- p_coords.x > 0 ? p_coords.x / quad_size : (p_coords.x - (quad_size - 1)) / quad_size,
- p_coords.y > 0 ? p_coords.y / quad_size : (p_coords.y - (quad_size - 1)) / quad_size);
+ p_coords.x > 0 ? p_coords.x / TILE_MAP_DEBUG_QUADRANT_SIZE : (p_coords.x - (TILE_MAP_DEBUG_QUADRANT_SIZE - 1)) / TILE_MAP_DEBUG_QUADRANT_SIZE,
+ p_coords.y > 0 ? p_coords.y / TILE_MAP_DEBUG_QUADRANT_SIZE : (p_coords.y - (TILE_MAP_DEBUG_QUADRANT_SIZE - 1)) / TILE_MAP_DEBUG_QUADRANT_SIZE);
}
-HashMap<Vector2i, TileMapQuadrant>::Iterator TileMapLayer::_create_quadrant(const Vector2i &p_qk) {
- TileMapQuadrant q;
- q.coords = p_qk;
+void TileMapLayer::_debug_update() {
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+ RenderingServer *rs = RenderingServer::get_singleton();
- rect_cache_dirty = true;
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
- // Create the debug canvas item.
- RenderingServer *rs = RenderingServer::get_singleton();
- q.debug_canvas_item = rs->canvas_item_create();
- rs->canvas_item_set_z_index(q.debug_canvas_item, RS::CANVAS_ITEM_Z_MAX - 1);
- rs->canvas_item_set_parent(q.debug_canvas_item, tile_map_node->get_canvas_item());
+ if (forced_cleanup) {
+ for (KeyValue<Vector2i, Ref<DebugQuadrant>> &kv : debug_quadrant_map) {
+ // Free the quadrant.
+ Ref<DebugQuadrant> &debug_quadrant = kv.value;
+ if (debug_quadrant->canvas_item.is_valid()) {
+ rs->free(debug_quadrant->canvas_item);
+ }
+ }
+ debug_quadrant_map.clear();
+ _debug_was_cleaned_up = true;
+ return;
+ }
- // Call the create_quadrant method on plugins.
- const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- if (tile_set.is_valid()) {
- _rendering_create_quadrant(&q);
+ // Check if anything is dirty, in such a case, redraw debug.
+ bool anything_changed = false;
+ for (int i = 0; i < DIRTY_FLAGS_MAX; i++) {
+ if (dirty.flags[i]) {
+ anything_changed = true;
+ break;
+ }
}
- return quadrant_map.insert(p_qk, q);
-}
+ // List all debug quadrants to update, creating new ones if needed.
+ SelfList<DebugQuadrant>::List dirty_debug_quadrant_list;
-void TileMapLayer::_make_quadrant_dirty(HashMap<Vector2i, TileMapQuadrant>::Iterator Q) {
- // Make the given quadrant dirty, then trigger an update later.
- TileMapQuadrant &q = Q->value;
- if (!q.dirty_list_element.in_list()) {
- dirty_quadrant_list.add(&q.dirty_list_element);
+ if (_debug_was_cleaned_up || anything_changed) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ CellData &cell_data = kv.value;
+ _debug_quadrants_update_cell(cell_data, dirty_debug_quadrant_list);
+ }
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _debug_quadrants_update_cell(cell_data, dirty_debug_quadrant_list);
+ }
}
- tile_map_node->queue_update_dirty_quadrants();
-}
-void TileMapLayer::_erase_quadrant(HashMap<Vector2i, TileMapQuadrant>::Iterator Q) {
- // Remove a quadrant.
- TileMapQuadrant *q = &(Q->value);
+ // Update those quadrants.
+ for (SelfList<DebugQuadrant> *quadrant_list_element = dirty_debug_quadrant_list.first(); quadrant_list_element;) {
+ SelfList<DebugQuadrant> *next_quadrant_list_element = quadrant_list_element->next(); // "Hack" to clear the list while iterating.
- // Call the cleanup_quadrant method on plugins.
- if (tile_map_node->get_tileset().is_valid()) {
- _rendering_cleanup_quadrant(q);
- _physics_cleanup_quadrant(q);
- _navigation_cleanup_quadrant(q);
- _scenes_cleanup_quadrant(q);
- }
+ DebugQuadrant &debug_quadrant = *quadrant_list_element->self();
+
+ // Check if the quadrant has a tile.
+ bool has_a_tile = false;
+ RID &ci = debug_quadrant.canvas_item;
+ for (SelfList<CellData> *cell_data_list_element = debug_quadrant.cells.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ if (cell_data.cell.source_id != TileSet::INVALID_SOURCE) {
+ has_a_tile = true;
+ break;
+ }
+ }
+
+ if (has_a_tile) {
+ // Update the quadrant.
+ if (ci.is_valid()) {
+ rs->canvas_item_clear(ci);
+ } else {
+ ci = rs->canvas_item_create();
+ rs->canvas_item_set_z_index(ci, RS::CANVAS_ITEM_Z_MAX - 1);
+ rs->canvas_item_set_parent(ci, tile_map_node->get_canvas_item());
+ }
- // Remove the quadrant from the dirty_list if it is there.
- if (q->dirty_list_element.in_list()) {
- dirty_quadrant_list.remove(&(q->dirty_list_element));
+ const Vector2 quadrant_pos = tile_map_node->map_to_local(debug_quadrant.quadrant_coords * TILE_MAP_DEBUG_QUADRANT_SIZE);
+ Transform2D xform(0, quadrant_pos);
+ rs->canvas_item_set_transform(ci, xform);
+
+ for (SelfList<CellData> *cell_data_list_element = debug_quadrant.cells.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ if (cell_data.cell.source_id != TileSet::INVALID_SOURCE) {
+ _rendering_draw_cell_debug(ci, quadrant_pos, cell_data);
+ _physics_draw_cell_debug(ci, quadrant_pos, cell_data);
+ _navigation_draw_cell_debug(ci, quadrant_pos, cell_data);
+ _scenes_draw_cell_debug(ci, quadrant_pos, cell_data);
+ }
+ }
+ } else {
+ // Free the quadrant.
+ if (ci.is_valid()) {
+ rs->free(ci);
+ }
+ quadrant_list_element->remove_from_list();
+ debug_quadrant_map.erase(debug_quadrant.quadrant_coords);
+ }
+
+ quadrant_list_element = next_quadrant_list_element;
}
- // Free the debug canvas item.
- RenderingServer *rs = RenderingServer::get_singleton();
- rs->free(q->debug_canvas_item);
+ dirty_debug_quadrant_list.clear();
- quadrant_map.remove(Q);
- rect_cache_dirty = true;
+ _debug_was_cleaned_up = false;
}
-/////////////////////////////// Rendering //////////////////////////////////////
+void TileMapLayer::_debug_quadrants_update_cell(CellData &r_cell_data, SelfList<DebugQuadrant>::List &r_dirty_debug_quadrant_list) {
+ Vector2i quadrant_coords = _coords_to_debug_quadrant_coords(r_cell_data.coords);
-void TileMapLayer::_rendering_update() {
- RenderingServer *rs = RenderingServer::get_singleton();
- if (!canvas_item.is_valid()) {
- RID ci = rs->canvas_item_create();
- rs->canvas_item_set_parent(ci, tile_map_node->get_canvas_item());
- rs->canvas_item_set_draw_index(ci, layer_index_in_tile_map_node - (int64_t)0x80000000);
- canvas_item = ci;
- }
- RID &ci = canvas_item;
- rs->canvas_item_set_sort_children_by_y(ci, y_sort_enabled);
- rs->canvas_item_set_use_parent_material(ci, tile_map_node->get_use_parent_material() || tile_map_node->get_material().is_valid());
- rs->canvas_item_set_z_index(ci, z_index);
- rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(tile_map_node->get_texture_filter_in_tree()));
- rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(tile_map_node->get_texture_repeat_in_tree()));
- rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
-
- Color layer_modulate = modulate;
- int selected_layer = tile_map_node->get_selected_layer();
- if (selected_layer >= 0 && layer_index_in_tile_map_node != selected_layer) {
- int z_selected = tile_map_node->get_layer_z_index(selected_layer);
- if (z_index < z_selected || (z_index == z_selected && layer_index_in_tile_map_node < selected_layer)) {
- layer_modulate = layer_modulate.darkened(0.5);
- } else if (z_index > z_selected || (z_index == z_selected && layer_index_in_tile_map_node > selected_layer)) {
- layer_modulate = layer_modulate.darkened(0.5);
- layer_modulate.a *= 0.3;
- }
+ if (!debug_quadrant_map.has(quadrant_coords)) {
+ // Create a new quadrant and add it to the quadrant map.
+ Ref<DebugQuadrant> new_quadrant;
+ new_quadrant.instantiate();
+ new_quadrant->quadrant_coords = quadrant_coords;
+ debug_quadrant_map[quadrant_coords] = new_quadrant;
}
- rs->canvas_item_set_modulate(ci, layer_modulate);
-}
-void TileMapLayer::_rendering_cleanup() {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- RenderingServer *rs = RenderingServer::get_singleton();
- if (canvas_item.is_valid()) {
- rs->free(canvas_item);
- canvas_item = RID();
+ // Add the cell to its quadrant, if it is not already in there.
+ Ref<DebugQuadrant> &debug_quadrant = debug_quadrant_map[quadrant_coords];
+ if (!r_cell_data.debug_quadrant_list_element.in_list()) {
+ debug_quadrant->cells.add(&r_cell_data.debug_quadrant_list_element);
+ }
+
+ // Mark the quadrant as dirty.
+ if (!debug_quadrant->dirty_quadrant_list_element.in_list()) {
+ r_dirty_debug_quadrant_list.add(&debug_quadrant->dirty_quadrant_list_element);
}
}
+#endif // DEBUG_ENABLED
-void TileMapLayer::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) {
- ERR_FAIL_COND(!tile_map_node->is_inside_tree());
+/////////////////////////////// Rendering //////////////////////////////////////
+Vector2i TileMapLayer::_coords_to_rendering_quadrant_coords(const Vector2i &p_coords) const {
+ int quad_size = get_effective_quadrant_size();
+
+ // Rounding down, instead of simply rounding towards zero (truncating).
+ return Vector2i(
+ p_coords.x > 0 ? p_coords.x / quad_size : (p_coords.x - (quad_size - 1)) / quad_size,
+ p_coords.y > 0 ? p_coords.y / quad_size : (p_coords.y - (quad_size - 1)) / quad_size);
+}
+
+void TileMapLayer::_rendering_update() {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
+ RenderingServer *rs = RenderingServer::get_singleton();
- bool node_visible = tile_map_node->is_visible_in_tree();
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
+
+ // ----------- Layer level processing -----------
+ if (forced_cleanup) {
+ // Cleanup.
+ if (canvas_item.is_valid()) {
+ rs->free(canvas_item);
+ canvas_item = RID();
+ }
+ } else {
+ // Create/Update the layer's CanvasItem.
+ if (!canvas_item.is_valid()) {
+ RID ci = rs->canvas_item_create();
+ rs->canvas_item_set_parent(ci, tile_map_node->get_canvas_item());
+ rs->canvas_item_set_draw_index(ci, layer_index_in_tile_map_node - (int64_t)0x80000000);
+ canvas_item = ci;
+ }
+ RID &ci = canvas_item;
+ rs->canvas_item_set_sort_children_by_y(ci, y_sort_enabled);
+ rs->canvas_item_set_use_parent_material(ci, tile_map_node->get_use_parent_material() || tile_map_node->get_material().is_valid());
+ rs->canvas_item_set_z_index(ci, z_index);
+ rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(tile_map_node->get_texture_filter_in_tree()));
+ rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(tile_map_node->get_texture_repeat_in_tree()));
+ rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
+
+ // Modulate the layer.
+ Color layer_modulate = modulate;
+ int selected_layer = tile_map_node->get_selected_layer();
+ if (selected_layer >= 0 && layer_index_in_tile_map_node != selected_layer) {
+ int z_selected = tile_map_node->get_layer_z_index(selected_layer);
+ if (z_index < z_selected || (z_index == z_selected && layer_index_in_tile_map_node < selected_layer)) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ } else if (z_index > z_selected || (z_index == z_selected && layer_index_in_tile_map_node > selected_layer)) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ layer_modulate.a *= 0.3;
+ }
+ }
+ rs->canvas_item_set_modulate(ci, layer_modulate);
+ }
- SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first();
- while (q_list_element) {
- TileMapQuadrant &q = *q_list_element->self();
+ // ----------- Quadrants processing -----------
- RenderingServer *rs = RenderingServer::get_singleton();
+ // List all rendering quadrants to update, creating new ones if needed.
+ SelfList<RenderingQuadrant>::List dirty_rendering_quadrant_list;
- // Free the canvas items.
- for (const RID &ci : q.canvas_items) {
- rs->free(ci);
+ // Check if anything changed that might change the quadrant shape.
+ // If so, recreate everything.
+ if (forced_cleanup || dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] || dirty.flags[DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE]) {
+ // Free all quadrants.
+ for (const KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
+ for (int i = 0; i < kv.value->canvas_items.size(); i++) {
+ const RID &ci = kv.value->canvas_items[i];
+ if (ci.is_valid()) {
+ rs->free(ci);
+ }
+ }
+ kv.value->cells.clear();
}
- q.canvas_items.clear();
+ rendering_quadrant_map.clear();
+ _rendering_was_cleaned_up = true;
+ }
- // Free the occluders.
- for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
- rs->free(kv.value);
+ if (!forced_cleanup) {
+ // List all quadrants to update, recreating them if needed.
+ if (dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET] || _rendering_was_cleaned_up) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ CellData &cell_data = kv.value;
+ _rendering_quadrants_update_cell(cell_data, dirty_rendering_quadrant_list);
+ }
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _rendering_quadrants_update_cell(cell_data, dirty_rendering_quadrant_list);
+ }
}
- q.occluders.clear();
- // Those allow to group cell per material or z-index.
- Ref<Material> prev_material;
- int prev_z_index = 0;
- RID prev_ci;
+ // Update all dirty quadrants.
+ for (SelfList<RenderingQuadrant> *quadrant_list_element = dirty_rendering_quadrant_list.first(); quadrant_list_element;) {
+ SelfList<RenderingQuadrant> *next_quadrant_list_element = quadrant_list_element->next(); // "Hack" to clear the list while iterating.
- // Iterate over the cells of the quadrant.
- for (const KeyValue<Vector2, Vector2i> &E_cell : q.local_to_map) {
- TileMapCell c = get_cell(E_cell.value, true);
+ const Ref<RenderingQuadrant> &rendering_quadrant = quadrant_list_element->self();
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
+ // Check if the quadrant has a tile.
+ bool has_a_tile = false;
+ for (SelfList<CellData> *cell_data_list_element = rendering_quadrant->cells.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ if (cell_data.cell.source_id != TileSet::INVALID_SOURCE) {
+ has_a_tile = true;
+ break;
+ }
+ }
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
+ if (has_a_tile) {
+ // Process the quadrant.
+
+ // First, clear the quadrant's canvas items.
+ for (RID &ci : rendering_quadrant->canvas_items) {
+ rs->free(ci);
}
+ rendering_quadrant->canvas_items.clear();
+
+ // Those allow to group cell per material or z-index.
+ Ref<Material> prev_material;
+ int prev_z_index = 0;
+ RID prev_ci;
+
+ for (SelfList<CellData> *cell_data_quadrant_list_element = rendering_quadrant->cells.first(); cell_data_quadrant_list_element; cell_data_quadrant_list_element = cell_data_quadrant_list_element->next()) {
+ CellData &cell_data = *cell_data_quadrant_list_element->self();
+
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(cell_data.cell.source_id));
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
// Get the tile data.
const TileData *tile_data;
- if (q.runtime_tile_data_cache.has(E_cell.value)) {
- tile_data = q.runtime_tile_data_cache[E_cell.value];
+ if (cell_data.runtime_tile_data_cache) {
+ tile_data = cell_data.runtime_tile_data_cache;
} else {
- tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+ tile_data = atlas_source->get_tile_data(cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile);
}
Ref<Material> mat = tile_data->get_material();
int tile_z_index = tile_data->get_z_index();
// Quandrant pos.
- Vector2 tile_position = tile_map_node->map_to_local(q.coords * get_effective_quadrant_size());
+ Vector2i quadrant_coords = _coords_to_rendering_quadrant_coords(cell_data.coords);
+ Vector2 ci_position = tile_map_node->map_to_local(quadrant_coords * get_effective_quadrant_size());
if (tile_map_node->is_y_sort_enabled() && y_sort_enabled) {
// When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem.
- tile_position.y += y_sort_origin + tile_data->get_y_sort_origin();
+ ci_position.y += y_sort_origin + tile_data->get_y_sort_origin();
}
// --- CanvasItems ---
- // Create two canvas items, for rendering and debug.
RID ci;
// Check if the material or the z_index changed.
@@ -221,8 +337,7 @@ void TileMapLayer::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::
rs->canvas_item_set_parent(ci, canvas_item);
rs->canvas_item_set_use_parent_material(ci, tile_map_node->get_use_parent_material() || tile_map_node->get_material().is_valid());
- Transform2D xform;
- xform.set_origin(tile_position);
+ Transform2D xform(0, ci_position);
rs->canvas_item_set_transform(ci, xform);
rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
@@ -232,7 +347,7 @@ void TileMapLayer::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::
rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(tile_map_node->get_texture_filter_in_tree()));
rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(tile_map_node->get_texture_repeat_in_tree()));
- q.canvas_items.push_back(ci);
+ rendering_quadrant->canvas_items.push_back(ci);
prev_ci = ci;
prev_material = mat;
@@ -243,84 +358,214 @@ void TileMapLayer::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::
ci = prev_ci;
}
+ const Vector2 local_tile_pos = tile_map_node->map_to_local(cell_data.coords);
+
// Random animation offset.
real_t random_animation_offset = 0.0;
- if (atlas_source->get_tile_animation_mode(c.get_atlas_coords()) != TileSetAtlasSource::TILE_ANIMATION_MODE_DEFAULT) {
+ if (atlas_source->get_tile_animation_mode(cell_data.cell.get_atlas_coords()) != TileSetAtlasSource::TILE_ANIMATION_MODE_DEFAULT) {
Array to_hash;
- to_hash.push_back(E_cell.key);
+ to_hash.push_back(local_tile_pos);
to_hash.push_back(get_instance_id()); // Use instance id as a random hash
random_animation_offset = RandomPCG(to_hash.hash()).randf();
}
// Drawing the tile in the canvas item.
- tile_map_node->draw_tile(ci, E_cell.key - tile_position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, tile_map_node->get_self_modulate(), tile_data, random_animation_offset);
-
- // --- Occluders ---
- for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) {
- Transform2D xform;
- xform.set_origin(E_cell.key);
- if (tile_data->get_occluder(i).is_valid()) {
- RID occluder_id = rs->canvas_light_occluder_create();
- rs->canvas_light_occluder_set_enabled(occluder_id, node_visible);
- rs->canvas_light_occluder_set_transform(occluder_id, tile_map_node->get_global_transform() * xform);
- rs->canvas_light_occluder_set_polygon(occluder_id, tile_data->get_occluder(i)->get_rid());
- rs->canvas_light_occluder_attach_to_canvas(occluder_id, tile_map_node->get_canvas());
- rs->canvas_light_occluder_set_light_mask(occluder_id, tile_set->get_occlusion_layer_light_mask(i));
- q.occluders[E_cell.value] = occluder_id;
- }
+ tile_map_node->draw_tile(ci, local_tile_pos - ci_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, tile_map_node->get_self_modulate(), tile_data, random_animation_offset);
+ }
+ } else {
+ // Free the quadrant.
+ for (int i = 0; i < rendering_quadrant->canvas_items.size(); i++) {
+ const RID &ci = rendering_quadrant->canvas_items[i];
+ if (ci.is_valid()) {
+ rs->free(ci);
}
}
+ rendering_quadrant->cells.clear();
+ rendering_quadrant_map.erase(rendering_quadrant->quadrant_coords);
}
+
+ quadrant_list_element = next_quadrant_list_element;
}
- _rendering_quadrant_order_dirty = true;
- q_list_element = q_list_element->next();
- }
+ dirty_rendering_quadrant_list.clear();
- // Reset the drawing indices.
- if (_rendering_quadrant_order_dirty) {
- int index = -(int64_t)0x80000000; //always must be drawn below children.
+ // Reset the drawing indices.
+ {
+ int index = -(int64_t)0x80000000; // Always must be drawn below children.
- // Sort the quadrants coords per local coordinates.
- RBMap<Vector2, Vector2i, TileMapQuadrant::CoordsWorldComparator> local_to_map;
- for (const KeyValue<Vector2i, TileMapQuadrant> &E : quadrant_map) {
- local_to_map[tile_map_node->map_to_local(E.key)] = E.key;
+ // Sort the quadrants coords per local coordinates.
+ RBMap<Vector2, Ref<RenderingQuadrant>, RenderingQuadrant::CoordsWorldComparator> local_to_map;
+ for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
+ Ref<RenderingQuadrant> &rendering_quadrant = kv.value;
+ local_to_map[tile_map_node->map_to_local(rendering_quadrant->quadrant_coords)] = rendering_quadrant;
+ }
+
+ // Sort the quadrants.
+ for (const KeyValue<Vector2, Ref<RenderingQuadrant>> &E : local_to_map) {
+ for (const RID &ci : E.value->canvas_items) {
+ RS::get_singleton()->canvas_item_set_draw_index(ci, index++);
+ }
+ }
}
- // Sort the quadrants.
- for (const KeyValue<Vector2, Vector2i> &E : local_to_map) {
- TileMapQuadrant &q = quadrant_map[E.value];
- for (const RID &ci : q.canvas_items) {
- RS::get_singleton()->canvas_item_set_draw_index(ci, index++);
+ // Updates on TileMap changes.
+ if (dirty.flags[DIRTY_FLAGS_TILE_MAP_LIGHT_MASK] ||
+ dirty.flags[DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL] ||
+ dirty.flags[DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER] ||
+ dirty.flags[DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT]) {
+ for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
+ Ref<RenderingQuadrant> &rendering_quadrant = kv.value;
+ for (const RID &ci : rendering_quadrant->canvas_items) {
+ rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
+ rs->canvas_item_set_use_parent_material(ci, tile_map_node->get_use_parent_material() || tile_map_node->get_material().is_valid());
+ rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(tile_map_node->get_texture_filter_in_tree()));
+ rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(tile_map_node->get_texture_repeat_in_tree()));
+ }
+ }
+ }
+ }
+
+ // ----------- Occluders processing -----------
+ if (forced_cleanup) {
+ // Clean everything.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _rendering_occluders_clear_cell(kv.value);
+ }
+ } else {
+ if (_rendering_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET]) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _rendering_occluders_update_cell(kv.value);
+ }
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _rendering_occluders_update_cell(cell_data);
+ }
+ }
+
+ // Updates on TileMap changes.
+ if (dirty.flags[DIRTY_FLAGS_TILE_MAP_IN_CANVAS] || dirty.flags[DIRTY_FLAGS_TILE_MAP_VISIBILITY]) {
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ CellData &cell_data = kv.value;
+ for (const RID &occluder : cell_data.occluders) {
+ Transform2D xform(0, tile_map_node->map_to_local(kv.key));
+ rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas());
+ rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform);
+ }
}
}
- _rendering_quadrant_order_dirty = false;
}
+
+ // -----------
+ // Mark the rendering state as up to date.
+ _rendering_was_cleaned_up = forced_cleanup;
}
-void TileMapLayer::_rendering_create_quadrant(TileMapQuadrant *p_quadrant) {
+void TileMapLayer::_rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list) {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
+ Vector2i quadrant_coords = _coords_to_rendering_quadrant_coords(r_cell_data.coords);
- _rendering_quadrant_order_dirty = true;
-}
+ if (rendering_quadrant_map.has(quadrant_coords)) {
+ // Mark the quadrant as dirty.
+ Ref<RenderingQuadrant> &rendering_quadrant = rendering_quadrant_map[quadrant_coords];
+ if (!rendering_quadrant->dirty_quadrant_list_element.in_list()) {
+ r_dirty_rendering_quadrant_list.add(&rendering_quadrant->dirty_quadrant_list_element);
+ }
+ } else {
+ // Create a new quadrant and add it to the quadrant lists.
+ Ref<RenderingQuadrant> new_quadrant;
+ new_quadrant.instantiate();
+ new_quadrant->quadrant_coords = quadrant_coords;
+ rendering_quadrant_map[quadrant_coords] = new_quadrant;
+ }
+
+ // Check if the cell is valid.
+ bool is_valid = false;
+ TileSetSource *source;
+ if (tile_set->has_source(r_cell_data.cell.source_id)) {
+ source = *tile_set->get_source(r_cell_data.cell.source_id);
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source && atlas_source->has_tile(r_cell_data.cell.get_atlas_coords()) && atlas_source->has_alternative_tile(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile)) {
+ is_valid = true;
+ }
+ }
-void TileMapLayer::_rendering_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- // Free the canvas items.
- for (const RID &ci : p_quadrant->canvas_items) {
- RenderingServer::get_singleton()->free(ci);
+ // Add/Remove the cell to/from its quadrant.
+ Ref<RenderingQuadrant> &rendering_quadrant = rendering_quadrant_map[quadrant_coords];
+ if (r_cell_data.rendering_quadrant_list_element.in_list()) {
+ if (!is_valid) {
+ r_cell_data.rendering_quadrant_list_element.remove_from_list();
+ }
+ } else {
+ if (is_valid) {
+ rendering_quadrant->cells.add(&r_cell_data.rendering_quadrant_list_element);
+ }
}
- p_quadrant->canvas_items.clear();
+
+ // Add the quadrant to the dirty quadrant list.
+ if (!rendering_quadrant->dirty_quadrant_list_element.in_list()) {
+ r_dirty_rendering_quadrant_list.add(&rendering_quadrant->dirty_quadrant_list_element);
+ }
+}
+
+void TileMapLayer::_rendering_occluders_clear_cell(CellData &r_cell_data) {
+ RenderingServer *rs = RenderingServer::get_singleton();
// Free the occluders.
- for (const KeyValue<Vector2i, RID> &kv : p_quadrant->occluders) {
- RenderingServer::get_singleton()->free(kv.value);
+ for (const RID &rid : r_cell_data.occluders) {
+ rs->free(rid);
+ }
+ r_cell_data.occluders.clear();
+}
+
+void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
+ bool node_visible = tile_map_node->is_visible_in_tree();
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+ RenderingServer *rs = RenderingServer::get_singleton();
+
+ TileSetSource *source;
+ if (tile_set->has_source(r_cell_data.cell.source_id)) {
+ source = *tile_set->get_source(r_cell_data.cell.source_id);
+
+ if (source->has_tile(r_cell_data.cell.get_atlas_coords()) && source->has_alternative_tile(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile)) {
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ // Get the tile data.
+ const TileData *tile_data;
+ if (r_cell_data.runtime_tile_data_cache) {
+ tile_data = r_cell_data.runtime_tile_data_cache;
+ } else {
+ tile_data = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile);
+ }
+
+ // Update/create occluders.
+ for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) {
+ Transform2D xform;
+ xform.set_origin(tile_map_node->map_to_local(r_cell_data.coords));
+ if (tile_data->get_occluder(i).is_valid()) {
+ RID occluder_id = rs->canvas_light_occluder_create();
+ rs->canvas_light_occluder_set_enabled(occluder_id, node_visible);
+ rs->canvas_light_occluder_set_transform(occluder_id, tile_map_node->get_global_transform() * xform);
+ rs->canvas_light_occluder_set_polygon(occluder_id, tile_data->get_occluder(i)->get_rid());
+ rs->canvas_light_occluder_attach_to_canvas(occluder_id, tile_map_node->get_canvas());
+ rs->canvas_light_occluder_set_light_mask(occluder_id, tile_set->get_occlusion_layer_light_mask(i));
+ r_cell_data.occluders.push_back(occluder_id);
+ }
+ }
+
+ return;
+ }
+ }
}
- p_quadrant->occluders.clear();
+
+ // If we did not return earlier, clear the cell.
+ _rendering_occluders_clear_cell(r_cell_data);
}
-void TileMapLayer::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
+#ifdef DEBUG_ENABLED
+void TileMapLayer::_rendering_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data) {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
ERR_FAIL_COND(!tile_set.is_valid());
@@ -330,18 +575,13 @@ void TileMapLayer::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder for tiles needing one.
RenderingServer *rs = RenderingServer::get_singleton();
- Vector2 quadrant_pos = tile_map_node->map_to_local(p_quadrant->coords * get_effective_quadrant_size());
- for (const Vector2i &E_cell : p_quadrant->cells) {
- const TileMapCell &c = get_cell(E_cell, true);
+ const TileMapCell &c = r_cell_data.cell;
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
-
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
Vector2i grid_size = atlas_source->get_atlas_grid_size();
@@ -362,71 +602,156 @@ void TileMapLayer::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder tile.
Transform2D cell_to_quadrant;
- cell_to_quadrant.set_origin(tile_map_node->map_to_local(E_cell) - quadrant_pos);
- rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, cell_to_quadrant);
- rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
+ cell_to_quadrant.set_origin(tile_map_node->map_to_local(r_cell_data.coords) - p_quadrant_pos);
+ rs->canvas_item_add_set_transform(p_canvas_item, cell_to_quadrant);
+ rs->canvas_item_add_circle(p_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
}
}
}
}
}
+#endif // DEBUG_ENABLED
/////////////////////////////// Physics //////////////////////////////////////
-void TileMapLayer::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) {
- ERR_FAIL_COND(!tile_map_node->is_inside_tree());
+void TileMapLayer::_physics_update() {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
+ if (forced_cleanup) {
+ // Clean everything.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _physics_clear_cell(kv.value);
+ }
+ } else {
+ if (_physics_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET] || dirty.flags[DIRTY_FLAGS_TILE_MAP_COLLISION_ANIMATABLE]) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _physics_update_cell(kv.value);
+ }
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _physics_update_cell(cell_data);
+ }
+ }
+ }
+
+ // -----------
+ // Mark the physics state as up to date.
+ _physics_was_cleaned_up = forced_cleanup;
+}
+
+void TileMapLayer::_physics_notify_tilemap_change(TileMapLayer::DirtyFlags p_what) {
Transform2D gl_transform = tile_map_node->get_global_transform();
+ bool in_editor = false;
+#ifdef TOOLS_ENABLED
+ in_editor = Engine::get_singleton()->is_editor_hint();
+#endif
- PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
- RID space = tile_map_node->get_world_2d()->get_space();
+ if (p_what == DIRTY_FLAGS_TILE_MAP_XFORM) {
+ if (tile_map_node->is_inside_tree() && (!tile_map_node->is_collision_animatable() || in_editor)) {
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ const CellData &cell_data = kv.value;
- SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first();
- while (q_list_element) {
- TileMapQuadrant &q = *q_list_element->self();
+ for (RID body : cell_data.bodies) {
+ if (body.is_valid()) {
+ Transform2D xform(0, tile_map_node->map_to_local(bodies_coords[body]));
+ xform = gl_transform * xform;
+ PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
+ }
+ }
+ }
+ }
+ } else if (p_what == DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM) {
+ if (tile_map_node->is_inside_tree() && tile_map_node->is_collision_animatable() && !in_editor) {
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ const CellData &cell_data = kv.value;
+
+ for (RID body : cell_data.bodies) {
+ if (body.is_valid()) {
+ Transform2D xform(0, tile_map_node->map_to_local(bodies_coords[body]));
+ xform = gl_transform * xform;
+ PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
+ }
+ }
+ }
+ }
+ }
+}
+
+void TileMapLayer::_physics_clear_cell(CellData &r_cell_data) {
+ PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
- // Clear bodies.
- for (RID body : q.bodies) {
+ // Clear bodies.
+ for (RID body : r_cell_data.bodies) {
+ if (body.is_valid()) {
bodies_coords.erase(body);
ps->free(body);
}
- q.bodies.clear();
+ }
+ r_cell_data.bodies.clear();
+}
- // Recreate bodies and shapes.
- for (const Vector2i &E_cell : q.cells) {
- TileMapCell c = get_cell(E_cell, true);
+void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+ Transform2D gl_transform = tile_map_node->get_global_transform();
+ RID space = tile_map_node->get_world_2d()->get_space();
+ PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
+ // Recreate bodies and shapes.
+ TileMapCell &c = r_cell_data.cell;
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
+
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ const TileData *tile_data;
+ if (r_cell_data.runtime_tile_data_cache) {
+ tile_data = r_cell_data.runtime_tile_data_cache;
+ } else {
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
- const TileData *tile_data;
- if (q.runtime_tile_data_cache.has(E_cell)) {
- tile_data = q.runtime_tile_data_cache[E_cell];
- } else {
- tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+ // Free unused bodies then resize the bodies array.
+ for (unsigned int i = tile_set->get_physics_layers_count(); i < r_cell_data.bodies.size(); i++) {
+ RID body = r_cell_data.bodies[i];
+ if (body.is_valid()) {
+ bodies_coords.erase(body);
+ ps->free(body);
}
- for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) {
- Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
- uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer);
- uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer);
-
- // Create the body.
- RID body = ps->body_create();
- bodies_coords[body] = E_cell;
+ }
+ r_cell_data.bodies.resize(tile_set->get_physics_layers_count());
+
+ for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) {
+ Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
+ uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer);
+ uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer);
+
+ RID body = r_cell_data.bodies[tile_set_physics_layer];
+ if (tile_data->get_collision_polygons_count(tile_set_physics_layer) == 0) {
+ // No body needed, free it if it exists.
+ if (body.is_valid()) {
+ bodies_coords.erase(body);
+ ps->free(body);
+ }
+ body = RID();
+ } else {
+ // Create or update the body.
+ if (!body.is_valid()) {
+ body = ps->body_create();
+ }
+ bodies_coords[body] = r_cell_data.coords;
ps->body_set_mode(body, tile_map_node->is_collision_animatable() ? PhysicsServer2D::BODY_MODE_KINEMATIC : PhysicsServer2D::BODY_MODE_STATIC);
ps->body_set_space(body, space);
Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(E_cell));
+ xform.set_origin(tile_map_node->map_to_local(r_cell_data.coords));
xform = gl_transform * xform;
ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
@@ -445,7 +770,8 @@ void TileMapLayer::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::Li
ps->body_set_param(body, PhysicsServer2D::BODY_PARAM_FRICTION, physics_material->computed_friction());
}
- q.bodies.push_back(body);
+ // Clear body's shape if needed.
+ ps->body_clear_shapes(body);
// Add the shapes to the body.
int body_shape_index = 0;
@@ -464,25 +790,22 @@ void TileMapLayer::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::Li
}
}
}
+
+ // Set the body again.
+ r_cell_data.bodies[tile_set_physics_layer] = body;
}
+
+ return;
}
}
-
- q_list_element = q_list_element->next();
}
-}
-void TileMapLayer::_physics_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
- // Remove a quadrant.
- ERR_FAIL_NULL(PhysicsServer2D::get_singleton());
- for (RID body : p_quadrant->bodies) {
- bodies_coords.erase(body);
- PhysicsServer2D::get_singleton()->free(body);
- }
- p_quadrant->bodies.clear();
+ // If we did not return earlier, clear the cell.
+ _physics_clear_cell(r_cell_data);
}
-void TileMapLayer::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
+#ifdef DEBUG_ENABLED
+void TileMapLayer::_physics_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data) {
// Draw the debug collision shapes.
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
ERR_FAIL_COND(!tile_set.is_valid());
@@ -514,155 +837,191 @@ void TileMapLayer::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
Vector<Color> color;
color.push_back(debug_collision_color);
- Vector2 quadrant_pos = tile_map_node->map_to_local(p_quadrant->coords * get_effective_quadrant_size());
- Transform2D quadrant_to_local;
- quadrant_to_local.set_origin(quadrant_pos);
+ Transform2D quadrant_to_local(0, p_quadrant_pos);
Transform2D global_to_quadrant = (tile_map_node->get_global_transform() * quadrant_to_local).affine_inverse();
- for (RID body : p_quadrant->bodies) {
- Transform2D body_to_quadrant = global_to_quadrant * Transform2D(ps->body_get_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM));
- rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, body_to_quadrant);
- for (int shape_index = 0; shape_index < ps->body_get_shape_count(body); shape_index++) {
- const RID &shape = ps->body_get_shape(body, shape_index);
- PhysicsServer2D::ShapeType type = ps->shape_get_type(shape);
- if (type == PhysicsServer2D::SHAPE_CONVEX_POLYGON) {
- Vector<Vector2> polygon = ps->shape_get_data(shape);
- rs->canvas_item_add_polygon(p_quadrant->debug_canvas_item, polygon, color);
- } else {
- WARN_PRINT("Wrong shape type for a tile, should be SHAPE_CONVEX_POLYGON.");
+ for (RID body : r_cell_data.bodies) {
+ if (body.is_valid()) {
+ Transform2D body_to_quadrant = global_to_quadrant * Transform2D(ps->body_get_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM));
+ rs->canvas_item_add_set_transform(p_canvas_item, body_to_quadrant);
+ for (int shape_index = 0; shape_index < ps->body_get_shape_count(body); shape_index++) {
+ const RID &shape = ps->body_get_shape(body, shape_index);
+ const PhysicsServer2D::ShapeType &type = ps->shape_get_type(shape);
+ if (type == PhysicsServer2D::SHAPE_CONVEX_POLYGON) {
+ rs->canvas_item_add_polygon(p_canvas_item, ps->shape_get_data(shape), color);
+ } else {
+ WARN_PRINT("Wrong shape type for a tile, should be SHAPE_CONVEX_POLYGON.");
+ }
}
+ rs->canvas_item_add_set_transform(p_canvas_item, Transform2D());
}
- rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, Transform2D());
}
};
+#endif // DEBUG_ENABLED
/////////////////////////////// Navigation //////////////////////////////////////
-void TileMapLayer::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) {
- ERR_FAIL_COND(!tile_map_node->is_inside_tree());
+void TileMapLayer::_navigation_update() {
+ ERR_FAIL_NULL(NavigationServer2D::get_singleton());
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
+ NavigationServer2D *ns = NavigationServer2D::get_singleton();
- Transform2D tilemap_xform = tile_map_node->get_global_transform();
- SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first();
- while (q_list_element) {
- TileMapQuadrant &q = *q_list_element->self();
-
- // Clear navigation shapes in the quadrant.
- for (const KeyValue<Vector2i, Vector<RID>> &E : q.navigation_regions) {
- for (int i = 0; i < E.value.size(); i++) {
- RID region = E.value[i];
- if (!region.is_valid()) {
- continue;
- }
- NavigationServer2D::get_singleton()->region_set_map(region, RID());
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
+
+ // ----------- Layer level processing -----------
+ if (forced_cleanup) {
+ if (navigation_map.is_valid() && !uses_world_navigation_map) {
+ ns->free(navigation_map);
+ navigation_map = RID();
+ }
+ } else {
+ // Update navigation maps.
+ if (!navigation_map.is_valid()) {
+ if (layer_index_in_tile_map_node == 0) {
+ // Use the default World2D navigation map for the first layer when empty.
+ navigation_map = tile_map_node->get_world_2d()->get_navigation_map();
+ uses_world_navigation_map = true;
+ } else {
+ RID new_layer_map = ns->map_create();
+ // Set the default NavigationPolygon cell_size on the new map as a mismatch causes an error.
+ ns->map_set_cell_size(new_layer_map, 1.0);
+ ns->map_set_active(new_layer_map, true);
+ navigation_map = new_layer_map;
+ uses_world_navigation_map = false;
}
}
- q.navigation_regions.clear();
-
- // Get the navigation polygons and create regions.
- for (const Vector2i &E_cell : q.cells) {
- TileMapCell c = get_cell(E_cell, true);
-
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
+ }
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
+ // ----------- Navigation regions processing -----------
+ if (forced_cleanup) {
+ // Clean everything.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _navigation_clear_cell(kv.value);
+ }
+ } else {
+ if (_navigation_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET]) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _navigation_update_cell(kv.value);
+ }
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _navigation_update_cell(cell_data);
+ }
+ }
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
- const TileData *tile_data;
- if (q.runtime_tile_data_cache.has(E_cell)) {
- tile_data = q.runtime_tile_data_cache[E_cell];
- } else {
- tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
- }
- q.navigation_regions[E_cell].resize(tile_set->get_navigation_layers_count());
-
- for (int navigation_layer_index = 0; navigation_layer_index < tile_set->get_navigation_layers_count(); navigation_layer_index++) {
- Ref<NavigationPolygon> navigation_polygon;
- navigation_polygon = tile_data->get_navigation_polygon(navigation_layer_index);
-
- if (navigation_polygon.is_valid()) {
- Transform2D tile_transform;
- tile_transform.set_origin(tile_map_node->map_to_local(E_cell));
-
- RID region = NavigationServer2D::get_singleton()->region_create();
- NavigationServer2D::get_singleton()->region_set_owner_id(region, tile_map_node->get_instance_id());
- NavigationServer2D::get_singleton()->region_set_map(region, navigation_map);
- NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform);
- NavigationServer2D::get_singleton()->region_set_navigation_layers(region, tile_set->get_navigation_layer_layers(navigation_layer_index));
- NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, navigation_polygon);
- q.navigation_regions[E_cell].write[navigation_layer_index] = region;
- }
+ if (dirty.flags[DIRTY_FLAGS_TILE_MAP_XFORM]) {
+ Transform2D tilemap_xform = tile_map_node->get_global_transform();
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ const CellData &cell_data = kv.value;
+ // Update navigation regions transform.
+ for (const RID &region : cell_data.navigation_regions) {
+ if (!region.is_valid()) {
+ continue;
}
+ Transform2D tile_transform;
+ tile_transform.set_origin(tile_map_node->map_to_local(kv.key));
+ NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform);
}
}
}
-
- q_list_element = q_list_element->next();
}
-}
-void TileMapLayer::_navigation_update() {
- ERR_FAIL_NULL(NavigationServer2D::get_singleton());
+ // -----------
+ // Mark the navigation state as up to date.
+ _navigation_was_cleaned_up = forced_cleanup;
+}
- if (!navigation_map.is_valid()) {
- if (layer_index_in_tile_map_node == 0 && tile_map_node->is_inside_tree()) {
- // Use the default World2D navigation map for the first layer when empty.
- navigation_map = tile_map_node->get_world_2d()->get_navigation_map();
- uses_world_navigation_map = true;
- } else {
- RID new_layer_map = NavigationServer2D::get_singleton()->map_create();
- // Set the default NavigationPolygon cell_size on the new map as a mismatch causes an error.
- NavigationServer2D::get_singleton()->map_set_cell_size(new_layer_map, 1.0);
- NavigationServer2D::get_singleton()->map_set_active(new_layer_map, true);
- navigation_map = new_layer_map;
- uses_world_navigation_map = false;
+void TileMapLayer::_navigation_clear_cell(CellData &r_cell_data) {
+ NavigationServer2D *ns = NavigationServer2D::get_singleton();
+ // Clear navigation shapes.
+ for (unsigned int i = 0; i < r_cell_data.navigation_regions.size(); i++) {
+ const RID &region = r_cell_data.navigation_regions[i];
+ if (region.is_valid()) {
+ ns->region_set_map(region, RID());
+ ns->free(region);
}
}
+ r_cell_data.navigation_regions.clear();
}
-void TileMapLayer::_navigation_cleanup() {
- ERR_FAIL_NULL(NavigationServer2D::get_singleton());
+void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+ NavigationServer2D *ns = NavigationServer2D::get_singleton();
+ Transform2D tilemap_xform = tile_map_node->get_global_transform();
- if (navigation_map.is_valid()) {
- if (uses_world_navigation_map) {
- // Do not delete the World2D default navigation map.
- return;
- }
- NavigationServer2D::get_singleton()->free(navigation_map);
- navigation_map = RID();
- }
-}
+ // Get the navigation polygons and create regions.
+ TileMapCell &c = r_cell_data.cell;
-void TileMapLayer::_navigation_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
- // Clear navigation shapes in the quadrant.
- ERR_FAIL_NULL(NavigationServer2D::get_singleton());
- for (const KeyValue<Vector2i, Vector<RID>> &E : p_quadrant->navigation_regions) {
- for (int i = 0; i < E.value.size(); i++) {
- RID region = E.value[i];
- if (!region.is_valid()) {
- continue;
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
+
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ const TileData *tile_data;
+ if (r_cell_data.runtime_tile_data_cache) {
+ tile_data = r_cell_data.runtime_tile_data_cache;
+ } else {
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+ }
+
+ // Free unused regions then resize the regions array.
+ for (unsigned int i = tile_set->get_navigation_layers_count(); i < r_cell_data.navigation_regions.size(); i++) {
+ RID &region = r_cell_data.navigation_regions[i];
+ if (region.is_valid()) {
+ ns->region_set_map(region, RID());
+ ns->free(region);
+ region = RID();
+ }
+ }
+ r_cell_data.navigation_regions.resize(tile_set->get_navigation_layers_count());
+
+ // Create, update or clear regions.
+ for (unsigned int navigation_layer_index = 0; navigation_layer_index < r_cell_data.navigation_regions.size(); navigation_layer_index++) {
+ Ref<NavigationPolygon> navigation_polygon;
+ navigation_polygon = tile_data->get_navigation_polygon(navigation_layer_index);
+
+ RID &region = r_cell_data.navigation_regions[navigation_layer_index];
+
+ if (navigation_polygon.is_valid() && (navigation_polygon->get_polygon_count() > 0 || navigation_polygon->get_outline_count() > 0)) {
+ // Create or update regions.
+ Transform2D tile_transform;
+ tile_transform.set_origin(tile_map_node->map_to_local(r_cell_data.coords));
+ if (!region.is_valid()) {
+ region = ns->region_create();
+ }
+ ns->region_set_owner_id(region, tile_map_node->get_instance_id());
+ ns->region_set_map(region, navigation_map);
+ ns->region_set_transform(region, tilemap_xform * tile_transform);
+ ns->region_set_navigation_layers(region, tile_set->get_navigation_layer_layers(navigation_layer_index));
+ ns->region_set_navigation_polygon(region, navigation_polygon);
+ } else {
+ // Clear region.
+ if (region.is_valid()) {
+ ns->region_set_map(region, RID());
+ ns->free(region);
+ region = RID();
+ }
+ }
+ }
+
+ return;
}
- NavigationServer2D::get_singleton()->free(region);
}
}
- p_quadrant->navigation_regions.clear();
+
+ // If we did not return earlier, clear the cell.
+ _navigation_clear_cell(r_cell_data);
}
-void TileMapLayer::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
+#ifdef DEBUG_ENABLED
+void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data) {
// Draw the debug collision shapes.
- const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
-
- if (!tile_map_node->get_tree()) {
- return;
- }
-
bool show_navigation = false;
switch (tile_map_node->get_navigation_visibility_mode()) {
case TileMap::VISIBILITY_MODE_DEFAULT:
@@ -679,7 +1038,8 @@ void TileMapLayer::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant)
return;
}
-#ifdef DEBUG_ENABLED
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+
RenderingServer *rs = RenderingServer::get_singleton();
const NavigationServer2D *ns2d = NavigationServer2D::get_singleton();
@@ -691,31 +1051,25 @@ void TileMapLayer::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant)
RandomPCG rand;
- Vector2 quadrant_pos = tile_map_node->map_to_local(p_quadrant->coords * get_effective_quadrant_size());
-
- for (const Vector2i &E_cell : p_quadrant->cells) {
- TileMapCell c = get_cell(E_cell, true);
+ const TileMapCell &c = r_cell_data.cell;
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
-
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
const TileData *tile_data;
- if (p_quadrant->runtime_tile_data_cache.has(E_cell)) {
- tile_data = p_quadrant->runtime_tile_data_cache[E_cell];
+ if (r_cell_data.runtime_tile_data_cache) {
+ tile_data = r_cell_data.runtime_tile_data_cache;
} else {
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
Transform2D cell_to_quadrant;
- cell_to_quadrant.set_origin(tile_map_node->map_to_local(E_cell) - quadrant_pos);
- rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, cell_to_quadrant);
+ cell_to_quadrant.set_origin(tile_map_node->map_to_local(r_cell_data.coords) - p_quadrant_pos);
+ rs->canvas_item_add_set_transform(p_canvas_item, cell_to_quadrant);
for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) {
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(layer_index);
@@ -747,13 +1101,13 @@ void TileMapLayer::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant)
Vector<Color> debug_face_colors;
debug_face_colors.push_back(random_variation_color);
- rs->canvas_item_add_polygon(p_quadrant->debug_canvas_item, debug_polygon_vertices, debug_face_colors);
+ rs->canvas_item_add_polygon(p_canvas_item, debug_polygon_vertices, debug_face_colors);
if (enabled_edge_lines) {
Vector<Color> debug_edge_colors;
debug_edge_colors.push_back(debug_edge_color);
debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline.
- rs->canvas_item_add_polyline(p_quadrant->debug_canvas_item, debug_polygon_vertices, debug_edge_colors);
+ rs->canvas_item_add_polyline(p_canvas_item, debug_polygon_vertices, debug_edge_colors);
}
}
}
@@ -761,79 +1115,89 @@ void TileMapLayer::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant)
}
}
}
-#endif // DEBUG_ENABLED
}
+#endif // DEBUG_ENABLED
/////////////////////////////// Scenes //////////////////////////////////////
-void TileMapLayer::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) {
+void TileMapLayer::_scenes_update() {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- ERR_FAIL_COND(!tile_set.is_valid());
- SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first();
- while (q_list_element) {
- TileMapQuadrant &q = *q_list_element->self();
- _scenes_cleanup_quadrant(&q);
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
- // Recreate the scenes.
- for (const Vector2i &E_cell : q.cells) {
- if (instantiated_scenes.has(E_cell)) {
- // Skip scene if the instance was cached (to avoid recreating scenes unnecessarily).
- continue;
+ if (forced_cleanup) {
+ // Clean everything.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _scenes_clear_cell(kv.value);
+ }
+ } else {
+ if (_scenes_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET]) {
+ // Update all cells.
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ _scenes_update_cell(kv.value);
}
- if (!Engine::get_singleton()->is_editor_hint()) {
- instantiated_scenes.insert(E_cell);
+ } else {
+ // Update dirty cells.
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _scenes_update_cell(cell_data);
}
+ }
+ }
- const TileMapCell &c = get_cell(E_cell, true);
+ // -----------
+ // Mark the scenes state as up to date.
+ _scenes_was_cleaned_up = forced_cleanup;
+}
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
+void TileMapLayer::_scenes_clear_cell(CellData &r_cell_data) {
+ // Cleanup existing scene.
+ Node *node = tile_map_node->get_node_or_null(r_cell_data.scene);
+ if (node) {
+ node->queue_free();
+ }
+ r_cell_data.scene = "";
+}
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
+void TileMapLayer::_scenes_update_cell(CellData &r_cell_data) {
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
- if (scenes_collection_source) {
- Ref<PackedScene> packed_scene = scenes_collection_source->get_scene_tile_scene(c.alternative_tile);
- if (packed_scene.is_valid()) {
- Node *scene = packed_scene->instantiate();
- Control *scene_as_control = Object::cast_to<Control>(scene);
- Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene);
- if (scene_as_control) {
- scene_as_control->set_position(tile_map_node->map_to_local(E_cell) + scene_as_control->get_position());
- } else if (scene_as_node2d) {
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(E_cell));
- scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
- }
- tile_map_node->add_child(scene);
- q.scenes[E_cell] = scene->get_name();
- }
- }
- }
- }
+ // Clear the scene in any case.
+ _scenes_clear_cell(r_cell_data);
- q_list_element = q_list_element->next();
- }
-}
+ // Create the scene.
+ const TileMapCell &c = r_cell_data.cell;
+
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
-void TileMapLayer::_scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
- // Clear the scenes if instance cache was cleared.
- if (instantiated_scenes.is_empty()) {
- for (const KeyValue<Vector2i, String> &E : p_quadrant->scenes) {
- Node *node = tile_map_node->get_node_or_null(E.value);
- if (node) {
- node->queue_free();
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
+ TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
+ if (scenes_collection_source) {
+ Ref<PackedScene> packed_scene = scenes_collection_source->get_scene_tile_scene(c.alternative_tile);
+ if (packed_scene.is_valid()) {
+ Node *scene = packed_scene->instantiate();
+ Control *scene_as_control = Object::cast_to<Control>(scene);
+ Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene);
+ if (scene_as_control) {
+ scene_as_control->set_position(tile_map_node->map_to_local(r_cell_data.coords) + scene_as_control->get_position());
+ } else if (scene_as_node2d) {
+ Transform2D xform;
+ xform.set_origin(tile_map_node->map_to_local(r_cell_data.coords));
+ scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
+ }
+ tile_map_node->add_child(scene);
+ r_cell_data.scene = scene->get_name();
+ }
}
}
- p_quadrant->scenes.clear();
}
}
-void TileMapLayer::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
+#ifdef DEBUG_ENABLED
+void TileMapLayer::_scenes_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data) {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
ERR_FAIL_COND(!tile_set.is_valid());
@@ -843,85 +1207,115 @@ void TileMapLayer::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder for scenes needing one.
RenderingServer *rs = RenderingServer::get_singleton();
- Vector2 quadrant_pos = tile_map_node->map_to_local(p_quadrant->coords * get_effective_quadrant_size());
- for (const Vector2i &E_cell : p_quadrant->cells) {
- const TileMapCell &c = get_cell(E_cell, true);
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
+ const TileMapCell &c = r_cell_data.cell;
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
- TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
- if (scenes_collection_source) {
- if (!scenes_collection_source->get_scene_tile_scene(c.alternative_tile).is_valid() || scenes_collection_source->get_scene_tile_display_placeholder(c.alternative_tile)) {
- // Generate a random color from the hashed values of the tiles.
- Array to_hash;
- to_hash.push_back(c.source_id);
- to_hash.push_back(c.alternative_tile);
- uint32_t hash = RandomPCG(to_hash.hash()).rand();
-
- Color color;
- color = color.from_hsv(
- (float)((hash >> 24) & 0xFF) / 256.0,
- Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
- Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
- 0.8);
+ if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
+ return;
+ }
- // Draw a placeholder tile.
- Transform2D cell_to_quadrant;
- cell_to_quadrant.set_origin(tile_map_node->map_to_local(E_cell) - quadrant_pos);
- rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, cell_to_quadrant);
- rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
- }
+ TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
+ if (scenes_collection_source) {
+ if (!scenes_collection_source->get_scene_tile_scene(c.alternative_tile).is_valid() || scenes_collection_source->get_scene_tile_display_placeholder(c.alternative_tile)) {
+ // Generate a random color from the hashed values of the tiles.
+ Array to_hash;
+ to_hash.push_back(c.source_id);
+ to_hash.push_back(c.alternative_tile);
+ uint32_t hash = RandomPCG(to_hash.hash()).rand();
+
+ Color color;
+ color = color.from_hsv(
+ (float)((hash >> 24) & 0xFF) / 256.0,
+ Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
+ Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
+ 0.8);
+
+ // Draw a placeholder tile.
+ Transform2D cell_to_quadrant;
+ cell_to_quadrant.set_origin(tile_map_node->map_to_local(r_cell_data.coords) - p_quadrant_pos);
+ rs->canvas_item_add_set_transform(p_canvas_item, cell_to_quadrant);
+ rs->canvas_item_add_circle(p_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
}
}
}
}
+#endif // DEBUG_ENABLED
/////////////////////////////////////////////////////////////////////
-void TileMapLayer::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) {
- if (!tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) || !tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update)) {
- return;
+void TileMapLayer::_build_runtime_update_tile_data() {
+ const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
+
+ // Check if we should cleanup everything.
+ bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree();
+ if (!forced_cleanup) {
+ if (tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) && tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update)) {
+ if (_runtime_update_tile_data_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_MAP_TILE_SET]) {
+ for (KeyValue<Vector2i, CellData> &E : tile_map) {
+ _build_runtime_update_tile_data_for_cell(E.value);
+ }
+ } else if (dirty.flags[DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE]) {
+ for (KeyValue<Vector2i, CellData> &E : tile_map) {
+ _build_runtime_update_tile_data_for_cell(E.value, true);
+ }
+ } else {
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ _build_runtime_update_tile_data_for_cell(cell_data);
+ }
+ }
+ }
}
+ // -----------
+ // Mark the navigation state as up to date.
+ _runtime_update_tile_data_was_cleaned_up = forced_cleanup;
+}
+
+void TileMapLayer::_build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_auto_add_to_dirty_list) {
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
- SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first();
- while (q_list_element) {
- TileMapQuadrant &q = *q_list_element->self();
- // Iterate over the cells of the quadrant.
- for (const KeyValue<Vector2, Vector2i> &E_cell : q.local_to_map) {
- TileMapCell c = get_cell(E_cell.value, true);
-
- TileSetSource *source;
- if (tile_set->has_source(c.source_id)) {
- source = *tile_set->get_source(c.source_id);
-
- if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
- continue;
- }
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
- bool ret = false;
- if (tile_map_node->GDVIRTUAL_CALL(_use_tile_data_runtime_update, layer_index_in_tile_map_node, E_cell.value, ret) && ret) {
- TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+ TileMapCell &c = r_cell_data.cell;
+ TileSetSource *source;
+ if (tile_set->has_source(c.source_id)) {
+ source = *tile_set->get_source(c.source_id);
- // Create the runtime TileData.
- TileData *tile_data_runtime_use = tile_data->duplicate();
- tile_data_runtime_use->set_allow_transform(true);
- q.runtime_tile_data_cache[E_cell.value] = tile_data_runtime_use;
+ if (source->has_tile(c.get_atlas_coords()) && source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) {
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ bool ret = false;
+ if (tile_map_node->GDVIRTUAL_CALL(_use_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, ret) && ret) {
+ TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+
+ // Create the runtime TileData.
+ TileData *tile_data_runtime_use = tile_data->duplicate();
+ tile_data_runtime_use->set_allow_transform(true);
+ r_cell_data.runtime_tile_data_cache = tile_data_runtime_use;
- tile_map_node->GDVIRTUAL_CALL(_tile_data_runtime_update, layer_index_in_tile_map_node, E_cell.value, tile_data_runtime_use);
+ tile_map_node->GDVIRTUAL_CALL(_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, tile_data_runtime_use);
+
+ if (p_auto_add_to_dirty_list) {
+ dirty.cell_list.add(&r_cell_data.dirty_list_element);
}
}
}
}
- q_list_element = q_list_element->next();
+ }
+}
+
+void TileMapLayer::_clear_runtime_update_tile_data() {
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+
+ // Clear the runtime tile data.
+ if (cell_data.runtime_tile_data_cache) {
+ memdelete(cell_data.runtime_tile_data_cache);
+ cell_data.runtime_tile_data_cache = nullptr;
+ }
}
}
@@ -1100,7 +1494,12 @@ void TileMapLayer::set_tile_map(TileMap *p_tile_map) {
}
void TileMapLayer::set_layer_index_in_tile_map_node(int p_index) {
+ if (p_index == layer_index_in_tile_map_node) {
+ return;
+ }
layer_index_in_tile_map_node = p_index;
+ dirty.flags[DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE] = true;
+ tile_map_node->queue_internal_update();
}
Rect2 TileMapLayer::get_rect(bool &r_changed) const {
@@ -1111,12 +1510,10 @@ Rect2 TileMapLayer::get_rect(bool &r_changed) const {
if (rect_cache_dirty) {
Rect2 r_total;
bool first = true;
- for (const KeyValue<Vector2i, TileMapQuadrant> &E : quadrant_map) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
Rect2 r;
- r.position = tile_map_node->map_to_local(E.key * get_effective_quadrant_size());
- r.expand_to(tile_map_node->map_to_local((E.key + Vector2i(1, 0)) * get_effective_quadrant_size()));
- r.expand_to(tile_map_node->map_to_local((E.key + Vector2i(1, 1)) * get_effective_quadrant_size()));
- r.expand_to(tile_map_node->map_to_local((E.key + Vector2i(0, 1)) * get_effective_quadrant_size()));
+ r.position = tile_map_node->map_to_local(E.key);
+ r.size = Size2();
if (first) {
r_total = r;
first = false;
@@ -1419,7 +1816,7 @@ TileMapCell TileMapLayer::get_cell(const Vector2i &p_coords, bool p_use_proxies)
if (!tile_map.has(p_coords)) {
return TileMapCell();
} else {
- TileMapCell c = tile_map.find(p_coords)->value;
+ TileMapCell c = tile_map.find(p_coords)->value.cell;
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
if (p_use_proxies && tile_set.is_valid()) {
Array proxyed = tile_set->map_tile_proxy(c.source_id, c.get_atlas_coords(), c.alternative_tile);
@@ -1436,7 +1833,7 @@ int TileMapLayer::get_effective_quadrant_size() const {
if (tile_map_node->is_y_sort_enabled() && is_y_sort_enabled()) {
return 1;
} else {
- return tile_map_node->get_quadrant_size();
+ return tile_map_node->get_rendering_quadrant_size();
}
}
@@ -1531,285 +1928,70 @@ Vector<int> TileMapLayer::get_tile_data() const {
// Save in highest format.
int idx = 0;
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
uint8_t *ptr = (uint8_t *)&w[idx];
encode_uint16((int16_t)(E.key.x), &ptr[0]);
encode_uint16((int16_t)(E.key.y), &ptr[2]);
- encode_uint16(E.value.source_id, &ptr[4]);
- encode_uint16(E.value.coord_x, &ptr[6]);
- encode_uint16(E.value.coord_y, &ptr[8]);
- encode_uint16(E.value.alternative_tile, &ptr[10]);
+ encode_uint16(E.value.cell.source_id, &ptr[4]);
+ encode_uint16(E.value.cell.coord_x, &ptr[6]);
+ encode_uint16(E.value.cell.coord_y, &ptr[8]);
+ encode_uint16(E.value.cell.alternative_tile, &ptr[10]);
idx += 3;
}
return tile_data;
}
-void TileMapLayer::clear_instantiated_scenes() {
- instantiated_scenes.clear();
-}
-
-void TileMapLayer::clear_internals() {
- // Clear quadrants.
- clear_instantiated_scenes();
- while (quadrant_map.size()) {
- _erase_quadrant(quadrant_map.begin());
- }
-
- // Clear the layers internals.
- _rendering_cleanup();
-
- // Clear the layers internal navigation maps.
- _navigation_cleanup();
-
- // Clear the dirty quadrants list.
- while (dirty_quadrant_list.first()) {
- dirty_quadrant_list.remove(dirty_quadrant_list.first());
- }
+void TileMapLayer::notify_tile_map_change(DirtyFlags p_what) {
+ dirty.flags[p_what] = true;
+ tile_map_node->queue_internal_update();
+ _physics_notify_tilemap_change(p_what);
}
-void TileMapLayer::recreate_internals() {
- // Make sure that _clear_internals() was called prior.
- ERR_FAIL_COND_MSG(quadrant_map.size() > 0, "TileMap layer had a non-empty quadrant map.");
-
- if (!enabled) {
- return;
- }
+void TileMapLayer::internal_update() {
+ // Find TileData that need a runtime modification.
+ // This may add cells to the dirty list is a runtime modification has been notified.
+ _build_runtime_update_tile_data();
- // Update the layer internals.
+ // Update all subsystems.
_rendering_update();
-
- // Update the layer internal navigation maps.
+ _physics_update();
_navigation_update();
+ _scenes_update();
+#ifdef DEBUG_ENABLED
+ _debug_update();
+#endif // DEBUG_ENABLED
- // Recreate the quadrants.
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
- Vector2i qk = _coords_to_quadrant_coords(Vector2i(E.key.x, E.key.y));
-
- HashMap<Vector2i, TileMapQuadrant>::Iterator Q = quadrant_map.find(qk);
- if (!Q) {
- Q = _create_quadrant(qk);
- dirty_quadrant_list.add(&Q->value.dirty_list_element);
- }
-
- Vector2i pk = E.key;
- Q->value.cells.insert(pk);
-
- _make_quadrant_dirty(Q);
- }
-
- tile_map_node->queue_update_dirty_quadrants();
-}
-
-void TileMapLayer::notify_canvas_entered() {
- // Rendering.
- bool node_visible = tile_map_node->is_visible_in_tree();
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : quadrant_map) {
- TileMapQuadrant &q = E_quadrant.value;
- for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(kv.key));
- RS::get_singleton()->canvas_light_occluder_attach_to_canvas(kv.value, tile_map_node->get_canvas());
- RS::get_singleton()->canvas_light_occluder_set_transform(kv.value, tile_map_node->get_global_transform() * xform);
- RS::get_singleton()->canvas_light_occluder_set_enabled(kv.value, node_visible);
- }
- }
-}
-
-void TileMapLayer::notify_visibility_changed() {
- bool node_visible = tile_map_node->is_visible_in_tree();
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : quadrant_map) {
- TileMapQuadrant &q = E_quadrant.value;
-
- // Update occluders transform.
- for (const KeyValue<Vector2, Vector2i> &E_cell : q.local_to_map) {
- Transform2D xform;
- xform.set_origin(E_cell.key);
- for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
- RS::get_singleton()->canvas_light_occluder_set_enabled(kv.value, node_visible);
- }
- }
- }
-}
-
-void TileMapLayer::notify_xform_changed() {
- if (!tile_map_node->is_inside_tree()) {
- return;
- }
-
- bool in_editor = false;
-#ifdef TOOLS_ENABLED
- in_editor = Engine::get_singleton()->is_editor_hint();
-#endif
-
- Transform2D tilemap_xform = tile_map_node->get_global_transform();
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : quadrant_map) {
- TileMapQuadrant &q = E_quadrant.value;
-
- // Update occluders transform.
- for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(kv.key));
- RenderingServer::get_singleton()->canvas_light_occluder_set_transform(kv.value, tilemap_xform * xform);
- }
-
- // Update navigation regions transform.
- for (const KeyValue<Vector2i, Vector<RID>> &E_region : q.navigation_regions) {
- for (const RID &region : E_region.value) {
- if (!region.is_valid()) {
- continue;
- }
- Transform2D tile_transform;
- tile_transform.set_origin(tile_map_node->map_to_local(E_region.key));
- NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform);
- }
- }
-
- // Physics.
- if (!tile_map_node->is_collision_animatable() || in_editor) {
- for (RID body : q.bodies) {
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(bodies_coords[body]));
- xform = tilemap_xform * xform;
- PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
- }
- }
- }
-}
-
-void TileMapLayer::notify_local_xform_changed() {
- if (!tile_map_node->is_inside_tree()) {
- return;
- }
-
- bool in_editor = false;
-#ifdef TOOLS_ENABLED
- in_editor = Engine::get_singleton()->is_editor_hint();
-#endif
- if (!tile_map_node->is_collision_animatable() || in_editor) {
- Transform2D gl_transform = tile_map_node->get_global_transform();
- for (KeyValue<Vector2i, TileMapQuadrant> &E : quadrant_map) {
- TileMapQuadrant &q = E.value;
-
- for (RID body : q.bodies) {
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(bodies_coords[body]));
- xform = gl_transform * xform;
- PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
- }
- }
- }
-}
-
-void TileMapLayer::notify_canvas_exited() {
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : quadrant_map) {
- TileMapQuadrant &q = E_quadrant.value;
- for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
- RS::get_singleton()->canvas_light_occluder_attach_to_canvas(kv.value, RID());
- }
- }
-}
-
-void TileMapLayer::notify_selected_layer_changed() {
- _rendering_update();
-}
-
-void TileMapLayer::notify_light_mask_changed() {
- for (const KeyValue<Vector2i, TileMapQuadrant> &E : quadrant_map) {
- for (const RID &ci : E.value.canvas_items) {
- RenderingServer::get_singleton()->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
- }
- }
- _rendering_update();
-}
-
-void TileMapLayer::notify_material_changed() {
- for (KeyValue<Vector2i, TileMapQuadrant> &E : quadrant_map) {
- TileMapQuadrant &q = E.value;
- for (const RID &ci : q.canvas_items) {
- RS::get_singleton()->canvas_item_set_use_parent_material(ci, tile_map_node->get_use_parent_material() || tile_map_node->get_material().is_valid());
- }
- }
- _rendering_update();
-}
-
-void TileMapLayer::notify_use_parent_material_changed() {
- notify_material_changed();
-}
-
-void TileMapLayer::notify_texture_filter_changed() {
- for (HashMap<Vector2i, TileMapQuadrant>::Iterator F = quadrant_map.begin(); F; ++F) {
- TileMapQuadrant &q = F->value;
- for (const RID &ci : q.canvas_items) {
- RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(tile_map_node->get_texture_filter_in_tree()));
- _make_quadrant_dirty(F);
- }
- }
- _rendering_update();
-}
+ _clear_runtime_update_tile_data();
-void TileMapLayer::notify_texture_repeat_changed() {
- for (HashMap<Vector2i, TileMapQuadrant>::Iterator F = quadrant_map.begin(); F; ++F) {
- TileMapQuadrant &q = F->value;
- for (const RID &ci : q.canvas_items) {
- RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(tile_map_node->get_texture_repeat_in_tree()));
- _make_quadrant_dirty(F);
- }
+ // Clear the "what is dirty" flags.
+ for (int i = 0; i < DIRTY_FLAGS_MAX; i++) {
+ dirty.flags[i] = false;
}
- _rendering_update();
-}
-void TileMapLayer::update_dirty_quadrants() {
- // Update the coords cache.
- for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
- q->self()->map_to_local.clear();
- q->self()->local_to_map.clear();
- for (const Vector2i &E : q->self()->cells) {
- Vector2i pk = E;
- Vector2 pk_local_coords = tile_map_node->map_to_local(pk);
- q->self()->map_to_local[pk] = pk_local_coords;
- q->self()->local_to_map[pk_local_coords] = pk;
+ // List the cells to delete definitely.
+ Vector<Vector2i> to_delete;
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &cell_data = *cell_data_list_element->self();
+ // Select the the cell from tile_map if it is invalid.
+ if (cell_data.cell.source_id == TileSet::INVALID_SOURCE) {
+ to_delete.push_back(cell_data.coords);
}
}
- // Find TileData that need a runtime modification.
- _build_runtime_update_tile_data(dirty_quadrant_list);
-
- // Call the update_dirty_quadrant method on plugins.
- _rendering_update_dirty_quadrants(dirty_quadrant_list);
- _physics_update_dirty_quadrants(dirty_quadrant_list);
- _navigation_update_dirty_quadrants(dirty_quadrant_list);
- _scenes_update_dirty_quadrants(dirty_quadrant_list);
-
- // Redraw the debug canvas_items.
- RenderingServer *rs = RenderingServer::get_singleton();
- for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
- rs->canvas_item_clear(q->self()->debug_canvas_item);
- Transform2D xform;
- xform.set_origin(tile_map_node->map_to_local(q->self()->coords * get_effective_quadrant_size()));
- rs->canvas_item_set_transform(q->self()->debug_canvas_item, xform);
-
- _rendering_draw_quadrant_debug(q->self());
- _physics_draw_quadrant_debug(q->self());
- _navigation_draw_quadrant_debug(q->self());
- _scenes_draw_quadrant_debug(q->self());
+ // Remove cells that are empty after the cleanup.
+ for (const Vector2i &coords : to_delete) {
+ tile_map.erase(coords);
}
- // Clear the list.
- while (dirty_quadrant_list.first()) {
- // Clear the runtime tile data.
- for (const KeyValue<Vector2i, TileData *> &kv : dirty_quadrant_list.first()->self()->runtime_tile_data_cache) {
- memdelete(kv.value);
- }
-
- dirty_quadrant_list.remove(dirty_quadrant_list.first());
- }
+ // Clear the dirty cells list.
+ dirty.cell_list.clear();
}
void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
// Set the current cell tile (using integer position).
Vector2i pk(p_coords);
- HashMap<Vector2i, TileMapCell>::Iterator E = tile_map.find(pk);
+ HashMap<Vector2i, CellData>::Iterator E = tile_map.find(pk);
int source_id = p_source_id;
Vector2i atlas_coords = p_atlas_coords;
@@ -1822,73 +2004,33 @@ void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vec
alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
}
- if (!E && source_id == TileSet::INVALID_SOURCE) {
- return; // Nothing to do, the tile is already empty.
- }
-
- // Get the quadrant
- Vector2i qk = _coords_to_quadrant_coords(pk);
-
- HashMap<Vector2i, TileMapQuadrant>::Iterator Q = quadrant_map.find(qk);
-
- if (source_id == TileSet::INVALID_SOURCE) {
- // Erase existing cell in the tile map.
- tile_map.erase(pk);
-
- // Erase existing cell in the quadrant.
- ERR_FAIL_COND(!Q);
- TileMapQuadrant &q = Q->value;
-
- // Find node in scenes and remove it.
- HashMap<Vector2i, String>::Iterator entry = q.scenes.find(pk);
- if (entry != q.scenes.end()) {
- String scene_name = entry->value;
- Node *scene = tile_map_node->get_node_or_null(scene_name);
- if (scene) {
- scene->queue_free();
- instantiated_scenes.erase(Vector2i(pk.x, pk.y));
- }
- }
-
- q.cells.erase(pk);
-
- // Remove or make the quadrant dirty.
- if (q.cells.size() == 0) {
- _erase_quadrant(Q);
- } else {
- _make_quadrant_dirty(Q);
+ if (!E) {
+ if (source_id == TileSet::INVALID_SOURCE) {
+ return; // Nothing to do, the tile is already empty.
}
- used_rect_cache_dirty = true;
+ // Insert a new cell in the tile map.
+ CellData new_cell_data;
+ new_cell_data.coords = pk;
+ E = tile_map.insert(pk, new_cell_data);
} else {
- if (!E) {
- // Insert a new cell in the tile map.
- E = tile_map.insert(pk, TileMapCell());
-
- // Create a new quadrant if needed, then insert the cell if needed.
- if (!Q) {
- Q = _create_quadrant(qk);
- }
- TileMapQuadrant &q = Q->value;
- q.cells.insert(pk);
-
- } else {
- ERR_FAIL_COND(!Q); // TileMapQuadrant should exist...
-
- if (E->value.source_id == source_id && E->value.get_atlas_coords() == atlas_coords && E->value.alternative_tile == alternative_tile) {
- return; // Nothing changed.
- }
+ if (E->value.cell.source_id == source_id && E->value.cell.get_atlas_coords() == atlas_coords && E->value.cell.alternative_tile == alternative_tile) {
+ return; // Nothing changed.
}
+ }
- TileMapCell &c = E->value;
-
- c.source_id = source_id;
- c.set_atlas_coords(atlas_coords);
- c.alternative_tile = alternative_tile;
+ TileMapCell &c = E->value.cell;
+ c.source_id = source_id;
+ c.set_atlas_coords(atlas_coords);
+ c.alternative_tile = alternative_tile;
- _make_quadrant_dirty(Q);
- used_rect_cache_dirty = true;
+ // Make the given cell dirty.
+ if (!E->value.dirty_list_element.in_list()) {
+ dirty.cell_list.add(&(E->value.dirty_list_element));
}
+ tile_map_node->queue_internal_update();
+
+ used_rect_cache_dirty = true;
}
void TileMapLayer::erase_cell(const Vector2i &p_coords) {
@@ -1897,7 +2039,7 @@ void TileMapLayer::erase_cell(const Vector2i &p_coords) {
int TileMapLayer::get_cell_source_id(const Vector2i &p_coords, bool p_use_proxies) const {
// Get a cell source id from position.
- HashMap<Vector2i, TileMapCell>::ConstIterator E = tile_map.find(p_coords);
+ HashMap<Vector2i, CellData>::ConstIterator E = tile_map.find(p_coords);
if (!E) {
return TileSet::INVALID_SOURCE;
@@ -1905,16 +2047,16 @@ int TileMapLayer::get_cell_source_id(const Vector2i &p_coords, bool p_use_proxie
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
if (p_use_proxies && tile_set.is_valid()) {
- Array proxyed = tile_set->map_tile_proxy(E->value.source_id, E->value.get_atlas_coords(), E->value.alternative_tile);
+ Array proxyed = tile_set->map_tile_proxy(E->value.cell.source_id, E->value.cell.get_atlas_coords(), E->value.cell.alternative_tile);
return proxyed[0];
}
- return E->value.source_id;
+ return E->value.cell.source_id;
}
Vector2i TileMapLayer::get_cell_atlas_coords(const Vector2i &p_coords, bool p_use_proxies) const {
// Get a cell source id from position.
- HashMap<Vector2i, TileMapCell>::ConstIterator E = tile_map.find(p_coords);
+ HashMap<Vector2i, CellData>::ConstIterator E = tile_map.find(p_coords);
if (!E) {
return TileSetSource::INVALID_ATLAS_COORDS;
@@ -1922,16 +2064,16 @@ Vector2i TileMapLayer::get_cell_atlas_coords(const Vector2i &p_coords, bool p_us
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
if (p_use_proxies && tile_set.is_valid()) {
- Array proxyed = tile_set->map_tile_proxy(E->value.source_id, E->value.get_atlas_coords(), E->value.alternative_tile);
+ Array proxyed = tile_set->map_tile_proxy(E->value.cell.source_id, E->value.cell.get_atlas_coords(), E->value.cell.alternative_tile);
return proxyed[1];
}
- return E->value.get_atlas_coords();
+ return E->value.cell.get_atlas_coords();
}
int TileMapLayer::get_cell_alternative_tile(const Vector2i &p_coords, bool p_use_proxies) const {
// Get a cell source id from position.
- HashMap<Vector2i, TileMapCell>::ConstIterator E = tile_map.find(p_coords);
+ HashMap<Vector2i, CellData>::ConstIterator E = tile_map.find(p_coords);
if (!E) {
return TileSetSource::INVALID_TILE_ALTERNATIVE;
@@ -1939,11 +2081,11 @@ int TileMapLayer::get_cell_alternative_tile(const Vector2i &p_coords, bool p_use
const Ref<TileSet> &tile_set = tile_map_node->get_tileset();
if (p_use_proxies && tile_set.is_valid()) {
- Array proxyed = tile_set->map_tile_proxy(E->value.source_id, E->value.get_atlas_coords(), E->value.alternative_tile);
+ Array proxyed = tile_set->map_tile_proxy(E->value.cell.source_id, E->value.cell.get_atlas_coords(), E->value.cell.alternative_tile);
return proxyed[2];
}
- return E->value.alternative_tile;
+ return E->value.cell.alternative_tile;
}
TileData *TileMapLayer::get_cell_tile_data(const Vector2i &p_coords, bool p_use_proxies) const {
@@ -1963,10 +2105,9 @@ TileData *TileMapLayer::get_cell_tile_data(const Vector2i &p_coords, bool p_use_
void TileMapLayer::clear() {
// Remove all tiles.
- clear_instantiated_scenes();
- clear_internals();
- tile_map.clear();
- recreate_internals();
+ for (KeyValue<Vector2i, CellData> &kv : tile_map) {
+ erase_cell(kv.key);
+ }
used_rect_cache_dirty = true;
}
@@ -2122,7 +2263,7 @@ TypedArray<Vector2i> TileMapLayer::get_used_cells() const {
TypedArray<Vector2i> a;
a.resize(tile_map.size());
int i = 0;
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
Vector2i p(E.key.x, E.key.y);
a[i++] = p;
}
@@ -2133,10 +2274,10 @@ TypedArray<Vector2i> TileMapLayer::get_used_cells() const {
TypedArray<Vector2i> TileMapLayer::get_used_cells_by_id(int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) const {
// Returns the cells used in the tilemap.
TypedArray<Vector2i> a;
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
- if ((p_source_id == TileSet::INVALID_SOURCE || p_source_id == E.value.source_id) &&
- (p_atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || p_atlas_coords == E.value.get_atlas_coords()) &&
- (p_alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE || p_alternative_tile == E.value.alternative_tile)) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
+ if ((p_source_id == TileSet::INVALID_SOURCE || p_source_id == E.value.cell.source_id) &&
+ (p_atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || p_atlas_coords == E.value.cell.get_atlas_coords()) &&
+ (p_alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE || p_alternative_tile == E.value.cell.alternative_tile)) {
a.push_back(E.key);
}
}
@@ -2156,7 +2297,7 @@ Rect2i TileMapLayer::get_used_rect() const {
first = false;
}
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
used_rect_cache.expand_to(Vector2i(E.key.x, E.key.y));
}
}
@@ -2187,8 +2328,8 @@ void TileMapLayer::set_enabled(bool p_enabled) {
return;
}
enabled = p_enabled;
- clear_internals();
- recreate_internals();
+ dirty.flags[DIRTY_FLAGS_LAYER_ENABLED] = true;
+ tile_map_node->queue_internal_update();
tile_map_node->emit_signal(CoreStringNames::get_singleton()->changed);
tile_map_node->update_configuration_warnings();
@@ -2203,7 +2344,8 @@ void TileMapLayer::set_modulate(Color p_modulate) {
return;
}
modulate = p_modulate;
- _rendering_update();
+ dirty.flags[DIRTY_FLAGS_LAYER_MODULATE] = true;
+ tile_map_node->queue_internal_update();
tile_map_node->emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -2216,8 +2358,8 @@ void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) {
return;
}
y_sort_enabled = p_y_sort_enabled;
- clear_internals();
- recreate_internals();
+ dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] = true;
+ tile_map_node->queue_internal_update();
tile_map_node->emit_signal(CoreStringNames::get_singleton()->changed);
tile_map_node->update_configuration_warnings();
@@ -2232,8 +2374,8 @@ void TileMapLayer::set_y_sort_origin(int p_y_sort_origin) {
return;
}
y_sort_origin = p_y_sort_origin;
- clear_internals();
- recreate_internals();
+ dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] = true;
+ tile_map_node->queue_internal_update();
tile_map_node->emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -2246,7 +2388,8 @@ void TileMapLayer::set_z_index(int p_z_index) {
return;
}
z_index = p_z_index;
- _rendering_update();
+ dirty.flags[DIRTY_FLAGS_LAYER_Z_INDEX] = true;
+ tile_map_node->queue_internal_update();
tile_map_node->emit_signal(CoreStringNames::get_singleton()->changed);
tile_map_node->update_configuration_warnings();
@@ -2269,19 +2412,14 @@ RID TileMapLayer::get_navigation_map() const {
return RID();
}
-void TileMapLayer::force_update() {
- clear_internals();
- recreate_internals();
-}
-
void TileMapLayer::fix_invalid_tiles() {
Ref<TileSet> tileset = tile_map_node->get_tileset();
ERR_FAIL_COND_MSG(tileset.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet.");
RBSet<Vector2i> coords;
- for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
- TileSetSource *source = *tileset->get_source(E.value.source_id);
- if (!source || !source->has_tile(E.value.get_atlas_coords()) || !source->has_alternative_tile(E.value.get_atlas_coords(), E.value.alternative_tile)) {
+ for (const KeyValue<Vector2i, CellData> &E : tile_map) {
+ TileSetSource *source = *tileset->get_source(E.value.cell.source_id);
+ if (!source || !source->has_tile(E.value.cell.get_atlas_coords()) || !source->has_alternative_tile(E.value.cell.get_atlas_coords(), E.value.cell.alternative_tile)) {
coords.insert(E.key);
}
}
@@ -2298,6 +2436,12 @@ Vector2i TileMapLayer::get_coords_for_body_rid(RID p_physics_body) const {
return bodies_coords[p_physics_body];
}
+TileMapLayer::~TileMapLayer() {
+ in_destructor = true;
+ clear();
+ internal_update();
+}
+
HashMap<Vector2i, TileSet::CellNeighbor> TerrainConstraint::get_overlapping_coords_and_peering_bits() const {
HashMap<Vector2i, TileSet::CellNeighbor> output;
@@ -2743,12 +2887,15 @@ Vector2i TileMap::transform_coords_layout(const Vector2i &p_coords, TileSet::Til
void TileMap::set_selected_layer(int p_layer_id) {
ERR_FAIL_COND(p_layer_id < -1 || p_layer_id >= (int)layers.size());
+ if (selected_layer == p_layer_id) {
+ return;
+ }
selected_layer = p_layer_id;
emit_signal(CoreStringNames::get_singleton()->changed);
// Update the layers modulation.
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_selected_layer_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_SELECTED_LAYER);
}
}
@@ -2759,114 +2906,114 @@ int TileMap::get_selected_layer() const {
void TileMap::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- _clear_internals();
- _recreate_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_TREE);
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
- _clear_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_TREE);
+ }
} break;
- }
- // Transfers the notification to tileset plugins.
- if (tile_set.is_valid()) {
- switch (p_what) {
- case TileMap::NOTIFICATION_ENTER_CANVAS: {
- for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_canvas_entered();
- }
- } break;
-
- case TileMap::NOTIFICATION_EXIT_CANVAS: {
- for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_canvas_exited();
- }
- } break;
+ case TileMap::NOTIFICATION_ENTER_CANVAS: {
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_CANVAS);
+ }
+ } break;
- case NOTIFICATION_DRAW: {
- // Rendering.
- if (tile_set.is_valid()) {
- RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), is_y_sort_enabled());
- }
- } break;
+ case TileMap::NOTIFICATION_EXIT_CANVAS: {
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_IN_CANVAS);
+ }
+ } break;
- case TileMap::NOTIFICATION_VISIBILITY_CHANGED: {
- for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_visibility_changed();
- }
- } break;
+ case NOTIFICATION_DRAW: {
+ // Rendering.
+ if (tile_set.is_valid()) {
+ RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), is_y_sort_enabled());
+ }
+ } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- // Physics.
- for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_xform_changed();
- }
- } break;
+ case TileMap::NOTIFICATION_VISIBILITY_CHANGED: {
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_VISIBILITY);
+ }
+ } break;
- case TileMap::NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- // Physics.
- bool in_editor = false;
+ case TileMap::NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ // Physics.
+ bool in_editor = false;
#ifdef TOOLS_ENABLED
- in_editor = Engine::get_singleton()->is_editor_hint();
+ in_editor = Engine::get_singleton()->is_editor_hint();
#endif
- if (is_inside_tree() && collision_animatable && !in_editor) {
- // Update transform on the physics tick when in animatable mode.
- last_valid_transform = new_transform;
- set_notify_local_transform(false);
- set_global_transform(new_transform);
- set_notify_local_transform(true);
- }
- } break;
+ if (is_inside_tree() && collision_animatable && !in_editor) {
+ // Update transform on the physics tick when in animatable mode.
+ last_valid_transform = new_transform;
+ set_notify_local_transform(false);
+ set_global_transform(new_transform);
+ set_notify_local_transform(true);
+ }
+ } break;
- case TileMap::NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
- for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_local_xform_changed();
- }
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ // Physics.
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_XFORM);
+ }
+ } break;
- // Physics.
- bool in_editor = false;
+ case TileMap::NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM);
+ }
+
+ // Physics.
+ bool in_editor = false;
#ifdef TOOLS_ENABLED
- in_editor = Engine::get_singleton()->is_editor_hint();
+ in_editor = Engine::get_singleton()->is_editor_hint();
#endif
- // Only active when animatable. Send the new transform to the physics...
- if (is_inside_tree() && !in_editor && collision_animatable) {
- // ... but then revert changes.
- set_notify_local_transform(false);
- set_global_transform(last_valid_transform);
- set_notify_local_transform(true);
- }
- } break;
- }
+ // Only active when animatable. Send the new transform to the physics...
+ if (is_inside_tree() && collision_animatable && !in_editor) {
+ // Store last valid transform.
+ new_transform = get_global_transform();
+
+ // ... but then revert changes.
+ set_notify_local_transform(false);
+ set_global_transform(last_valid_transform);
+ set_notify_local_transform(true);
+ }
+ } break;
}
}
-void TileMap::queue_update_dirty_quadrants() {
- if (pending_update || !is_inside_tree()) {
+#ifndef DISABLE_DEPRECATED
+// Deprecated methods.
+void TileMap::force_update(int p_layer) {
+ notify_runtime_tile_data_update(p_layer);
+ update_internals();
+}
+#endif
+
+void TileMap::queue_internal_update() {
+ if (pending_update) {
return;
}
pending_update = true;
- call_deferred(SNAME("_update_dirty_quadrants"));
+ callable_mp(this, &TileMap::_internal_update).call_deferred();
}
-void TileMap::_update_dirty_quadrants() {
+void TileMap::_internal_update() {
+ // Other updates.
if (!pending_update) {
return;
}
- if (!is_inside_tree() || !tile_set.is_valid()) {
- pending_update = false;
- return;
- }
-
- // Physics:
- Transform2D gl_transform = get_global_transform();
- last_valid_transform = gl_transform;
- new_transform = gl_transform;
-
// Update dirty quadrants on layers.
for (Ref<TileMapLayer> &layer : layers) {
- layer->update_dirty_quadrants();
+ layer->internal_update();
}
pending_update = false;
@@ -2882,16 +3029,14 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
tile_set->disconnect_changed(callable_mp(this, &TileMap::_tile_set_changed));
}
- if (!p_tileset.is_valid()) {
- _clear_internals();
- }
-
tile_set = p_tileset;
if (tile_set.is_valid()) {
tile_set->connect_changed(callable_mp(this, &TileMap::_tile_set_changed));
- _clear_internals();
- _recreate_internals();
+ }
+
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TILE_SET);
}
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -2901,17 +3046,18 @@ Ref<TileSet> TileMap::get_tileset() const {
return tile_set;
}
-void TileMap::set_quadrant_size(int p_size) {
+void TileMap::set_rendering_quadrant_size(int p_size) {
ERR_FAIL_COND_MSG(p_size < 1, "TileMapQuadrant size cannot be smaller than 1.");
- quadrant_size = p_size;
- _clear_internals();
- _recreate_internals();
+ rendering_quadrant_size = p_size;
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE);
+ }
emit_signal(CoreStringNames::get_singleton()->changed);
}
-int TileMap::get_quadrant_size() const {
- return quadrant_size;
+int TileMap::get_rendering_quadrant_size() const {
+ return rendering_quadrant_size;
}
void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_animation_offset) {
@@ -3006,7 +3152,6 @@ void TileMap::add_layer(int p_to_pos) {
ERR_FAIL_INDEX(p_to_pos, (int)layers.size() + 1);
// Must clear before adding the layer.
- _clear_internals();
Ref<TileMapLayer> new_layer;
new_layer.instantiate();
new_layer->set_tile_map(this);
@@ -3014,7 +3159,7 @@ void TileMap::add_layer(int p_to_pos) {
for (unsigned int i = 0; i < layers.size(); i++) {
layers[i]->set_layer_index_in_tile_map_node(i);
}
- _recreate_internals();
+ queue_internal_update();
notify_property_list_changed();
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -3027,14 +3172,13 @@ void TileMap::move_layer(int p_layer, int p_to_pos) {
ERR_FAIL_INDEX(p_to_pos, (int)layers.size() + 1);
// Clear before shuffling layers.
- _clear_internals();
Ref<TileMapLayer> layer = layers[p_layer];
layers.insert(p_to_pos, layer);
layers.remove_at(p_to_pos < p_layer ? p_layer + 1 : p_layer);
for (unsigned int i = 0; i < layers.size(); i++) {
layers[i]->set_layer_index_in_tile_map_node(i);
}
- _recreate_internals();
+ queue_internal_update();
notify_property_list_changed();
if (selected_layer == p_layer) {
@@ -3050,12 +3194,11 @@ void TileMap::remove_layer(int p_layer) {
ERR_FAIL_INDEX(p_layer, (int)layers.size());
// Clear before removing the layer.
- _clear_internals();
layers.remove_at(p_layer);
for (unsigned int i = 0; i < layers.size(); i++) {
layers[i]->set_layer_index_in_tile_map_node(i);
}
- _recreate_internals();
+ queue_internal_update();
notify_property_list_changed();
if (selected_layer >= p_layer) {
@@ -3128,10 +3271,11 @@ void TileMap::set_collision_animatable(bool p_enabled) {
return;
}
collision_animatable = p_enabled;
- _clear_internals();
set_notify_local_transform(p_enabled);
set_physics_process_internal(p_enabled);
- _recreate_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_COLLISION_ANIMATABLE);
+ }
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -3144,8 +3288,9 @@ void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_colli
return;
}
collision_visibility_mode = p_show_collision;
- _clear_internals();
- _recreate_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE);
+ }
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -3158,8 +3303,9 @@ void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navi
return;
}
navigation_visibility_mode = p_show_navigation;
- _clear_internals();
- _recreate_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE);
+ }
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -3172,27 +3318,13 @@ void TileMap::set_y_sort_enabled(bool p_enable) {
return;
}
Node2D::set_y_sort_enabled(p_enable);
- _clear_internals();
- _recreate_internals();
- emit_signal(CoreStringNames::get_singleton()->changed);
- update_configuration_warnings();
-}
-
-void TileMap::_clear_internals() {
- // Clear quadrants.
for (Ref<TileMapLayer> &layer : layers) {
- layer->clear_internals();
- }
-}
-
-void TileMap::_recreate_internals() {
- for (Ref<TileMapLayer> &layer : layers) {
- layer->recreate_internals();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED);
}
+ emit_signal(CoreStringNames::get_singleton()->changed);
+ update_configuration_warnings();
}
-/////////////////////////////// Rendering //////////////////////////////////////
-
void TileMap::set_cell(int p_layer, const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
TILEMAP_CALL_FOR_LAYER(p_layer, set_cell, p_coords, p_source_id, p_atlas_coords, p_alternative_tile);
}
@@ -3315,12 +3447,18 @@ void TileMap::clear() {
}
}
-void TileMap::force_update(int p_layer) {
+void TileMap::update_internals() {
+ pending_update = true;
+ _internal_update();
+}
+
+void TileMap::notify_runtime_tile_data_update(int p_layer) {
if (p_layer >= 0) {
- TILEMAP_CALL_FOR_LAYER(p_layer, force_update);
+ TILEMAP_CALL_FOR_LAYER(p_layer, notify_tile_map_change, TileMapLayer::DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE);
} else {
- _clear_internals();
- _recreate_internals();
+ for (Ref<TileMapLayer> &layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE);
+ }
}
}
@@ -3351,6 +3489,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
format = (TileMapLayer::DataFormat)(p_value.operator int64_t()); // Set format used for loading.
return true;
}
+#ifndef DISABLE_DEPRECATED
} else if (p_name == "tile_data") { // Kept for compatibility reasons.
if (p_value.is_array()) {
if (layers.size() == 0) {
@@ -3365,6 +3504,9 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
return false;
+ } else if (p_name == "rendering_quadrant_size") {
+ set_rendering_quadrant_size(p_value);
+#endif // DISABLE_DEPRECATED
} else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) {
int index = components[0].trim_prefix("layer_").to_int();
if (index < 0) {
@@ -3372,7 +3514,6 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
}
if (index >= (int)layers.size()) {
- _clear_internals();
while (index >= (int)layers.size()) {
Ref<TileMapLayer> new_layer;
new_layer.instantiate();
@@ -3380,7 +3521,6 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
new_layer->set_layer_index_in_tile_map_node(index);
layers.push_back(new_layer);
}
- _recreate_internals();
notify_property_list_changed();
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -4115,7 +4255,7 @@ void TileMap::set_light_mask(int p_light_mask) {
// Occlusion: set light mask.
CanvasItem::set_light_mask(p_light_mask);
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_light_mask_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_LIGHT_MASK);
}
}
@@ -4125,7 +4265,7 @@ void TileMap::set_material(const Ref<Material> &p_material) {
// Update material for the whole tilemap.
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_material_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_MATERIAL);
}
}
@@ -4135,7 +4275,7 @@ void TileMap::set_use_parent_material(bool p_use_parent_material) {
// Update use_parent_material for the whole tilemap.
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_use_parent_material_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL);
}
}
@@ -4143,7 +4283,7 @@ void TileMap::set_texture_filter(TextureFilter p_texture_filter) {
// Set a default texture filter for the whole tilemap.
CanvasItem::set_texture_filter(p_texture_filter);
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_texture_filter_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER);
}
}
@@ -4151,7 +4291,7 @@ void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
// Set a default texture repeat for the whole tilemap.
CanvasItem::set_texture_repeat(p_texture_repeat);
for (Ref<TileMapLayer> &layer : layers) {
- layer->notify_texture_repeat_changed();
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT);
}
}
@@ -4294,11 +4434,17 @@ PackedStringArray TileMap::get_configuration_warnings() const {
}
void TileMap::_bind_methods() {
+#ifndef DISABLE_DEPRECATED
+ ClassDB::bind_method(D_METHOD("set_navigation_map", "layer", "map"), &TileMap::set_layer_navigation_map);
+ ClassDB::bind_method(D_METHOD("get_navigation_map", "layer"), &TileMap::get_layer_navigation_map);
+ ClassDB::bind_method(D_METHOD("force_update", "layer"), &TileMap::force_update, DEFVAL(-1));
+#endif // DISABLE_DEPRECATED
+
ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset);
ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset);
- ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size);
- ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size);
+ ClassDB::bind_method(D_METHOD("set_rendering_quadrant_size", "size"), &TileMap::set_rendering_quadrant_size);
+ ClassDB::bind_method(D_METHOD("get_rendering_quadrant_size"), &TileMap::get_rendering_quadrant_size);
ClassDB::bind_method(D_METHOD("get_layers_count"), &TileMap::get_layers_count);
ClassDB::bind_method(D_METHOD("add_layer", "to_position"), &TileMap::add_layer);
@@ -4319,11 +4465,6 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_layer_navigation_map", "layer", "map"), &TileMap::set_layer_navigation_map);
ClassDB::bind_method(D_METHOD("get_layer_navigation_map", "layer"), &TileMap::get_layer_navigation_map);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("set_navigation_map", "layer", "map"), &TileMap::set_layer_navigation_map);
- ClassDB::bind_method(D_METHOD("get_navigation_map", "layer"), &TileMap::get_layer_navigation_map);
-#endif // DISABLE_DEPRECATED
-
ClassDB::bind_method(D_METHOD("set_collision_animatable", "enabled"), &TileMap::set_collision_animatable);
ClassDB::bind_method(D_METHOD("is_collision_animatable"), &TileMap::is_collision_animatable);
ClassDB::bind_method(D_METHOD("set_collision_visibility_mode", "collision_visibility_mode"), &TileMap::set_collision_visibility_mode);
@@ -4353,7 +4494,8 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_layer", "layer"), &TileMap::clear_layer);
ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
- ClassDB::bind_method(D_METHOD("force_update", "layer"), &TileMap::force_update, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("update_internals"), &TileMap::update_internals);
+ ClassDB::bind_method(D_METHOD("notify_runtime_tile_data_update", "layer"), &TileMap::notify_runtime_tile_data_update, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_surrounding_cells", "coords"), &TileMap::get_surrounding_cells);
@@ -4366,15 +4508,11 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &TileMap::get_neighbor_cell);
- ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants);
-
- ClassDB::bind_method(D_METHOD("_tile_set_changed_deferred_update"), &TileMap::_tile_set_changed_deferred_update);
-
GDVIRTUAL_BIND(_use_tile_data_runtime_update, "layer", "coords");
GDVIRTUAL_BIND(_tile_data_runtime_update, "layer", "coords", "tile_data");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "rendering_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_rendering_quadrant_size", "get_rendering_quadrant_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_animatable"), "set_collision_animatable", "is_collision_animatable");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode");
@@ -4392,22 +4530,12 @@ void TileMap::_bind_methods() {
void TileMap::_tile_set_changed() {
emit_signal(CoreStringNames::get_singleton()->changed);
- _tile_set_changed_deferred_update_needed = true;
- for (Ref<TileMapLayer> &layer : layers) {
- layer->clear_instantiated_scenes();
+ for (Ref<TileMapLayer> layer : layers) {
+ layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TILE_SET);
}
- call_deferred(SNAME("_tile_set_changed_deferred_update"));
update_configuration_warnings();
}
-void TileMap::_tile_set_changed_deferred_update() {
- if (_tile_set_changed_deferred_update_needed) {
- _clear_internals();
- _recreate_internals();
- _tile_set_changed_deferred_update_needed = false;
- }
-}
-
TileMap::TileMap() {
set_notify_transform(true);
set_notify_local_transform(false);
@@ -4423,8 +4551,6 @@ TileMap::~TileMap() {
if (tile_set.is_valid()) {
tile_set->disconnect_changed(callable_mp(this, &TileMap::_tile_set_changed));
}
-
- _clear_internals();
}
#undef TILEMAP_CALL_FOR_LAYER
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 0ad47c51da..7782d7de96 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -89,75 +89,139 @@ public:
TerrainConstraint(){};
};
-struct TileMapQuadrant {
- struct CoordsWorldComparator {
- _ALWAYS_INLINE_ bool operator()(const Vector2 &p_a, const Vector2 &p_b) const {
- // We sort the cells by their local coords, as it is needed by rendering.
- if (p_a.y == p_b.y) {
- return p_a.x > p_b.x;
- } else {
- return p_a.y < p_b.y;
- }
- }
- };
-
- // Dirty list element.
- SelfList<TileMapQuadrant> dirty_list_element;
+#ifdef DEBUG_ENABLED
+class DebugQuadrant;
+#endif // DEBUG_ENABLED
+class RenderingQuadrant;
- // Quadrant coords.
+struct CellData {
Vector2i coords;
-
- // TileMapCells.
- RBSet<Vector2i> cells;
- // We need those two maps to sort by local position for rendering.
- // This is kind of workaround, it would be better to sort the cells directly in the "cells" set instead.
- RBMap<Vector2i, Vector2> map_to_local;
- RBMap<Vector2, Vector2i, CoordsWorldComparator> local_to_map;
+ TileMapCell cell;
// Debug.
- RID debug_canvas_item;
+ SelfList<CellData> debug_quadrant_list_element;
// Rendering.
- List<RID> canvas_items;
- HashMap<Vector2i, RID> occluders;
+ Ref<RenderingQuadrant> rendering_quadrant;
+ SelfList<CellData> rendering_quadrant_list_element;
+ List<RID> occluders;
// Physics.
- List<RID> bodies;
+ LocalVector<RID> bodies;
// Navigation.
- HashMap<Vector2i, Vector<RID>> navigation_regions;
+ LocalVector<RID> navigation_regions;
// Scenes.
- HashMap<Vector2i, String> scenes;
+ String scene;
// Runtime TileData cache.
- HashMap<Vector2i, TileData *> runtime_tile_data_cache;
-
- void operator=(const TileMapQuadrant &q) {
- coords = q.coords;
- debug_canvas_item = q.debug_canvas_item;
- canvas_items = q.canvas_items;
- occluders = q.occluders;
- bodies = q.bodies;
- navigation_regions = q.navigation_regions;
+ TileData *runtime_tile_data_cache = nullptr;
+
+ // List elements.
+ SelfList<CellData> dirty_list_element;
+
+ // For those, copy everything but SelfList elements.
+ void operator=(const CellData &p_other) {
+ coords = p_other.coords;
+ cell = p_other.cell;
+ occluders = p_other.occluders;
+ bodies = p_other.bodies;
+ navigation_regions = p_other.navigation_regions;
+ scene = p_other.scene;
+ runtime_tile_data_cache = p_other.runtime_tile_data_cache;
}
- TileMapQuadrant(const TileMapQuadrant &q) :
+ CellData(const CellData &p_other) :
+ debug_quadrant_list_element(this),
+ rendering_quadrant_list_element(this),
dirty_list_element(this) {
- coords = q.coords;
- debug_canvas_item = q.debug_canvas_item;
- canvas_items = q.canvas_items;
- occluders = q.occluders;
- bodies = q.bodies;
- navigation_regions = q.navigation_regions;
+ coords = p_other.coords;
+ cell = p_other.cell;
+ occluders = p_other.occluders;
+ bodies = p_other.bodies;
+ navigation_regions = p_other.navigation_regions;
+ scene = p_other.scene;
+ runtime_tile_data_cache = p_other.runtime_tile_data_cache;
}
- TileMapQuadrant() :
+ CellData() :
+ debug_quadrant_list_element(this),
+ rendering_quadrant_list_element(this),
dirty_list_element(this) {
}
};
+#ifdef DEBUG_ENABLED
+class DebugQuadrant : public RefCounted {
+ GDCLASS(DebugQuadrant, RefCounted);
+
+public:
+ Vector2i quadrant_coords;
+ SelfList<CellData>::List cells;
+ RID canvas_item;
+
+ SelfList<DebugQuadrant> dirty_quadrant_list_element;
+
+ // For those, copy everything but SelfList elements.
+ DebugQuadrant(const DebugQuadrant &p_other) :
+ dirty_quadrant_list_element(this) {
+ quadrant_coords = p_other.quadrant_coords;
+ cells = p_other.cells;
+ canvas_item = p_other.canvas_item;
+ }
+
+ DebugQuadrant() :
+ dirty_quadrant_list_element(this) {
+ }
+
+ ~DebugQuadrant() {
+ cells.clear();
+ }
+};
+#endif // DEBUG_ENABLED
+
+class RenderingQuadrant : public RefCounted {
+ GDCLASS(RenderingQuadrant, RefCounted);
+
+public:
+ struct CoordsWorldComparator {
+ _ALWAYS_INLINE_ bool operator()(const Vector2 &p_a, const Vector2 &p_b) const {
+ // We sort the cells by their local coords, as it is needed by rendering.
+ if (p_a.y == p_b.y) {
+ return p_a.x > p_b.x;
+ } else {
+ return p_a.y < p_b.y;
+ }
+ }
+ };
+
+ Vector2i quadrant_coords;
+ SelfList<CellData>::List cells;
+ List<RID> canvas_items;
+
+ SelfList<RenderingQuadrant> dirty_quadrant_list_element;
+
+ // For those, copy everything but SelfList elements.
+ RenderingQuadrant(const RenderingQuadrant &p_other) :
+ dirty_quadrant_list_element(this) {
+ quadrant_coords = p_other.quadrant_coords;
+ cells = p_other.cells;
+ canvas_items = p_other.canvas_items;
+ }
+
+ RenderingQuadrant() :
+ dirty_quadrant_list_element(this) {
+ }
+
+ ~RenderingQuadrant() {
+ cells.clear();
+ }
+};
+
class TileMapLayer : public RefCounted {
+ GDCLASS(TileMapLayer, RefCounted);
+
public:
enum DataFormat {
FORMAT_1 = 0,
@@ -166,6 +230,34 @@ public:
FORMAT_MAX,
};
+ enum DirtyFlags {
+ DIRTY_FLAGS_LAYER_ENABLED = 0,
+ DIRTY_FLAGS_LAYER_MODULATE,
+ DIRTY_FLAGS_LAYER_Y_SORT_ENABLED,
+ DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN,
+ DIRTY_FLAGS_LAYER_Z_INDEX,
+ DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE,
+ DIRTY_FLAGS_TILE_MAP_IN_TREE,
+ DIRTY_FLAGS_TILE_MAP_IN_CANVAS,
+ DIRTY_FLAGS_TILE_MAP_VISIBILITY,
+ DIRTY_FLAGS_TILE_MAP_XFORM,
+ DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM,
+ DIRTY_FLAGS_TILE_MAP_SELECTED_LAYER,
+ DIRTY_FLAGS_TILE_MAP_LIGHT_MASK,
+ DIRTY_FLAGS_TILE_MAP_MATERIAL,
+ DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL,
+ DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER,
+ DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT,
+ DIRTY_FLAGS_TILE_MAP_TILE_SET,
+ DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE,
+ DIRTY_FLAGS_TILE_MAP_COLLISION_ANIMATABLE,
+ DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE,
+ DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE,
+ DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED,
+ DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE,
+ DIRTY_FLAGS_MAX,
+ };
+
private:
// Exposed properties.
String name;
@@ -181,10 +273,14 @@ private:
TileMap *tile_map_node = nullptr;
int layer_index_in_tile_map_node = -1;
RID canvas_item;
- bool _rendering_quadrant_order_dirty = false;
- HashMap<Vector2i, TileMapCell> tile_map;
- HashMap<Vector2i, TileMapQuadrant> quadrant_map;
- SelfList<TileMapQuadrant>::List dirty_quadrant_list;
+ HashMap<Vector2i, CellData> tile_map;
+
+ // Dirty flag. Allows knowing what was modified since the last update.
+ struct {
+ bool flags[DIRTY_FLAGS_MAX] = { false };
+ SelfList<CellData>::List cell_list;
+ } dirty;
+ bool in_destructor = false;
// Rect cache.
mutable Rect2 rect_cache;
@@ -192,40 +288,57 @@ private:
mutable Rect2i used_rect_cache;
mutable bool used_rect_cache_dirty = true;
- // Quadrants management.
- Vector2i _coords_to_quadrant_coords(const Vector2i &p_coords) const;
- HashMap<Vector2i, TileMapQuadrant>::Iterator _create_quadrant(const Vector2i &p_qk);
- void _make_quadrant_dirty(HashMap<Vector2i, TileMapQuadrant>::Iterator Q);
- void _erase_quadrant(HashMap<Vector2i, TileMapQuadrant>::Iterator Q);
+ // Runtime tile data.
+ bool _runtime_update_tile_data_was_cleaned_up = false;
+ void _build_runtime_update_tile_data();
+ void _build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_auto_add_to_dirty_list = false);
+ void _clear_runtime_update_tile_data();
// Per-system methods.
- void _rendering_notification(int p_what);
+#ifdef DEBUG_ENABLED
+ HashMap<Vector2i, Ref<DebugQuadrant>> debug_quadrant_map;
+ Vector2i _coords_to_debug_quadrant_coords(const Vector2i &p_coords) const;
+ bool _debug_was_cleaned_up = false;
+ void _debug_update();
+ void _debug_quadrants_update_cell(CellData &r_cell_data, SelfList<DebugQuadrant>::List &r_dirty_debug_quadrant_list);
+#endif // DEBUG_ENABLED
+
+ HashMap<Vector2i, Ref<RenderingQuadrant>> rendering_quadrant_map;
+ Vector2i _coords_to_rendering_quadrant_coords(const Vector2i &p_coords) const;
+ bool _rendering_was_cleaned_up = false;
void _rendering_update();
- void _rendering_cleanup();
- void _rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list);
- void _rendering_reorder_quadrants(int &r_index);
- void _rendering_create_quadrant(TileMapQuadrant *p_quadrant);
- void _rendering_cleanup_quadrant(TileMapQuadrant *p_quadrant);
- void _rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant);
+ void _rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list);
+ void _rendering_occluders_clear_cell(CellData &r_cell_data);
+ void _rendering_occluders_update_cell(CellData &r_cell_data);
+#ifdef DEBUG_ENABLED
+ void _rendering_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data);
+#endif // DEBUG_ENABLED
HashMap<RID, Vector2i> bodies_coords; // Mapping for RID to coords.
- void _physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list);
- void _physics_cleanup_quadrant(TileMapQuadrant *p_quadrant);
- void _physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant);
-
+ bool _physics_was_cleaned_up = false;
+ void _physics_update();
+ void _physics_notify_tilemap_change(DirtyFlags p_what);
+ void _physics_clear_cell(CellData &r_cell_data);
+ void _physics_update_cell(CellData &r_cell_data);
+#ifdef DEBUG_ENABLED
+ void _physics_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data);
+#endif // DEBUG_ENABLED
+
+ bool _navigation_was_cleaned_up = false;
void _navigation_update();
- void _navigation_cleanup();
- void _navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list);
- void _navigation_cleanup_quadrant(TileMapQuadrant *p_quadrant);
- void _navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant);
-
- HashSet<Vector2i> instantiated_scenes;
- void _scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list);
- void _scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant);
- void _scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant);
-
- // Runtime tile data.
- void _build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list);
+ void _navigation_clear_cell(CellData &r_cell_data);
+ void _navigation_update_cell(CellData &r_cell_data);
+#ifdef DEBUG_ENABLED
+ void _navigation_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data);
+#endif // DEBUG_ENABLED
+
+ bool _scenes_was_cleaned_up = false;
+ void _scenes_update();
+ void _scenes_clear_cell(CellData &r_cell_data);
+ void _scenes_update_cell(CellData &r_cell_data);
+#ifdef DEBUG_ENABLED
+ void _scenes_draw_cell_debug(const RID &p_canvas_item, const Vector2i &p_quadrant_pos, const CellData &r_cell_data);
+#endif // DEBUG_ENABLED
// Terrains.
TileSet::TerrainsPattern _get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, TileSet::TerrainsPattern p_current_pattern);
@@ -251,23 +364,10 @@ public:
int get_effective_quadrant_size() const;
// For TileMap node's use.
- void notify_canvas_entered();
- void notify_visibility_changed();
- void notify_xform_changed();
- void notify_local_xform_changed();
- void notify_canvas_exited();
- void notify_selected_layer_changed();
- void notify_light_mask_changed();
- void notify_material_changed();
- void notify_use_parent_material_changed();
- void notify_texture_filter_changed();
- void notify_texture_repeat_changed();
- void update_dirty_quadrants();
void set_tile_data(DataFormat p_format, const Vector<int> &p_data);
Vector<int> get_tile_data() const;
- void clear_instantiated_scenes();
- void clear_internals(); // Exposed for now to tilemap, but ideally, we should avoid it.
- void recreate_internals(); // Exposed for now to tilemap, but ideally, we should avoid it.
+ void notify_tile_map_change(DirtyFlags p_what);
+ void internal_update();
// --- Exposed in TileMap ---
@@ -310,15 +410,14 @@ public:
void set_navigation_map(RID p_map);
RID get_navigation_map() const;
- // In case something goes wrong.
- void force_update();
-
// Fixing and clearing methods.
void fix_invalid_tiles();
// Find coords for body.
bool has_body_rid(RID p_physics_body) const;
Vector2i get_coords_for_body_rid(RID p_physics_body) const; // For finding tiles from collision.
+
+ ~TileMapLayer();
};
class TileMap : public Node2D {
@@ -341,7 +440,7 @@ private:
// Properties.
Ref<TileSet> tile_set;
- int quadrant_size = 16;
+ int rendering_quadrant_size = 16;
bool collision_animatable = false;
VisibilityMode collision_visibility_mode = VISIBILITY_MODE_DEFAULT;
VisibilityMode navigation_visibility_mode = VISIBILITY_MODE_DEFAULT;
@@ -349,18 +448,12 @@ private:
// Layers.
LocalVector<Ref<TileMapLayer>> layers;
int selected_layer = -1;
-
- void _clear_internals();
- void _recreate_internals();
-
bool pending_update = false;
Transform2D last_valid_transform;
Transform2D new_transform;
void _tile_set_changed();
- bool _tile_set_changed_deferred_update_needed = false;
- void _tile_set_changed_deferred_update();
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -372,6 +465,9 @@ protected:
#ifndef DISABLE_DEPRECATED
Rect2i _get_used_rect_bind_compat_78328();
+ void _set_quadrant_size_compat_81070(int p_quadrant_size);
+ int _get_quadrant_size_compat_81070() const;
+
static void _bind_compatibility_methods();
#endif
@@ -382,15 +478,19 @@ public:
virtual Rect2 _edit_get_rect() const override;
#endif
+#ifndef DISABLE_DEPRECATED
+ void force_update(int p_layer);
+#endif
+
// Called by TileMapLayers.
- void queue_update_dirty_quadrants();
- void _update_dirty_quadrants();
+ void queue_internal_update();
+ void _internal_update();
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
- void set_quadrant_size(int p_size);
- int get_quadrant_size() const;
+ void set_rendering_quadrant_size(int p_size);
+ int get_rendering_quadrant_size() const;
static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_animation_offset = 0.0);
@@ -412,6 +512,7 @@ public:
int get_layer_y_sort_origin(int p_layer) const;
void set_layer_z_index(int p_layer, int p_z_index);
int get_layer_z_index(int p_layer) const;
+
void set_layer_navigation_map(int p_layer, RID p_map);
RID get_layer_navigation_map(int p_layer) const;
@@ -488,7 +589,8 @@ public:
void clear();
// Force a TileMap update.
- void force_update(int p_layer = -1);
+ void update_internals();
+ void notify_runtime_tile_data_update(int p_layer = -1);
// Helpers?
TypedArray<Vector2i> get_surrounding_cells(const Vector2i &coords);
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 3d304de1df..9eec2f5345 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -780,42 +780,31 @@ Ref<Font> Label3D::_get_font_or_default() const {
return font_override;
}
- // Check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ StringName theme_name = "font";
+ List<StringName> theme_types;
+ ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
+
+ ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_null()) {
+ continue;
+ }
for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(const_cast<Label3D *>(this), &Label3D::_font_changed));
- }
- return f;
+ if (!theme->has_font(theme_name, E)) {
+ continue;
}
- }
- }
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
-
- for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(const_cast<Label3D *>(this), &Label3D::_font_changed));
- }
- return f;
+ Ref<Font> f = theme->get_font(theme_name, E);
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect_changed(callable_mp(const_cast<Label3D *>(this), &Label3D::_font_changed));
}
+ return f;
}
}
- // If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
if (f.is_valid()) {
theme_font = f;
theme_font->connect_changed(callable_mp(const_cast<Label3D *>(this), &Label3D::_font_changed));
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 2364032863..df6e4fed73 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -384,6 +384,14 @@ bool AnimationNode::is_filter_enabled() const {
return filter_enabled;
}
+void AnimationNode::set_closable(bool p_closable) {
+ closable = p_closable;
+}
+
+bool AnimationNode::is_closable() const {
+ return closable;
+}
+
bool AnimationNode::is_path_filtered(const NodePath &p_path) const {
return filter.has(p_path);
}
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 422bd0abb1..93ca20f8f5 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -101,6 +101,8 @@ public:
HashMap<NodePath, bool> filter;
bool filter_enabled = false;
+ bool closable = false;
+
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
@@ -160,6 +162,9 @@ public:
void set_filter_enabled(bool p_enable);
bool is_filter_enabled() const;
+ void set_closable(bool p_closable);
+ bool is_closable() const;
+
virtual bool has_filter() const;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const;
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 738778b516..a94b12541e 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -554,10 +554,8 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) {
}
void Button::_texture_changed() {
- if (icon.is_valid()) {
- queue_redraw();
- update_minimum_size();
- }
+ queue_redraw();
+ update_minimum_size();
}
Ref<Texture2D> Button::get_icon() const {
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index addbb6e468..1bd4db9e2c 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -31,6 +31,7 @@
#ifndef CODE_EDIT_H
#define CODE_EDIT_H
+#include "core/object/script_language.h"
#include "scene/gui/text_edit.h"
class CodeEdit : public TextEdit {
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 3c19766ca7..2b4d5677c4 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -654,7 +654,9 @@ void ColorPicker::_text_type_toggled() {
text_is_constructor = !text_is_constructor;
if (text_is_constructor) {
text_type->set_text("");
- text_type->set_icon(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")));
+#ifdef TOOLS_ENABLED
+ text_type->set_icon(get_editor_theme_icon(SNAME("Script")));
+#endif
c_text->set_editable(false);
c_text->set_tooltip_text(RTR("Copy this constructor in a script."));
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 63692dd064..d97ce65afc 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2465,6 +2465,11 @@ bool Control::has_theme_owner_node() const {
return data.theme_owner->has_owner_node();
}
+void Control::set_theme_context(ThemeContext *p_context, bool p_propagate) {
+ ERR_MAIN_THREAD_GUARD;
+ data.theme_owner->set_owner_context(p_context, p_propagate);
+}
+
void Control::set_theme(const Ref<Theme> &p_theme) {
ERR_MAIN_THREAD_GUARD;
if (data.theme == p_theme) {
@@ -2664,6 +2669,12 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th
return constant;
}
+#ifdef TOOLS_ENABLED
+Ref<Texture2D> Control::get_editor_theme_icon(const StringName &p_name) const {
+ return get_theme_icon(p_name, SNAME("EditorIcons"));
+}
+#endif
+
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
@@ -3118,7 +3129,9 @@ void Control::_notification(int p_notification) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
- notification(NOTIFICATION_THEME_CHANGED);
+
+ // Emits NOTIFICATION_THEME_CHANGED internally.
+ set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
} break;
case NOTIFICATION_POST_ENTER_TREE: {
@@ -3128,6 +3141,7 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ set_theme_context(nullptr, false);
release_focus();
get_viewport()->_gui_remove_control(this);
} break;
@@ -3626,7 +3640,7 @@ void Control::_bind_methods() {
}
Control::Control() {
- data.theme_owner = memnew(ThemeOwner);
+ data.theme_owner = memnew(ThemeOwner(this));
}
Control::~Control() {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 7cb8fc5bf6..bad78a66d3 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -42,6 +42,7 @@ class Viewport;
class Label;
class Panel;
class ThemeOwner;
+class ThemeContext;
class Control : public CanvasItem {
GDCLASS(Control, CanvasItem);
@@ -553,6 +554,8 @@ public:
Node *get_theme_owner_node() const;
bool has_theme_owner_node() const;
+ void set_theme_context(ThemeContext *p_context, bool p_propagate = true);
+
void set_theme(const Ref<Theme> &p_theme);
Ref<Theme> get_theme() const;
@@ -582,6 +585,9 @@ public:
int get_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
Color get_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
int get_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
+#ifdef TOOLS_ENABLED
+ Ref<Texture2D> get_editor_theme_icon(const StringName &p_name) const;
+#endif
bool has_theme_icon_override(const StringName &p_name) const;
bool has_theme_stylebox_override(const StringName &p_name) const;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index cb9fba44e5..be0ae45e7e 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -295,16 +295,16 @@ void GraphEdit::_update_scroll_offset() {
set_block_minimum_size_adjust(true);
for (int i = 0; i < get_child_count(); i++) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (!graph_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!graph_element) {
continue;
}
- Point2 pos = graph_node->get_position_offset() * zoom;
+ Point2 pos = graph_element->get_position_offset() * zoom;
pos -= Point2(h_scrollbar->get_value(), v_scrollbar->get_value());
- graph_node->set_position(pos);
- if (graph_node->get_scale() != Vector2(zoom, zoom)) {
- graph_node->set_scale(Vector2(zoom, zoom));
+ graph_element->set_position(pos);
+ if (graph_element->get_scale() != Vector2(zoom, zoom)) {
+ graph_element->set_scale(Vector2(zoom, zoom));
}
}
@@ -328,14 +328,14 @@ void GraphEdit::_update_scroll() {
Rect2 screen_rect;
for (int i = 0; i < get_child_count(); i++) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (!graph_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!graph_element) {
continue;
}
Rect2 node_rect;
- node_rect.position = graph_node->get_position_offset() * zoom;
- node_rect.size = graph_node->get_size() * zoom;
+ node_rect.position = graph_element->get_position_offset() * zoom;
+ node_rect.size = graph_element->get_size() * zoom;
screen_rect = screen_rect.merge(node_rect);
}
@@ -378,46 +378,48 @@ void GraphEdit::_update_scroll() {
updating = false;
}
-void GraphEdit::_graph_node_moved_to_front(Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
- ERR_FAIL_NULL(graph_node);
+void GraphEdit::_graph_element_moved_to_front(Node *p_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_NULL(graph_element);
- graph_node->move_to_front();
+ graph_element->move_to_front();
}
-void GraphEdit::_graph_node_selected(Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
- ERR_FAIL_NULL(graph_node);
+void GraphEdit::_graph_element_selected(Node *p_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_NULL(graph_element);
- emit_signal(SNAME("node_selected"), graph_node);
+ emit_signal(SNAME("node_selected"), graph_element);
}
-void GraphEdit::_graph_node_deselected(Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
- ERR_FAIL_NULL(graph_node);
+void GraphEdit::_graph_element_deselected(Node *p_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_NULL(graph_element);
- emit_signal(SNAME("node_deselected"), graph_node);
+ emit_signal(SNAME("node_deselected"), graph_element);
}
-void GraphEdit::_graph_node_resized(Vector2 p_new_minsize, Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
- ERR_FAIL_NULL(graph_node);
+void GraphEdit::_graph_element_resized(Vector2 p_new_minsize, Node *p_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_NULL(graph_element);
- graph_node->set_custom_minimum_size(p_new_minsize);
+ graph_element->set_size(p_new_minsize);
}
-void GraphEdit::_graph_node_moved(Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
- ERR_FAIL_NULL(graph_node);
+void GraphEdit::_graph_element_moved(Node *p_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_node);
+ ERR_FAIL_NULL(graph_element);
+
top_layer->queue_redraw();
minimap->queue_redraw();
queue_redraw();
connections_layer->queue_redraw();
}
-void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_gn) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_gn);
+void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_node) {
+ GraphNode *graph_node = Object::cast_to<GraphNode>(p_node);
ERR_FAIL_NULL(graph_node);
+
top_layer->queue_redraw();
minimap->queue_redraw();
queue_redraw();
@@ -430,19 +432,25 @@ void GraphEdit::add_child_notify(Node *p_child) {
// Keep the top layer always on top!
callable_mp((CanvasItem *)top_layer, &CanvasItem::move_to_front).call_deferred();
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_child);
- if (graph_node) {
- graph_node->set_scale(Vector2(zoom, zoom));
- graph_node->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved).bind(graph_node));
- graph_node->connect("node_selected", callable_mp(this, &GraphEdit::_graph_node_selected).bind(graph_node));
- graph_node->connect("node_deselected", callable_mp(this, &GraphEdit::_graph_node_deselected).bind(graph_node));
- graph_node->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(graph_node));
- graph_node->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_moved_to_front).bind(graph_node));
- graph_node->connect("resize_request", callable_mp(this, &GraphEdit::_graph_node_resized).bind(graph_node));
- graph_node->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
- graph_node->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
- _graph_node_moved(graph_node);
- graph_node->set_mouse_filter(MOUSE_FILTER_PASS);
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_child);
+ if (graph_element) {
+ graph_element->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_element_moved).bind(graph_element));
+ graph_element->connect("node_selected", callable_mp(this, &GraphEdit::_graph_element_selected).bind(graph_element));
+ graph_element->connect("node_deselected", callable_mp(this, &GraphEdit::_graph_element_deselected).bind(graph_element));
+
+ GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element);
+ if (graph_node) {
+ graph_element->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(graph_element));
+ }
+
+ graph_element->connect("raise_request", callable_mp(this, &GraphEdit::_graph_element_moved_to_front).bind(graph_element));
+ graph_element->connect("resize_request", callable_mp(this, &GraphEdit::_graph_element_resized).bind(graph_element));
+ graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
+ graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
+
+ graph_element->set_scale(Vector2(zoom, zoom));
+ _graph_element_moved(graph_element);
+ graph_element->set_mouse_filter(MOUSE_FILTER_PASS);
}
}
@@ -461,20 +469,26 @@ void GraphEdit::remove_child_notify(Node *p_child) {
callable_mp((CanvasItem *)top_layer, &CanvasItem::move_to_front).call_deferred();
}
- GraphNode *graph_node = Object::cast_to<GraphNode>(p_child);
- if (graph_node) {
- graph_node->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved));
- graph_node->disconnect("node_selected", callable_mp(this, &GraphEdit::_graph_node_selected));
- graph_node->disconnect("node_deselected", callable_mp(this, &GraphEdit::_graph_node_deselected));
- graph_node->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated));
- graph_node->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_moved_to_front));
+ GraphElement *graph_element = Object::cast_to<GraphElement>(p_child);
+ if (graph_element) {
+ graph_element->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_element_moved));
+ graph_element->disconnect("node_selected", callable_mp(this, &GraphEdit::_graph_element_selected));
+ graph_element->disconnect("node_deselected", callable_mp(this, &GraphEdit::_graph_element_deselected));
+
+ GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element);
+ if (graph_node) {
+ graph_element->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated));
+ }
+
+ graph_element->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_element_moved_to_front));
+ graph_element->disconnect("resize_request", callable_mp(this, &GraphEdit::_graph_element_resized));
// In case of the whole GraphEdit being destroyed these references can already be freed.
if (connections_layer != nullptr && connections_layer->is_inside_tree()) {
- graph_node->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
+ graph_element->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
}
if (minimap != nullptr && minimap->is_inside_tree()) {
- graph_node->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
+ graph_element->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
}
}
}
@@ -572,11 +586,11 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
continue;
}
- for (int j = 0; j < graph_node->get_connection_input_count(); j++) {
+ for (int j = 0; j < graph_node->get_input_port_count(); j++) {
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_input_slot(j);
+ int slot_index = graph_node->get_input_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
@@ -586,11 +600,11 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
}
}
- for (int j = 0; j < graph_node->get_connection_output_count(); j++) {
+ for (int j = 0; j < graph_node->get_output_port_count(); j++) {
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_output_slot(j);
+ int slot_index = graph_node->get_output_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
@@ -616,17 +630,17 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
continue;
}
- for (int j = 0; j < graph_node->get_connection_output_count(); j++) {
- Vector2 pos = graph_node->get_connection_output_position(j) * zoom + graph_node->get_position();
+ for (int j = 0; j < graph_node->get_output_port_count(); j++) {
+ Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position();
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_output_slot(j);
+ int slot_index = graph_node->get_output_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
if (is_in_output_hotzone(graph_node, j, click_pos, port_size)) {
- if (valid_left_disconnect_types.has(graph_node->get_connection_output_type(j))) {
+ if (valid_left_disconnect_types.has(graph_node->get_output_port_type(j))) {
// Check disconnect.
for (const Connection &E : connections) {
if (E.from_node == graph_node->get_name() && E.from_port == j) {
@@ -635,8 +649,8 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_from = E.to_node;
connecting_index = E.to_port;
connecting_out = false;
- connecting_type = Object::cast_to<GraphNode>(to)->get_connection_input_type(E.to_port);
- connecting_color = Object::cast_to<GraphNode>(to)->get_connection_input_color(E.to_port);
+ connecting_type = Object::cast_to<GraphNode>(to)->get_input_port_type(E.to_port);
+ connecting_color = Object::cast_to<GraphNode>(to)->get_input_port_color(E.to_port);
connecting_target = false;
connecting_to = pos;
@@ -659,8 +673,8 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_from = graph_node->get_name();
connecting_index = j;
connecting_out = true;
- connecting_type = graph_node->get_connection_output_type(j);
- connecting_color = graph_node->get_connection_output_color(j);
+ connecting_type = graph_node->get_output_port_type(j);
+ connecting_color = graph_node->get_output_port_color(j);
connecting_target = false;
connecting_to = pos;
if (connecting_type >= 0) {
@@ -672,18 +686,18 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
- for (int j = 0; j < graph_node->get_connection_input_count(); j++) {
- Vector2 pos = graph_node->get_connection_input_position(j) + graph_node->get_position();
+ for (int j = 0; j < graph_node->get_input_port_count(); j++) {
+ Vector2 pos = graph_node->get_input_port_position(j) * zoom + graph_node->get_position();
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_input_slot(j);
+ int slot_index = graph_node->get_input_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
if (is_in_input_hotzone(graph_node, j, click_pos, port_size)) {
- if (right_disconnects || valid_right_disconnect_types.has(graph_node->get_connection_input_type(j))) {
+ if (right_disconnects || valid_right_disconnect_types.has(graph_node->get_input_port_type(j))) {
// Check disconnect.
for (const Connection &E : connections) {
if (E.to_node == graph_node->get_name() && E.to_port == j) {
@@ -692,8 +706,8 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_from = E.from_node;
connecting_index = E.from_port;
connecting_out = true;
- connecting_type = Object::cast_to<GraphNode>(fr)->get_connection_output_type(E.from_port);
- connecting_color = Object::cast_to<GraphNode>(fr)->get_connection_output_color(E.from_port);
+ connecting_type = Object::cast_to<GraphNode>(fr)->get_output_port_type(E.from_port);
+ connecting_color = Object::cast_to<GraphNode>(fr)->get_output_port_color(E.from_port);
connecting_target = false;
connecting_to = pos;
just_disconnected = true;
@@ -715,8 +729,8 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_from = graph_node->get_name();
connecting_index = j;
connecting_out = false;
- connecting_type = graph_node->get_connection_input_type(j);
- connecting_color = graph_node->get_connection_input_color(j);
+ connecting_type = graph_node->get_input_port_type(j);
+ connecting_color = graph_node->get_input_port_color(j);
connecting_target = false;
connecting_to = pos;
if (connecting_type >= 0) {
@@ -749,16 +763,16 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
if (!connecting_out) {
- for (int j = 0; j < graph_node->get_connection_output_count(); j++) {
- Vector2 pos = graph_node->get_connection_output_position(j) + graph_node->get_position();
+ for (int j = 0; j < graph_node->get_output_port_count(); j++) {
+ Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position();
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_output_slot(j);
+ int slot_index = graph_node->get_output_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
- int type = graph_node->get_connection_output_type(j);
+ int type = graph_node->get_output_port_type(j);
if ((type == connecting_type ||
valid_connection_types.has(ConnectionType(connecting_type, type))) &&
is_in_output_hotzone(graph_node, j, mpos, port_size)) {
@@ -773,16 +787,16 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
} else {
- for (int j = 0; j < graph_node->get_connection_input_count(); j++) {
- Vector2 pos = graph_node->get_connection_input_position(j) + graph_node->get_position();
+ for (int j = 0; j < graph_node->get_input_port_count(); j++) {
+ Vector2 pos = graph_node->get_input_port_position(j) * zoom + graph_node->get_position();
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
// Determine slot height.
- int slot_index = graph_node->get_connection_input_slot(j);
+ int slot_index = graph_node->get_input_port_slot(j);
Control *child = Object::cast_to<Control>(graph_node->get_child(slot_index));
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
- int type = graph_node->get_connection_input_type(j);
+ int type = graph_node->get_input_port_type(j);
if ((type == connecting_type || valid_connection_types.has(ConnectionType(connecting_type, type))) &&
is_in_input_hotzone(graph_node, j, mpos, port_size)) {
if (!is_node_hover_valid(connecting_from, connecting_index, graph_node->get_name(), j)) {
@@ -851,17 +865,17 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &mpos
}
}
-bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
+bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
bool success;
- if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_graph_node, p_port, p_mouse_pos, success)) {
+ if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_graph_node, p_port_idx, p_mouse_pos, success)) {
return success;
} else {
- Vector2 pos = p_graph_node->get_connection_input_position(p_port) + p_graph_node->get_position();
+ Vector2 pos = p_graph_node->get_input_port_position(p_port_idx) * zoom + p_graph_node->get_position();
return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, true);
}
}
-bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
+bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
if (p_graph_node->is_resizable()) {
Ref<Texture2D> resizer = p_graph_node->get_theme_icon(SNAME("resizer"));
Rect2 resizer_rect = Rect2(p_graph_node->get_position() / zoom + p_graph_node->get_size() - resizer->get_size(), resizer->get_size());
@@ -871,10 +885,10 @@ bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port, const
}
bool success;
- if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_graph_node, p_port, p_mouse_pos, success)) {
+ if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_graph_node, p_port_idx, p_mouse_pos, success)) {
return success;
} else {
- Vector2 pos = p_graph_node->get_connection_output_position(p_port) + p_graph_node->get_position();
+ Vector2 pos = p_graph_node->get_output_port_position(p_port_idx) * zoom + p_graph_node->get_position();
return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, false);
}
}
@@ -978,10 +992,10 @@ void GraphEdit::_connections_layer_draw() {
continue;
}
- Vector2 frompos = gnode_from->get_connection_output_position(c.from_port) + gnode_from->get_position_offset() * zoom;
- Color color = gnode_from->get_connection_output_color(c.from_port);
- Vector2 topos = gnode_to->get_connection_input_position(c.to_port) + gnode_to->get_position_offset() * zoom;
- Color tocolor = gnode_to->get_connection_input_color(c.to_port);
+ Vector2 frompos = gnode_from->get_output_port_position(c.from_port) * zoom + gnode_from->get_position_offset() * zoom;
+ Color color = gnode_from->get_output_port_color(c.from_port);
+ Vector2 topos = gnode_to->get_input_port_position(c.to_port) * zoom + gnode_to->get_position_offset() * zoom;
+ Color tocolor = gnode_to->get_input_port_color(c.to_port);
if (c.activity > 0) {
color = color.lerp(activity_color, c.activity);
@@ -1005,9 +1019,9 @@ void GraphEdit::_top_layer_draw() {
ERR_FAIL_NULL(graph_node_from);
Vector2 pos;
if (connecting_out) {
- pos = graph_node_from->get_connection_output_position(connecting_index);
+ pos = graph_node_from->get_output_port_position(connecting_index) * zoom;
} else {
- pos = graph_node_from->get_connection_input_position(connecting_index);
+ pos = graph_node_from->get_input_port_position(connecting_index) * zoom;
}
pos += graph_node_from->get_position();
@@ -1061,7 +1075,7 @@ void GraphEdit::_minimap_draw() {
Ref<StyleBoxFlat> sb_minimap = minimap->get_theme_stylebox(SNAME("node"))->duplicate();
// Override default values with colors provided by the GraphNode's stylebox, if possible.
- Ref<StyleBoxFlat> sb_frame = graph_node->get_theme_stylebox(graph_node->is_selected() ? "selected_frame" : "frame");
+ Ref<StyleBoxFlat> sb_frame = graph_node->get_theme_stylebox(graph_node->is_selected() ? "panel_selected" : "panel");
if (sb_frame.is_valid()) {
Color node_color = sb_frame->get_bg_color();
sb_minimap->set_bg_color(node_color);
@@ -1085,12 +1099,12 @@ void GraphEdit::_minimap_draw() {
continue;
}
- Vector2 from_port_position = graph_node_from->get_position_offset() + graph_node_from->get_connection_output_position(E.from_port);
+ Vector2 from_port_position = graph_node_from->get_position_offset() * zoom + graph_node_from->get_output_port_position(E.from_port) * zoom;
Vector2 from_position = minimap->_convert_from_graph_position(from_port_position - graph_offset) + minimap_offset;
- Color from_color = graph_node_from->get_connection_output_color(E.from_port);
- Vector2 to_port_position = graph_node_to->get_position_offset() + graph_node_to->get_connection_input_position(E.to_port);
+ Color from_color = graph_node_from->get_output_port_color(E.from_port);
+ Vector2 to_port_position = graph_node_to->get_position_offset() * zoom + graph_node_to->get_input_port_position(E.to_port) * zoom;
Vector2 to_position = minimap->_convert_from_graph_position(to_port_position - graph_offset) + minimap_offset;
- Color to_color = graph_node_to->get_connection_input_color(E.to_port);
+ Color to_color = graph_node_to->get_input_port_color(E.to_port);
if (E.activity > 0) {
from_color = from_color.lerp(activity_color, E.activity);
@@ -1137,9 +1151,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
just_selected = true;
drag_accum += mm->get_relative();
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (graph_node && graph_node->is_selected() && graph_node->is_draggable()) {
- Vector2 pos = (graph_node->get_drag_from() * zoom + drag_accum) / zoom;
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (graph_element && graph_element->is_selected() && graph_element->is_draggable()) {
+ Vector2 pos = (graph_element->get_drag_from() * zoom + drag_accum) / zoom;
// Snapping can be toggled temporarily by holding down Ctrl.
// This is done here as to not toggle the grid when holding down Ctrl.
@@ -1147,7 +1161,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
pos = pos.snapped(Vector2(snapping_distance, snapping_distance));
}
- graph_node->set_position_offset(pos);
+ graph_element->set_position_offset(pos);
}
}
}
@@ -1158,18 +1172,18 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
box_selecting_rect = Rect2(box_selecting_from.min(box_selecting_to), (box_selecting_from - box_selecting_to).abs());
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (!graph_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!graph_element) {
continue;
}
- Rect2 r = graph_node->get_rect();
+ Rect2 r = graph_element->get_rect();
bool in_box = r.intersects(box_selecting_rect);
if (in_box) {
- graph_node->set_selected(box_selection_mode_additive);
+ graph_element->set_selected(box_selection_mode_additive);
} else {
- graph_node->set_selected(prev_selected.find(graph_node) != nullptr);
+ graph_element->set_selected(prev_selected.find(graph_element) != nullptr);
}
}
@@ -1183,12 +1197,12 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (box_selecting) {
box_selecting = false;
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (!graph_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!graph_element) {
continue;
}
- graph_node->set_selected(prev_selected.find(graph_node) != nullptr);
+ graph_element->set_selected(prev_selected.find(graph_element) != nullptr);
}
top_layer->queue_redraw();
minimap->queue_redraw();
@@ -1205,12 +1219,12 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(Key::CTRL)) {
// Deselect current node.
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
- if (graph_node) {
- Rect2 r = graph_node->get_rect();
+ if (graph_element) {
+ Rect2 r = graph_element->get_rect();
if (r.has_point(mb->get_position())) {
- graph_node->set_selected(false);
+ graph_element->set_selected(false);
}
}
}
@@ -1218,9 +1232,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (drag_accum != Vector2()) {
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (graph_node && graph_node->is_selected()) {
- graph_node->set_drag(false);
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (graph_element && graph_element->is_selected()) {
+ graph_element->set_drag(false);
}
}
}
@@ -1240,27 +1254,27 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
// Node selection logic.
if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
- GraphNode *graph_node = nullptr;
+ GraphElement *graph_element = nullptr;
// Find node which was clicked on.
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *selected_gcontrol = Object::cast_to<GraphNode>(get_child(i));
+ GraphElement *selected_element = Object::cast_to<GraphElement>(get_child(i));
- if (!selected_gcontrol) {
+ if (!selected_element) {
continue;
}
- if (selected_gcontrol->is_resizing()) {
+ if (selected_element->is_resizing()) {
continue;
}
- if (selected_gcontrol->has_point((mb->get_position() - selected_gcontrol->get_position()) / zoom)) {
- graph_node = selected_gcontrol;
+ if (selected_element->has_point((mb->get_position() - selected_element->get_position()) / zoom)) {
+ graph_element = selected_element;
break;
}
}
- if (graph_node) {
+ if (graph_element) {
if (_filter_input(mb->get_position())) {
return;
}
@@ -1268,26 +1282,26 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
// Left-clicked on a node, select it.
dragging = true;
drag_accum = Vector2();
- just_selected = !graph_node->is_selected();
- if (!graph_node->is_selected() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ just_selected = !graph_element->is_selected();
+ if (!graph_element->is_selected() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
for (int i = 0; i < get_child_count(); i++) {
- GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
- if (!o_gn) {
+ GraphElement *child_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!child_element) {
continue;
}
- o_gn->set_selected(o_gn == graph_node);
+ child_element->set_selected(child_element == graph_element);
}
}
- graph_node->set_selected(true);
+ graph_element->set_selected(true);
for (int i = 0; i < get_child_count(); i++) {
- GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
- if (!o_gn) {
+ GraphElement *child_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!child_element) {
continue;
}
- if (o_gn->is_selected()) {
- o_gn->set_drag(true);
+ if (child_element->is_selected()) {
+ child_element->set_drag(true);
}
}
@@ -1306,34 +1320,34 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
box_selection_mode_additive = true;
prev_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2 || !gn2->is_selected()) {
+ GraphElement *child_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!child_element || !child_element->is_selected()) {
continue;
}
- prev_selected.push_back(gn2);
+ prev_selected.push_back(child_element);
}
} else if (mb->is_shift_pressed()) {
box_selection_mode_additive = false;
prev_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2 || !gn2->is_selected()) {
+ GraphElement *child_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!child_element || !child_element->is_selected()) {
continue;
}
- prev_selected.push_back(gn2);
+ prev_selected.push_back(child_element);
}
} else {
box_selection_mode_additive = true;
prev_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2) {
+ GraphElement *child_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!child_element) {
continue;
}
- gn2->set_selected(false);
+ child_element->set_selected(false);
}
}
}
@@ -1372,7 +1386,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
}
}
- emit_signal(SNAME("delete_nodes_request"), nodes);
+ emit_signal(SNAME("close_nodes_request"), nodes);
accept_event();
}
}
@@ -1886,7 +1900,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("node_deselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from_node"), PropertyInfo(Variant::INT, "from_port"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to_node"), PropertyInfo(Variant::INT, "to_port"), PropertyInfo(Variant::VECTOR2, "release_position")));
- ADD_SIGNAL(MethodInfo("delete_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName")));
+ ADD_SIGNAL(MethodInfo("close_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName")));
ADD_SIGNAL(MethodInfo("begin_node_move"));
ADD_SIGNAL(MethodInfo("end_node_move"));
ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "offset")));
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index d86cc4a5f9..5e97ea353d 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -195,7 +195,7 @@ private:
Point2 box_selecting_from;
Point2 box_selecting_to;
Rect2 box_selecting_rect;
- List<GraphNode *> prev_selected;
+ List<GraphElement *> prev_selected;
bool setting_scroll_offset = false;
bool right_disconnects = false;
@@ -229,12 +229,12 @@ private:
void _draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom);
- void _graph_node_selected(Node *p_gn);
- void _graph_node_deselected(Node *p_gn);
- void _graph_node_moved_to_front(Node *p_gn);
- void _graph_node_resized(Vector2 p_new_minsize, Node *p_gn);
- void _graph_node_moved(Node *p_gn);
- void _graph_node_slot_updated(int p_index, Node *p_gn);
+ void _graph_element_selected(Node *p_node);
+ void _graph_element_deselected(Node *p_node);
+ void _graph_element_moved_to_front(Node *p_node);
+ void _graph_element_resized(Vector2 p_new_minsize, Node *p_node);
+ void _graph_element_moved(Node *p_node);
+ void _graph_node_slot_updated(int p_index, Node *p_node);
void _update_scroll();
void _update_scroll_offset();
@@ -269,8 +269,8 @@ protected:
void _notification(int p_what);
- virtual bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
- virtual bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
+ virtual bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
+ virtual bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2)
GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2)
diff --git a/scene/gui/graph_edit_arranger.cpp b/scene/gui/graph_edit_arranger.cpp
index f4d9dcbf95..c1750a7b0f 100644
--- a/scene/gui/graph_edit_arranger.cpp
+++ b/scene/gui/graph_edit_arranger.cpp
@@ -408,8 +408,8 @@ void GraphEditArranger::_calculate_inner_shifts(Dictionary &r_inner_shifts, cons
int port_from = ports.first;
int port_to = ports.second;
- Vector2 pos_from = gnode_from->get_connection_output_position(port_from) * graph_edit->get_zoom();
- Vector2 pos_to = gnode_to->get_connection_input_position(port_to) * graph_edit->get_zoom();
+ Vector2 pos_from = gnode_from->get_output_port_position(port_from) * graph_edit->get_zoom();
+ Vector2 pos_to = gnode_to->get_input_port_position(port_to) * graph_edit->get_zoom();
real_t s = (real_t)r_inner_shifts[u] + (pos_from.y - pos_to.y) / graph_edit->get_zoom();
r_inner_shifts[v] = s;
@@ -459,8 +459,8 @@ float GraphEditArranger::_calculate_threshold(StringName p_v, StringName p_w, co
if (incoming.from_node != StringName()) {
GraphNode *gnode_from = Object::cast_to<GraphNode>(r_node_names[incoming.from_node]);
GraphNode *gnode_to = Object::cast_to<GraphNode>(r_node_names[p_w]);
- Vector2 pos_from = gnode_from->get_connection_output_position(incoming.from_port) * graph_edit->get_zoom();
- Vector2 pos_to = gnode_to->get_connection_input_position(incoming.to_port) * graph_edit->get_zoom();
+ Vector2 pos_from = gnode_from->get_output_port_position(incoming.from_port) * graph_edit->get_zoom();
+ Vector2 pos_to = gnode_to->get_input_port_position(incoming.to_port) * graph_edit->get_zoom();
// If connected block node is selected, calculate thershold or add current block to list.
if (gnode_from->is_selected()) {
@@ -491,8 +491,8 @@ float GraphEditArranger::_calculate_threshold(StringName p_v, StringName p_w, co
if (outgoing.to_node != StringName()) {
GraphNode *gnode_from = Object::cast_to<GraphNode>(r_node_names[p_w]);
GraphNode *gnode_to = Object::cast_to<GraphNode>(r_node_names[outgoing.to_node]);
- Vector2 pos_from = gnode_from->get_connection_output_position(outgoing.from_port) * graph_edit->get_zoom();
- Vector2 pos_to = gnode_to->get_connection_input_position(outgoing.to_port) * graph_edit->get_zoom();
+ Vector2 pos_from = gnode_from->get_output_port_position(outgoing.from_port) * graph_edit->get_zoom();
+ Vector2 pos_to = gnode_to->get_input_port_position(outgoing.to_port) * graph_edit->get_zoom();
// If connected block node is selected, calculate thershold or add current block to list.
if (gnode_to->is_selected()) {
diff --git a/scene/gui/graph_element.cpp b/scene/gui/graph_element.cpp
new file mode 100644
index 0000000000..04c4aa6ce8
--- /dev/null
+++ b/scene/gui/graph_element.cpp
@@ -0,0 +1,244 @@
+/**************************************************************************/
+/* graph_element.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "graph_element.h"
+
+#include "core/string/translation.h"
+#include "scene/gui/graph_edit.h"
+
+#ifdef TOOLS_ENABLED
+void GraphElement::_edit_set_position(const Point2 &p_position) {
+ GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
+ if (graph) {
+ Point2 offset = (p_position + graph->get_scroll_offset()) * graph->get_zoom();
+ set_position_offset(offset);
+ }
+ set_position(p_position);
+}
+#endif
+
+void GraphElement::_resort() {
+ Size2 size = get_size();
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i));
+ if (!child || !child->is_visible_in_tree()) {
+ continue;
+ }
+ if (child->is_set_as_top_level()) {
+ continue;
+ }
+
+ fit_child_in_rect(child, Rect2(Point2(), size));
+ }
+}
+
+Size2 GraphElement::get_minimum_size() const {
+ Size2 minsize;
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i));
+ if (!child) {
+ continue;
+ }
+ if (child->is_set_as_top_level()) {
+ continue;
+ }
+
+ Size2i size = child->get_combined_minimum_size();
+
+ minsize.width = MAX(minsize.width, size.width);
+ minsize.height = MAX(minsize.height, size.height);
+ }
+
+ return minsize;
+}
+
+void GraphElement::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_SORT_CHILDREN: {
+ _resort();
+ } break;
+
+ case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
+ case NOTIFICATION_TRANSLATION_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
+ update_minimum_size();
+ queue_redraw();
+ } break;
+ }
+}
+
+void GraphElement::_validate_property(PropertyInfo &p_property) const {
+ Control::_validate_property(p_property);
+ GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
+ if (graph) {
+ if (p_property.name == "position") {
+ p_property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ }
+}
+
+void GraphElement::set_position_offset(const Vector2 &p_offset) {
+ if (position_offset == p_offset) {
+ return;
+ }
+
+ position_offset = p_offset;
+ emit_signal(SNAME("position_offset_changed"));
+ queue_redraw();
+}
+
+Vector2 GraphElement::get_position_offset() const {
+ return position_offset;
+}
+
+void GraphElement::set_selected(bool p_selected) {
+ if (!is_selectable() || selected == p_selected) {
+ return;
+ }
+ selected = p_selected;
+ emit_signal(p_selected ? SNAME("node_selected") : SNAME("node_deselected"));
+ queue_redraw();
+}
+
+bool GraphElement::is_selected() {
+ return selected;
+}
+
+void GraphElement::set_drag(bool p_drag) {
+ if (p_drag) {
+ drag_from = get_position_offset();
+ } else {
+ emit_signal(SNAME("dragged"), drag_from, get_position_offset()); // Required for undo/redo.
+ }
+}
+
+Vector2 GraphElement::get_drag_from() {
+ return drag_from;
+}
+
+void GraphElement::gui_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
+ Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid()) {
+ ERR_FAIL_COND_MSG(get_parent_control() == nullptr, "GraphElement must be the child of a GraphEdit node.");
+
+ if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
+ Vector2 mpos = mb->get_position();
+
+ Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
+
+ if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
+ resizing = true;
+ resizing_from = mpos;
+ resizing_from_size = get_size();
+ accept_event();
+ return;
+ }
+
+ emit_signal(SNAME("raise_request"));
+ }
+
+ if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
+ resizing = false;
+ }
+ }
+
+ Ref<InputEventMouseMotion> mm = p_ev;
+ if (resizing && mm.is_valid()) {
+ Vector2 mpos = mm->get_position();
+ Vector2 diff = mpos - resizing_from;
+
+ emit_signal(SNAME("resize_request"), resizing_from_size + diff);
+ }
+}
+
+void GraphElement::set_resizable(bool p_enable) {
+ if (resizable == p_enable) {
+ return;
+ }
+ resizable = p_enable;
+ queue_redraw();
+}
+
+bool GraphElement::is_resizable() const {
+ return resizable;
+}
+
+void GraphElement::set_draggable(bool p_draggable) {
+ draggable = p_draggable;
+}
+
+bool GraphElement::is_draggable() {
+ return draggable;
+}
+
+void GraphElement::set_selectable(bool p_selectable) {
+ if (!p_selectable) {
+ set_selected(false);
+ }
+ selectable = p_selectable;
+}
+
+bool GraphElement::is_selectable() {
+ return selectable;
+}
+
+void GraphElement::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphElement::set_resizable);
+ ClassDB::bind_method(D_METHOD("is_resizable"), &GraphElement::is_resizable);
+
+ ClassDB::bind_method(D_METHOD("set_draggable", "draggable"), &GraphElement::set_draggable);
+ ClassDB::bind_method(D_METHOD("is_draggable"), &GraphElement::is_draggable);
+
+ ClassDB::bind_method(D_METHOD("set_selectable", "selectable"), &GraphElement::set_selectable);
+ ClassDB::bind_method(D_METHOD("is_selectable"), &GraphElement::is_selectable);
+
+ ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphElement::set_selected);
+ ClassDB::bind_method(D_METHOD("is_selected"), &GraphElement::is_selected);
+
+ ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphElement::set_position_offset);
+ ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphElement::get_position_offset);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset"), "set_position_offset", "get_position_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draggable"), "set_draggable", "is_draggable");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selectable"), "set_selectable", "is_selectable");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selected"), "set_selected", "is_selected");
+
+ ADD_SIGNAL(MethodInfo("position_offset_changed"));
+ ADD_SIGNAL(MethodInfo("node_selected"));
+ ADD_SIGNAL(MethodInfo("node_deselected"));
+ ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
+ ADD_SIGNAL(MethodInfo("raise_request"));
+ ADD_SIGNAL(MethodInfo("close_request"));
+ ADD_SIGNAL(MethodInfo("resize_request", PropertyInfo(Variant::VECTOR2, "new_minsize")));
+}
diff --git a/platform/uwp/context_egl_uwp.h b/scene/gui/graph_element.h
index 810c3dcbc1..2c0a4760d8 100644
--- a/platform/uwp/context_egl_uwp.h
+++ b/scene/gui/graph_element.h
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* context_egl_uwp.h */
+/* graph_element.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,57 +28,66 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef CONTEXT_EGL_UWP_H
-#define CONTEXT_EGL_UWP_H
+#ifndef GRAPH_ELEMENT_H
+#define GRAPH_ELEMENT_H
-#include "core/error/error_list.h"
-#include "core/os/os.h"
+#include "scene/gui/container.h"
-#include <EGL/egl.h>
-#include <wrl.h>
+class GraphElement : public Container {
+ GDCLASS(GraphElement, Container);
-using namespace Windows::UI::Core;
+protected:
+ bool selected = false;
+ bool resizable = false;
+ bool resizing = false;
+ bool draggable = true;
+ bool selectable = true;
-class ContextEGL_UWP {
-public:
- enum Driver {
- GLES_2_0,
- VULKAN, // FIXME: Add Vulkan support.
- };
+ Vector2 drag_from;
+ Vector2 resizing_from;
+ Vector2 resizing_from_size;
-private:
- CoreWindow ^ window;
+ Vector2 position_offset;
- EGLDisplay mEglDisplay;
- EGLContext mEglContext;
- EGLSurface mEglSurface;
+#ifdef TOOLS_ENABLED
+ void _edit_set_position(const Point2 &p_position) override;
+#endif
- EGLint width;
- EGLint height;
+protected:
+ virtual void gui_input(const Ref<InputEvent> &p_ev) override;
+ void _notification(int p_what);
+ static void _bind_methods();
- bool vsync;
+ virtual void _resort();
- Driver driver;
+ void _validate_property(PropertyInfo &p_property) const;
public:
- void release_current();
+ void set_position_offset(const Vector2 &p_offset);
+ Vector2 get_position_offset() const;
+
+ void set_selected(bool p_selected);
+ bool is_selected();
+
+ void set_drag(bool p_drag);
+ Vector2 get_drag_from();
- void make_current();
+ void set_resizable(bool p_enable);
+ bool is_resizable() const;
- int get_window_width();
- int get_window_height();
- void swap_buffers();
+ void set_draggable(bool p_draggable);
+ bool is_draggable();
- void set_use_vsync(bool use) { vsync = use; }
- bool is_using_vsync() const { return vsync; }
+ void set_selectable(bool p_selectable);
+ bool is_selectable();
- Error initialize();
- void reset();
+ virtual Size2 get_minimum_size() const override;
- void cleanup();
+ bool is_resizing() const {
+ return resizing;
+ }
- ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver);
- ~ContextEGL_UWP();
+ GraphElement() {}
};
-#endif // CONTEXT_EGL_UWP_H
+#endif // GRAPH_ELEMENT_H
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 2223beafda..385b564b7c 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -31,8 +31,8 @@
#include "graph_node.h"
#include "core/string/translation.h"
-
-#include "graph_edit.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/label.h"
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;
@@ -42,72 +42,83 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
}
int idx = str.get_slice("/", 1).to_int();
- String what = str.get_slice("/", 2);
-
- Slot si;
- if (slot_info.has(idx)) {
- si = slot_info[idx];
- }
-
- if (what == "left_enabled") {
- si.enable_left = p_value;
- } else if (what == "left_type") {
- si.type_left = p_value;
- } else if (what == "left_icon") {
- si.custom_slot_left = p_value;
- } else if (what == "left_color") {
- si.color_left = p_value;
- } else if (what == "right_enabled") {
- si.enable_right = p_value;
- } else if (what == "right_type") {
- si.type_right = p_value;
- } else if (what == "right_color") {
- si.color_right = p_value;
- } else if (what == "right_icon") {
- si.custom_slot_right = p_value;
- } else if (what == "draw_stylebox") {
- si.draw_stylebox = p_value;
+ String slot_property_name = str.get_slice("/", 2);
+
+ Slot slot;
+ if (slot_table.has(idx)) {
+ slot = slot_table[idx];
+ }
+
+ if (slot_property_name == "left_enabled") {
+ slot.enable_left = p_value;
+ } else if (slot_property_name == "left_type") {
+ slot.type_left = p_value;
+ } else if (slot_property_name == "left_icon") {
+ slot.custom_port_icon_left = p_value;
+ } else if (slot_property_name == "left_color") {
+ slot.color_left = p_value;
+ } else if (slot_property_name == "right_enabled") {
+ slot.enable_right = p_value;
+ } else if (slot_property_name == "right_type") {
+ slot.type_right = p_value;
+ } else if (slot_property_name == "right_color") {
+ slot.color_right = p_value;
+ } else if (slot_property_name == "right_icon") {
+ slot.custom_port_icon_right = p_value;
+ } else if (slot_property_name == "draw_stylebox") {
+ slot.draw_stylebox = p_value;
} else {
return false;
}
- set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right, si.draw_stylebox);
+ set_slot(idx,
+ slot.enable_left,
+ slot.type_left,
+ slot.color_left,
+ slot.enable_right,
+ slot.type_right,
+ slot.color_right,
+ slot.custom_port_icon_left,
+ slot.custom_port_icon_right,
+ slot.draw_stylebox);
+
queue_redraw();
return true;
}
bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
String str = p_name;
+
if (!str.begins_with("slot/")) {
return false;
}
int idx = str.get_slice("/", 1).to_int();
- String what = str.get_slice("/", 2);
-
- Slot si;
- if (slot_info.has(idx)) {
- si = slot_info[idx];
- }
-
- if (what == "left_enabled") {
- r_ret = si.enable_left;
- } else if (what == "left_type") {
- r_ret = si.type_left;
- } else if (what == "left_color") {
- r_ret = si.color_left;
- } else if (what == "left_icon") {
- r_ret = si.custom_slot_left;
- } else if (what == "right_enabled") {
- r_ret = si.enable_right;
- } else if (what == "right_type") {
- r_ret = si.type_right;
- } else if (what == "right_color") {
- r_ret = si.color_right;
- } else if (what == "right_icon") {
- r_ret = si.custom_slot_right;
- } else if (what == "draw_stylebox") {
- r_ret = si.draw_stylebox;
+ StringName slot_property_name = str.get_slice("/", 2);
+
+ Slot slot;
+ if (slot_table.has(idx)) {
+ slot = slot_table[idx];
+ }
+
+ if (slot_property_name == "left_enabled") {
+ r_ret = slot.enable_left;
+ } else if (slot_property_name == "left_type") {
+ r_ret = slot.type_left;
+ } else if (slot_property_name == "left_color") {
+ r_ret = slot.color_left;
+ } else if (slot_property_name == "left_icon") {
+ r_ret = slot.custom_port_icon_left;
+ } else if (slot_property_name == "right_enabled") {
+ r_ret = slot.enable_right;
+ } else if (slot_property_name == "right_type") {
+ r_ret = slot.type_right;
+ } else if (slot_property_name == "right_color") {
+ r_ret = slot.color_right;
+ } else if (slot_property_name == "right_icon") {
+ r_ret = slot.custom_port_icon_right;
+ } else if (slot_property_name == "draw_stylebox") {
+ r_ret = slot.draw_stylebox;
} else {
return false;
}
@@ -117,9 +128,9 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
int idx = 0;
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || c->is_set_as_top_level()) {
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+ if (!child || child->is_set_as_top_level()) {
continue;
}
@@ -139,43 +150,51 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GraphNode::_resort() {
- /** First pass, determine minimum size AND amount of stretchable elements */
+ Size2 new_size = get_size();
+ Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
+ Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
- Size2i new_size = get_size();
- Ref<StyleBox> sb = get_theme_stylebox(SNAME("frame"));
- Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
+ // Resort titlebar first.
+ Size2 titlebar_size = Size2(new_size.width, titlebar_hbox->get_size().height);
+ titlebar_size -= sb_titlebar->get_minimum_size();
+ Rect2 titlebar_rect = Rect2(sb_titlebar->get_offset(), titlebar_size);
+ fit_child_in_rect(titlebar_hbox, titlebar_rect);
- int sep = get_theme_constant(SNAME("separation"));
+ // After resort, the children of the titlebar container may have changed their height (e.g. Label autowrap).
+ Size2i titlebar_min_size = titlebar_hbox->get_combined_minimum_size();
+
+ // First pass, determine minimum size AND amount of stretchable elements.
+ Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
+ int separation = get_theme_constant(SNAME("separation"));
- bool first = true;
int children_count = 0;
int stretch_min = 0;
- int stretch_avail = 0;
+ int available_stretch_space = 0;
float stretch_ratio_total = 0;
HashMap<Control *, _MinSizeCache> min_size_cache;
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree()) {
- continue;
- }
- if (c->is_set_as_top_level()) {
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+
+ if (!child || !child->is_visible_in_tree() || child->is_set_as_top_level()) {
continue;
}
- Size2i size = c->get_combined_minimum_size() + (slot_info[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2());
- _MinSizeCache msc;
+ Size2i size = child->get_combined_minimum_size() + (slot_table[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2());
stretch_min += size.height;
+
+ _MinSizeCache msc;
msc.min_size = size.height;
- msc.will_stretch = c->get_v_size_flags().has_flag(SIZE_EXPAND);
+ msc.will_stretch = child->get_v_size_flags().has_flag(SIZE_EXPAND);
+ msc.final_size = msc.min_size;
+ min_size_cache[child] = msc;
if (msc.will_stretch) {
- stretch_avail += msc.min_size;
- stretch_ratio_total += c->get_stretch_ratio();
+ available_stretch_space += msc.min_size;
+ stretch_ratio_total += child->get_stretch_ratio();
}
- msc.final_size = msc.min_size;
- min_size_cache[c] = msc;
+
children_count++;
}
@@ -183,43 +202,38 @@ void GraphNode::_resort() {
return;
}
- int stretch_max = new_size.height - (children_count - 1) * sep;
+ int stretch_max = new_size.height - (children_count - 1) * separation;
int stretch_diff = stretch_max - stretch_min;
- if (stretch_diff < 0) {
- //avoid negative stretch space
- stretch_diff = 0;
- }
- stretch_avail += stretch_diff - sb->get_margin(SIDE_BOTTOM) - sb->get_margin(SIDE_TOP); //available stretch space.
- /** Second, pass successively to discard elements that can't be stretched, this will run while stretchable
- elements exist */
+ // Avoid negative stretch space.
+ stretch_diff = MAX(stretch_diff, 0);
- while (stretch_ratio_total > 0) { // first of all, don't even be here if no stretchable objects exist
- bool refit_successful = true; //assume refit-test will go well
+ available_stretch_space += stretch_diff - sb_panel->get_margin(SIDE_BOTTOM) - sb_panel->get_margin(SIDE_TOP);
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree()) {
- continue;
- }
- if (c->is_set_as_top_level()) {
+ // Second pass, discard elements that can't be stretched, this will run while stretchable elements exist.
+
+ while (stretch_ratio_total > 0) {
+ // First of all, don't even be here if no stretchable objects exist.
+ bool refit_successful = true;
+
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+ if (!child || !child->is_visible_in_tree() || child->is_set_as_top_level()) {
continue;
}
- ERR_FAIL_COND(!min_size_cache.has(c));
- _MinSizeCache &msc = min_size_cache[c];
-
- if (msc.will_stretch) { //wants to stretch
- //let's see if it can really stretch
+ ERR_FAIL_COND(!min_size_cache.has(child));
+ _MinSizeCache &msc = min_size_cache[child];
- int final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
+ if (msc.will_stretch) {
+ int final_pixel_size = available_stretch_space * child->get_stretch_ratio() / stretch_ratio_total;
if (final_pixel_size < msc.min_size) {
- //if available stretching area is too small for widget,
- //then remove it from stretching area
+ // If the available stretching area is too small for a Control,
+ // then remove it from stretching area.
msc.will_stretch = false;
- stretch_ratio_total -= c->get_stretch_ratio();
+ stretch_ratio_total -= child->get_stretch_ratio();
refit_successful = false;
- stretch_avail -= msc.min_size;
+ available_stretch_space -= msc.min_size;
msc.final_size = msc.min_size;
break;
} else {
@@ -228,786 +242,514 @@ void GraphNode::_resort() {
}
}
- if (refit_successful) { //uf refit went well, break
+ if (refit_successful) {
break;
}
}
- /** Final pass, draw and stretch elements **/
+ // Final pass, draw and stretch elements.
- int ofs = sb->get_margin(SIDE_TOP);
-
- first = true;
- int idx = 0;
- cache_y.clear();
- int w = new_size.width - sb->get_minimum_size().x;
+ int ofs_y = sb_panel->get_margin(SIDE_TOP) + titlebar_min_size.height + sb_titlebar->get_minimum_size().height;
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree()) {
+ slot_y_cache.clear();
+ int width = new_size.width - sb_panel->get_minimum_size().width;
+ int valid_children_idx = 0;
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+ if (!child || !child->is_visible_in_tree() || child->is_set_as_top_level()) {
continue;
}
- if (c->is_set_as_top_level()) {
- continue;
+
+ _MinSizeCache &msc = min_size_cache[child];
+
+ if (valid_children_idx > 0) {
+ ofs_y += separation;
}
- _MinSizeCache &msc = min_size_cache[c];
+ int from_y_pos = ofs_y;
+ int to_y_pos = ofs_y + msc.final_size;
- if (first) {
- first = false;
- } else {
- ofs += sep;
+ // Adjust so the last valid child always fits perfect, compensating for numerical imprecision.
+ if (msc.will_stretch && valid_children_idx == children_count - 1) {
+ to_y_pos = new_size.height - sb_panel->get_margin(SIDE_BOTTOM);
}
- int from = ofs;
- int to = ofs + msc.final_size;
+ int height = to_y_pos - from_y_pos;
+ float margin = sb_panel->get_margin(SIDE_LEFT) + (slot_table[i].draw_stylebox ? sb_slot->get_margin(SIDE_LEFT) : 0);
+ float final_width = width - (slot_table[i].draw_stylebox ? sb_slot->get_minimum_size().x : 0);
+ Rect2 rect(margin, from_y_pos, final_width, height);
+ fit_child_in_rect(child, rect);
- if (msc.will_stretch && idx == children_count - 1) {
- //adjust so the last one always fits perfect
- //compensating for numerical imprecision
+ slot_y_cache.push_back(from_y_pos - sb_panel->get_margin(SIDE_TOP) + height * 0.5);
- to = new_size.height - sb->get_margin(SIDE_BOTTOM);
- }
+ ofs_y = to_y_pos;
+ valid_children_idx++;
+ }
- int size = to - from;
+ queue_redraw();
+ port_pos_dirty = true;
+}
- float margin = sb->get_margin(SIDE_LEFT) + (slot_info[i].draw_stylebox ? sb_slot->get_margin(SIDE_LEFT) : 0);
- float width = w - (slot_info[i].draw_stylebox ? sb_slot->get_minimum_size().x : 0);
- Rect2 rect(margin, from, width, size);
+void GraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) {
+ if (GDVIRTUAL_CALL(_draw_port, p_slot_index, p_pos, p_left, p_color)) {
+ return;
+ }
- fit_child_in_rect(c, rect);
- cache_y.push_back(from - sb->get_margin(SIDE_TOP) + size * 0.5);
+ Slot slot = slot_table[p_slot_index];
+ Ref<Texture2D> port_icon = p_left ? slot.custom_port_icon_left : slot.custom_port_icon_right;
- ofs = to;
- idx++;
+ Point2 icon_offset;
+ if (!port_icon.is_valid()) {
+ port_icon = get_theme_icon(SNAME("port"));
}
- queue_redraw();
- connpos_dirty = true;
+ icon_offset = -port_icon->get_size() * 0.5;
+ port_icon->draw(get_canvas_item(), p_pos + icon_offset, p_color);
}
void GraphNode::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
- Ref<StyleBox> sb;
-
- sb = get_theme_stylebox(selected ? SNAME("selected_frame") : SNAME("frame"));
+ // Used for layout calculations.
+ Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
+ Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
+ // Used for drawing.
+ Ref<StyleBox> sb_to_draw_panel = get_theme_stylebox(selected ? SNAME("panel_selected") : SNAME("panel"));
+ Ref<StyleBox> sb_to_draw_titlebar = get_theme_stylebox(selected ? SNAME("titlebar_selected") : SNAME("titlebar"));
Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
- Ref<Texture2D> port = get_theme_icon(SNAME("port"));
- Ref<Texture2D> close = get_theme_icon(SNAME("close"));
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
- int close_offset = get_theme_constant(SNAME("close_offset"));
- int close_h_offset = get_theme_constant(SNAME("close_h_offset"));
- Color close_color = get_theme_color(SNAME("close_color"));
+ int port_h_offset = get_theme_constant(SNAME("port_h_offset"));
+
+ Ref<Texture2D> resizer_icon = get_theme_icon(SNAME("resizer"));
+
Color resizer_color = get_theme_color(SNAME("resizer_color"));
- int title_offset = get_theme_constant(SNAME("title_offset"));
- int title_h_offset = get_theme_constant(SNAME("title_h_offset"));
- Color title_color = get_theme_color(SNAME("title_color"));
- Point2i icofs = -port->get_size() * 0.5;
- int edgeofs = get_theme_constant(SNAME("port_offset"));
- icofs.y += sb->get_margin(SIDE_TOP);
-
- draw_style_box(sb, Rect2(Point2(), get_size()));
-
- switch (overlay) {
- case OVERLAY_DISABLED: {
- } break;
- case OVERLAY_BREAKPOINT: {
- draw_style_box(get_theme_stylebox(SNAME("breakpoint")), Rect2(Point2(), get_size()));
- } break;
- case OVERLAY_POSITION: {
- draw_style_box(get_theme_stylebox(SNAME("position")), Rect2(Point2(), get_size()));
-
- } break;
- }
- int w = get_size().width - sb->get_minimum_size().x;
+ Rect2 titlebar_rect(Point2(), titlebar_hbox->get_size() + sb_titlebar->get_minimum_size());
+ Size2 body_size = get_size();
+ titlebar_rect.size.width = body_size.width;
+ body_size.height -= titlebar_rect.size.height;
+ Rect2 body_rect(0, titlebar_rect.size.height, body_size.width, body_size.height);
- title_buf->draw(get_canvas_item(), Point2(sb->get_margin(SIDE_LEFT) + title_h_offset, -title_buf->get_size().y + title_offset), title_color);
- if (show_close) {
- Vector2 cpos = Point2(w + sb->get_margin(SIDE_LEFT) + close_h_offset - close->get_width(), -close->get_height() + close_offset);
- draw_texture(close, cpos, close_color);
- close_rect.position = cpos;
- close_rect.size = close->get_size();
- } else {
- close_rect = Rect2();
- }
+ // Draw body (slots area) stylebox.
+ draw_style_box(sb_to_draw_panel, body_rect);
+
+ // Draw title bar stylebox above.
+ draw_style_box(sb_to_draw_titlebar, titlebar_rect);
+
+ int width = get_size().width - sb_panel->get_minimum_size().x;
if (get_child_count() > 0) {
- for (const KeyValue<int, Slot> &E : slot_info) {
- if (E.key < 0 || E.key >= cache_y.size()) {
+ int slot_index = 0;
+ for (const KeyValue<int, Slot> &E : slot_table) {
+ if (E.key < 0 || E.key >= slot_y_cache.size()) {
continue;
}
- if (!slot_info.has(E.key)) {
+ if (!slot_table.has(E.key)) {
continue;
}
- const Slot &s = slot_info[E.key];
+ const Slot &slot = slot_table[E.key];
+
// Left port.
- if (s.enable_left) {
- Ref<Texture2D> p = port;
- if (s.custom_slot_left.is_valid()) {
- p = s.custom_slot_left;
- }
- p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E.key]), s.color_left);
+ if (slot.enable_left) {
+ draw_port(slot_index, Point2i(port_h_offset, slot_y_cache[E.key] + sb_panel->get_margin(SIDE_TOP)), true, slot.color_left);
}
+
// Right port.
- if (s.enable_right) {
- Ref<Texture2D> p = port;
- if (s.custom_slot_right.is_valid()) {
- p = s.custom_slot_right;
- }
- p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E.key]), s.color_right);
+ if (slot.enable_right) {
+ draw_port(slot_index, Point2i(get_size().x - port_h_offset, slot_y_cache[E.key] + sb_panel->get_margin(SIDE_TOP)), false, slot.color_right);
}
// Draw slot stylebox.
- if (s.draw_stylebox) {
- Control *c = Object::cast_to<Control>(get_child(E.key));
- if (!c || !c->is_visible_in_tree()) {
- continue;
- }
- if (c->is_set_as_top_level()) {
+ if (slot.draw_stylebox) {
+ Control *child = Object::cast_to<Control>(get_child(E.key, false));
+ if (!child || !child->is_visible_in_tree()) {
continue;
}
- Rect2 c_rect = c->get_rect();
- c_rect.position.x = sb->get_margin(SIDE_LEFT);
- c_rect.size.width = w;
- draw_style_box(sb_slot, c_rect);
+ Rect2 child_rect = child->get_rect();
+ child_rect.position.x = sb_panel->get_margin(SIDE_LEFT);
+ child_rect.size.width = width;
+ draw_style_box(sb_slot, child_rect);
}
+
+ slot_index++;
}
}
if (resizable) {
- draw_texture(resizer, get_size() - resizer->get_size(), resizer_color);
+ draw_texture(resizer_icon, get_size() - resizer_icon->get_size(), resizer_color);
}
} break;
-
- case NOTIFICATION_SORT_CHILDREN: {
- _resort();
- } break;
-
- case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
- case NOTIFICATION_TRANSLATION_CHANGED:
- case NOTIFICATION_THEME_CHANGED: {
- _shape();
-
- update_minimum_size();
- queue_redraw();
- } break;
}
}
-void GraphNode::_shape() {
- Ref<Font> font = get_theme_font(SNAME("title_font"));
- int font_size = get_theme_font_size(SNAME("title_font_size"));
-
- title_buf->clear();
- if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
- title_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
- } else {
- title_buf->set_direction((TextServer::Direction)text_direction);
- }
- title_buf->add_string(title, font, font_size, language);
-}
-
-#ifdef TOOLS_ENABLED
-void GraphNode::_edit_set_position(const Point2 &p_position) {
- GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
- if (graph) {
- Point2 offset = (p_position + graph->get_scroll_offset()) * graph->get_zoom();
- set_position_offset(offset);
- }
- set_position(p_position);
-}
-#endif
-
-void GraphNode::_validate_property(PropertyInfo &p_property) const {
- GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
- if (graph) {
- if (p_property.name == "position") {
- p_property.usage |= PROPERTY_USAGE_READ_ONLY;
- }
- }
-}
-
-void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right, bool p_draw_stylebox) {
- ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set slot with p_idx (%d) lesser than zero.", p_idx));
+void GraphNode::set_slot(int p_slot_index, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right, bool p_draw_stylebox) {
+ ERR_FAIL_COND_MSG(p_slot_index < 0, vformat("Cannot set slot with index (%d) lesser than zero.", p_slot_index));
if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) &&
!p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1) &&
!p_custom_left.is_valid() && !p_custom_right.is_valid()) {
- slot_info.erase(p_idx);
+ slot_table.erase(p_slot_index);
return;
}
- Slot s;
- s.enable_left = p_enable_left;
- s.type_left = p_type_left;
- s.color_left = p_color_left;
- s.enable_right = p_enable_right;
- s.type_right = p_type_right;
- s.color_right = p_color_right;
- s.custom_slot_left = p_custom_left;
- s.custom_slot_right = p_custom_right;
- s.draw_stylebox = p_draw_stylebox;
- slot_info[p_idx] = s;
+ Slot slot;
+ slot.enable_left = p_enable_left;
+ slot.type_left = p_type_left;
+ slot.color_left = p_color_left;
+ slot.enable_right = p_enable_right;
+ slot.type_right = p_type_right;
+ slot.color_right = p_color_right;
+ slot.custom_port_icon_left = p_custom_left;
+ slot.custom_port_icon_right = p_custom_right;
+ slot.draw_stylebox = p_draw_stylebox;
+ slot_table[p_slot_index] = slot;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-void GraphNode::clear_slot(int p_idx) {
- slot_info.erase(p_idx);
+void GraphNode::clear_slot(int p_slot_index) {
+ slot_table.erase(p_slot_index);
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
}
void GraphNode::clear_all_slots() {
- slot_info.clear();
+ slot_table.clear();
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
}
-bool GraphNode::is_slot_enabled_left(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+bool GraphNode::is_slot_enabled_left(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return false;
}
- return slot_info[p_idx].enable_left;
+ return slot_table[p_slot_index].enable_left;
}
-void GraphNode::set_slot_enabled_left(int p_idx, bool p_enable_left) {
- ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_left for the slot with p_idx (%d) lesser than zero.", p_idx));
+void GraphNode::set_slot_enabled_left(int p_slot_index, bool p_enable) {
+ ERR_FAIL_COND_MSG(p_slot_index < 0, vformat("Cannot set enable_left for the slot with index (%d) lesser than zero.", p_slot_index));
- if (slot_info[p_idx].enable_left == p_enable_left) {
+ if (slot_table[p_slot_index].enable_left == p_enable) {
return;
}
- slot_info[p_idx].enable_left = p_enable_left;
+ slot_table[p_slot_index].enable_left = p_enable;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-void GraphNode::set_slot_type_left(int p_idx, int p_type_left) {
- ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_left for the slot '%d' because it hasn't been enabled.", p_idx));
+void GraphNode::set_slot_type_left(int p_slot_index, int p_type) {
+ ERR_FAIL_COND_MSG(!slot_table.has(p_slot_index), vformat("Cannot set type_left for the slot with index '%d' because it hasn't been enabled.", p_slot_index));
- if (slot_info[p_idx].type_left == p_type_left) {
+ if (slot_table[p_slot_index].type_left == p_type) {
return;
}
- slot_info[p_idx].type_left = p_type_left;
+ slot_table[p_slot_index].type_left = p_type;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-int GraphNode::get_slot_type_left(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+int GraphNode::get_slot_type_left(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return 0;
}
- return slot_info[p_idx].type_left;
+ return slot_table[p_slot_index].type_left;
}
-void GraphNode::set_slot_color_left(int p_idx, const Color &p_color_left) {
- ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_left for the slot '%d' because it hasn't been enabled.", p_idx));
+void GraphNode::set_slot_color_left(int p_slot_index, const Color &p_color) {
+ ERR_FAIL_COND_MSG(!slot_table.has(p_slot_index), vformat("Cannot set color_left for the slot with index '%d' because it hasn't been enabled.", p_slot_index));
- if (slot_info[p_idx].color_left == p_color_left) {
+ if (slot_table[p_slot_index].color_left == p_color) {
return;
}
- slot_info[p_idx].color_left = p_color_left;
+ slot_table[p_slot_index].color_left = p_color;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-Color GraphNode::get_slot_color_left(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+Color GraphNode::get_slot_color_left(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return Color(1, 1, 1, 1);
}
- return slot_info[p_idx].color_left;
+ return slot_table[p_slot_index].color_left;
}
-bool GraphNode::is_slot_enabled_right(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+bool GraphNode::is_slot_enabled_right(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return false;
}
- return slot_info[p_idx].enable_right;
+ return slot_table[p_slot_index].enable_right;
}
-void GraphNode::set_slot_enabled_right(int p_idx, bool p_enable_right) {
- ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_right for the slot with p_idx (%d) lesser than zero.", p_idx));
+void GraphNode::set_slot_enabled_right(int p_slot_index, bool p_enable) {
+ ERR_FAIL_COND_MSG(p_slot_index < 0, vformat("Cannot set enable_right for the slot with index (%d) lesser than zero.", p_slot_index));
- if (slot_info[p_idx].enable_right == p_enable_right) {
+ if (slot_table[p_slot_index].enable_right == p_enable) {
return;
}
- slot_info[p_idx].enable_right = p_enable_right;
+ slot_table[p_slot_index].enable_right = p_enable;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-void GraphNode::set_slot_type_right(int p_idx, int p_type_right) {
- ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_right for the slot '%d' because it hasn't been enabled.", p_idx));
+void GraphNode::set_slot_type_right(int p_slot_index, int p_type) {
+ ERR_FAIL_COND_MSG(!slot_table.has(p_slot_index), vformat("Cannot set type_right for the slot with index '%d' because it hasn't been enabled.", p_slot_index));
- if (slot_info[p_idx].type_right == p_type_right) {
+ if (slot_table[p_slot_index].type_right == p_type) {
return;
}
- slot_info[p_idx].type_right = p_type_right;
+ slot_table[p_slot_index].type_right = p_type;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-int GraphNode::get_slot_type_right(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+int GraphNode::get_slot_type_right(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return 0;
}
- return slot_info[p_idx].type_right;
+ return slot_table[p_slot_index].type_right;
}
-void GraphNode::set_slot_color_right(int p_idx, const Color &p_color_right) {
- ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_right for the slot '%d' because it hasn't been enabled.", p_idx));
+void GraphNode::set_slot_color_right(int p_slot_index, const Color &p_color) {
+ ERR_FAIL_COND_MSG(!slot_table.has(p_slot_index), vformat("Cannot set color_right for the slot with index '%d' because it hasn't been enabled.", p_slot_index));
- if (slot_info[p_idx].color_right == p_color_right) {
+ if (slot_table[p_slot_index].color_right == p_color) {
return;
}
- slot_info[p_idx].color_right = p_color_right;
+ slot_table[p_slot_index].color_right = p_color;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
-Color GraphNode::get_slot_color_right(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+Color GraphNode::get_slot_color_right(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return Color(1, 1, 1, 1);
}
- return slot_info[p_idx].color_right;
+ return slot_table[p_slot_index].color_right;
}
-bool GraphNode::is_slot_draw_stylebox(int p_idx) const {
- if (!slot_info.has(p_idx)) {
+bool GraphNode::is_slot_draw_stylebox(int p_slot_index) const {
+ if (!slot_table.has(p_slot_index)) {
return false;
}
- return slot_info[p_idx].draw_stylebox;
+ return slot_table[p_slot_index].draw_stylebox;
}
-void GraphNode::set_slot_draw_stylebox(int p_idx, bool p_enable) {
- ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set draw_stylebox for the slot with p_idx (%d) lesser than zero.", p_idx));
+void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) {
+ ERR_FAIL_COND_MSG(p_slot_index < 0, vformat("Cannot set draw_stylebox for the slot with p_index (%d) lesser than zero.", p_slot_index));
- slot_info[p_idx].draw_stylebox = p_enable;
+ slot_table[p_slot_index].draw_stylebox = p_enable;
queue_redraw();
- connpos_dirty = true;
+ port_pos_dirty = true;
- emit_signal(SNAME("slot_updated"), p_idx);
+ emit_signal(SNAME("slot_updated"), p_slot_index);
}
Size2 GraphNode::get_minimum_size() const {
- Ref<StyleBox> sb = get_theme_stylebox(SNAME("frame"));
+ Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
+ Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
- int sep = get_theme_constant(SNAME("separation"));
- int title_h_offset = get_theme_constant(SNAME("title_h_offset"));
-
- bool first = true;
+ int separation = get_theme_constant(SNAME("separation"));
+ Size2 minsize = titlebar_hbox->get_minimum_size() + sb_titlebar->get_minimum_size();
- Size2 minsize;
- minsize.x = title_buf->get_size().x + title_h_offset;
- if (show_close) {
- int close_h_offset = get_theme_constant(SNAME("close_h_offset"));
- Ref<Texture2D> close = get_theme_icon(SNAME("close"));
- //TODO: Remove this magic number after GraphNode rework.
- minsize.x += 12 + close->get_width() + close_h_offset;
- }
-
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible()) {
- continue;
- }
- if (c->is_set_as_top_level()) {
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+ if (!child || !child->is_visible() || child->is_set_as_top_level()) {
continue;
}
- Size2i size = c->get_combined_minimum_size();
- if (slot_info.has(i)) {
- size += slot_info[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2();
+ Size2i size = child->get_combined_minimum_size();
+ size.width += sb_panel->get_minimum_size().width;
+ if (slot_table.has(i)) {
+ size += slot_table[i].draw_stylebox ? sb_slot->get_minimum_size() : Size2();
}
- minsize.y += size.y;
- minsize.x = MAX(minsize.x, size.x);
+ minsize.height += size.height;
+ minsize.width = MAX(minsize.width, size.width);
- if (first) {
- first = false;
- } else {
- minsize.y += sep;
+ if (i > 0) {
+ minsize.height += separation;
}
}
- return minsize + sb->get_minimum_size();
-}
-
-void GraphNode::set_title(const String &p_title) {
- if (title == p_title) {
- return;
- }
- title = p_title;
- _shape();
-
- queue_redraw();
- update_minimum_size();
-}
-
-String GraphNode::get_title() const {
- return title;
-}
-
-void GraphNode::set_text_direction(Control::TextDirection p_text_direction) {
- ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
- if (text_direction != p_text_direction) {
- text_direction = p_text_direction;
- _shape();
- queue_redraw();
- }
-}
+ minsize.height += sb_panel->get_minimum_size().height;
-Control::TextDirection GraphNode::get_text_direction() const {
- return text_direction;
+ return minsize;
}
-void GraphNode::set_language(const String &p_language) {
- if (language != p_language) {
- language = p_language;
- _shape();
- queue_redraw();
- }
-}
+void GraphNode::_port_pos_update() {
+ int edgeofs = get_theme_constant(SNAME("port_h_offset"));
+ int separation = get_theme_constant(SNAME("separation"));
-String GraphNode::get_language() const {
- return language;
-}
+ Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
+ Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
-void GraphNode::set_position_offset(const Vector2 &p_offset) {
- if (position_offset == p_offset) {
- return;
- }
-
- position_offset = p_offset;
- emit_signal(SNAME("position_offset_changed"));
- queue_redraw();
-}
-
-Vector2 GraphNode::get_position_offset() const {
- return position_offset;
-}
-
-void GraphNode::set_selected(bool p_selected) {
- if (!is_selectable() || selected == p_selected) {
- return;
- }
-
- selected = p_selected;
- emit_signal(p_selected ? SNAME("node_selected") : SNAME("node_deselected"));
- queue_redraw();
-}
-
-bool GraphNode::is_selected() {
- return selected;
-}
-
-void GraphNode::set_drag(bool p_drag) {
- if (p_drag) {
- drag_from = get_position_offset();
- } else {
- emit_signal(SNAME("dragged"), drag_from, get_position_offset()); //useful for undo/redo
- }
-}
-
-Vector2 GraphNode::get_drag_from() {
- return drag_from;
-}
-
-void GraphNode::set_show_close_button(bool p_enable) {
- if (show_close == p_enable) {
- return;
- }
-
- show_close = p_enable;
- queue_redraw();
-}
-
-bool GraphNode::is_close_button_visible() const {
- return show_close;
-}
-
-void GraphNode::_connpos_update() {
- int edgeofs = get_theme_constant(SNAME("port_offset"));
- int sep = get_theme_constant(SNAME("separation"));
-
- Ref<StyleBox> sb = get_theme_stylebox(SNAME("frame"));
left_port_cache.clear();
right_port_cache.clear();
- int vofs = 0;
-
- int idx = 0;
+ int vertical_ofs = titlebar_hbox->get_size().height + sb_titlebar->get_minimum_size().height + sb_panel->get_margin(SIDE_TOP);
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
+ for (int i = 0; i < get_child_count(false); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i, false));
+ if (!child || child->is_set_as_top_level()) {
continue;
}
- if (c->is_set_as_top_level()) {
- continue;
- }
-
- Size2i size = c->get_rect().size;
- int y = sb->get_margin(SIDE_TOP) + vofs;
- int h = size.height;
+ Size2i size = child->get_rect().size;
- if (slot_info.has(idx)) {
- if (slot_info[idx].enable_left) {
- PortCache cc;
- cc.position = Point2i(edgeofs, y + h / 2);
- cc.height = h;
-
- cc.slot_idx = idx;
- cc.type = slot_info[idx].type_left;
- cc.color = slot_info[idx].color_left;
-
- left_port_cache.push_back(cc);
+ if (slot_table.has(i)) {
+ if (slot_table[i].enable_left) {
+ PortCache port_cache;
+ port_cache.pos = Point2i(edgeofs, vertical_ofs + size.height / 2);
+ port_cache.type = slot_table[i].type_left;
+ port_cache.color = slot_table[i].color_left;
+ port_cache.slot_index = child->get_index(); // Index with internal nodes included.
+ left_port_cache.push_back(port_cache);
}
- if (slot_info[idx].enable_right) {
- PortCache cc;
- cc.position = Point2i(get_size().width - edgeofs, y + h / 2);
- cc.height = h;
-
- cc.slot_idx = idx;
- cc.type = slot_info[idx].type_right;
- cc.color = slot_info[idx].color_right;
-
- right_port_cache.push_back(cc);
+ if (slot_table[i].enable_right) {
+ PortCache port_cache;
+ port_cache.pos = Point2i(get_size().width - edgeofs, vertical_ofs + size.height / 2);
+ port_cache.type = slot_table[i].type_right;
+ port_cache.color = slot_table[i].color_right;
+ port_cache.slot_index = child->get_index(); // Index with internal nodes included.
+ right_port_cache.push_back(port_cache);
}
}
- vofs += sep;
- vofs += h;
- idx++;
+ vertical_ofs += separation;
+ vertical_ofs += size.height;
}
- connpos_dirty = false;
+ port_pos_dirty = false;
}
-int GraphNode::get_connection_input_count() {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_input_port_count() {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
return left_port_cache.size();
}
-int GraphNode::get_connection_input_height(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_output_port_count() {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), 0);
- return left_port_cache[p_port].height;
+ return right_port_cache.size();
}
-Vector2 GraphNode::get_connection_input_position(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+Vector2 GraphNode::get_input_port_position(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), Vector2());
- Vector2 pos = left_port_cache[p_port].position;
- pos.x *= get_scale().x;
- pos.y *= get_scale().y;
+ ERR_FAIL_INDEX_V(p_port_idx, left_port_cache.size(), Vector2());
+ Vector2 pos = left_port_cache[p_port_idx].pos;
return pos;
}
-int GraphNode::get_connection_input_type(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
- }
-
- ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), 0);
- return left_port_cache[p_port].type;
-}
-
-Color GraphNode::get_connection_input_color(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
- }
-
- ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), Color());
- return left_port_cache[p_port].color;
-}
-
-int GraphNode::get_connection_input_slot(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_input_port_type(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, left_port_cache.size(), -1);
- return left_port_cache[p_port].slot_idx;
+ ERR_FAIL_INDEX_V(p_port_idx, left_port_cache.size(), 0);
+ return left_port_cache[p_port_idx].type;
}
-int GraphNode::get_connection_output_count() {
- if (connpos_dirty) {
- _connpos_update();
+Color GraphNode::get_input_port_color(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- return right_port_cache.size();
+ ERR_FAIL_INDEX_V(p_port_idx, left_port_cache.size(), Color());
+ return left_port_cache[p_port_idx].color;
}
-int GraphNode::get_connection_output_height(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_input_port_slot(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), 0);
- return right_port_cache[p_port].height;
+ ERR_FAIL_INDEX_V(p_port_idx, left_port_cache.size(), -1);
+ return left_port_cache[p_port_idx].slot_index;
}
-Vector2 GraphNode::get_connection_output_position(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+Vector2 GraphNode::get_output_port_position(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), Vector2());
- Vector2 pos = right_port_cache[p_port].position;
- pos.x *= get_scale().x;
- pos.y *= get_scale().y;
+ ERR_FAIL_INDEX_V(p_port_idx, right_port_cache.size(), Vector2());
+ Vector2 pos = right_port_cache[p_port_idx].pos;
return pos;
}
-int GraphNode::get_connection_output_type(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_output_port_type(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), 0);
- return right_port_cache[p_port].type;
+ ERR_FAIL_INDEX_V(p_port_idx, right_port_cache.size(), 0);
+ return right_port_cache[p_port_idx].type;
}
-Color GraphNode::get_connection_output_color(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+Color GraphNode::get_output_port_color(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), Color());
- return right_port_cache[p_port].color;
+ ERR_FAIL_INDEX_V(p_port_idx, right_port_cache.size(), Color());
+ return right_port_cache[p_port_idx].color;
}
-int GraphNode::get_connection_output_slot(int p_port) {
- if (connpos_dirty) {
- _connpos_update();
+int GraphNode::get_output_port_slot(int p_port_idx) {
+ if (port_pos_dirty) {
+ _port_pos_update();
}
- ERR_FAIL_INDEX_V(p_port, right_port_cache.size(), -1);
- return right_port_cache[p_port].slot_idx;
+ ERR_FAIL_INDEX_V(p_port_idx, right_port_cache.size(), -1);
+ return right_port_cache[p_port_idx].slot_index;
}
-void GraphNode::gui_input(const Ref<InputEvent> &p_ev) {
- ERR_FAIL_COND(p_ev.is_null());
-
- Ref<InputEventMouseButton> mb = p_ev;
- if (mb.is_valid()) {
- ERR_FAIL_COND_MSG(get_parent_control() == nullptr, "GraphNode must be the child of a GraphEdit node.");
-
- if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
- Vector2 mpos = mb->get_position();
- if (close_rect.size != Size2() && close_rect.has_point(mpos)) {
- //send focus to parent
- get_parent_control()->grab_focus();
- emit_signal(SNAME("close_request"));
- accept_event();
- return;
- }
-
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
-
- if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
- resizing = true;
- resizing_from = mpos;
- resizing_from_size = get_size();
- accept_event();
- return;
- }
-
- emit_signal(SNAME("raise_request"));
- }
-
- if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
- resizing = false;
- }
- }
-
- Ref<InputEventMouseMotion> mm = p_ev;
- if (resizing && mm.is_valid()) {
- Vector2 mpos = mm->get_position();
- Vector2 diff = mpos - resizing_from;
-
- emit_signal(SNAME("resize_request"), resizing_from_size + diff);
- }
-}
-
-void GraphNode::set_overlay(Overlay p_overlay) {
- if (overlay == p_overlay) {
+void GraphNode::set_title(const String &p_title) {
+ if (title == p_title) {
return;
}
-
- overlay = p_overlay;
- queue_redraw();
-}
-
-GraphNode::Overlay GraphNode::get_overlay() const {
- return overlay;
-}
-
-void GraphNode::set_resizable(bool p_enable) {
- if (resizable == p_enable) {
- return;
+ title = p_title;
+ if (title_label) {
+ title_label->set_text(title);
}
-
- resizable = p_enable;
- queue_redraw();
-}
-
-bool GraphNode::is_resizable() const {
- return resizable;
-}
-
-void GraphNode::set_draggable(bool p_draggable) {
- draggable = p_draggable;
-}
-
-bool GraphNode::is_draggable() {
- return draggable;
+ update_minimum_size();
}
-void GraphNode::set_selectable(bool p_selectable) {
- if (!p_selectable) {
- set_selected(false);
- }
- selectable = p_selectable;
+String GraphNode::get_title() const {
+ return title;
}
-bool GraphNode::is_selectable() {
- return selectable;
+HBoxContainer *GraphNode::get_titlebar_hbox() {
+ return titlebar_hbox;
}
Control::CursorShape GraphNode::get_cursor_shape(const Point2 &p_pos) const {
@@ -1044,17 +786,15 @@ Vector<int> GraphNode::get_allowed_size_flags_vertical() const {
void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_title", "title"), &GraphNode::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
- ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &GraphNode::set_text_direction);
- ClassDB::bind_method(D_METHOD("get_text_direction"), &GraphNode::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language);
- ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language);
+
+ ClassDB::bind_method(D_METHOD("get_titlebar_hbox"), &GraphNode::get_titlebar_hbox);
ClassDB::bind_method(D_METHOD("set_slot", "slot_index", "enable_left_port", "type_left", "color_left", "enable_right_port", "type_right", "color_right", "custom_icon_left", "custom_icon_right", "draw_stylebox"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("clear_slot", "slot_index"), &GraphNode::clear_slot);
ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots);
- ClassDB::bind_method(D_METHOD("set_slot_enabled_left", "slot_index", "enable"), &GraphNode::set_slot_enabled_left);
ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "slot_index"), &GraphNode::is_slot_enabled_left);
+ ClassDB::bind_method(D_METHOD("set_slot_enabled_left", "slot_index", "enable"), &GraphNode::set_slot_enabled_left);
ClassDB::bind_method(D_METHOD("set_slot_type_left", "slot_index", "type"), &GraphNode::set_slot_type_left);
ClassDB::bind_method(D_METHOD("get_slot_type_left", "slot_index"), &GraphNode::get_slot_type_left);
@@ -1062,8 +802,8 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_slot_color_left", "slot_index", "color"), &GraphNode::set_slot_color_left);
ClassDB::bind_method(D_METHOD("get_slot_color_left", "slot_index"), &GraphNode::get_slot_color_left);
- ClassDB::bind_method(D_METHOD("set_slot_enabled_right", "slot_index", "enable"), &GraphNode::set_slot_enabled_right);
ClassDB::bind_method(D_METHOD("is_slot_enabled_right", "slot_index"), &GraphNode::is_slot_enabled_right);
+ ClassDB::bind_method(D_METHOD("set_slot_enabled_right", "slot_index", "enable"), &GraphNode::set_slot_enabled_right);
ClassDB::bind_method(D_METHOD("set_slot_type_right", "slot_index", "type"), &GraphNode::set_slot_type_right);
ClassDB::bind_method(D_METHOD("get_slot_type_right", "slot_index"), &GraphNode::get_slot_type_right);
@@ -1074,70 +814,33 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "slot_index"), &GraphNode::is_slot_draw_stylebox);
ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "slot_index", "enable"), &GraphNode::set_slot_draw_stylebox);
- ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphNode::set_position_offset);
- ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphNode::get_position_offset);
-
- ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphNode::set_resizable);
- ClassDB::bind_method(D_METHOD("is_resizable"), &GraphNode::is_resizable);
-
- ClassDB::bind_method(D_METHOD("set_draggable", "draggable"), &GraphNode::set_draggable);
- ClassDB::bind_method(D_METHOD("is_draggable"), &GraphNode::is_draggable);
+ ClassDB::bind_method(D_METHOD("get_input_port_count"), &GraphNode::get_input_port_count);
+ ClassDB::bind_method(D_METHOD("get_input_port_position", "port_idx"), &GraphNode::get_input_port_position);
+ ClassDB::bind_method(D_METHOD("get_input_port_type", "port_idx"), &GraphNode::get_input_port_type);
+ ClassDB::bind_method(D_METHOD("get_input_port_color", "port_idx"), &GraphNode::get_input_port_color);
+ ClassDB::bind_method(D_METHOD("get_input_port_slot", "port_idx"), &GraphNode::get_input_port_slot);
- ClassDB::bind_method(D_METHOD("set_selectable", "selectable"), &GraphNode::set_selectable);
- ClassDB::bind_method(D_METHOD("is_selectable"), &GraphNode::is_selectable);
+ ClassDB::bind_method(D_METHOD("get_output_port_count"), &GraphNode::get_output_port_count);
+ ClassDB::bind_method(D_METHOD("get_output_port_position", "port_idx"), &GraphNode::get_output_port_position);
+ ClassDB::bind_method(D_METHOD("get_output_port_type", "port_idx"), &GraphNode::get_output_port_type);
+ ClassDB::bind_method(D_METHOD("get_output_port_color", "port_idx"), &GraphNode::get_output_port_color);
+ ClassDB::bind_method(D_METHOD("get_output_port_slot", "port_idx"), &GraphNode::get_output_port_slot);
- ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphNode::set_selected);
- ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected);
-
- ClassDB::bind_method(D_METHOD("get_connection_input_count"), &GraphNode::get_connection_input_count);
- ClassDB::bind_method(D_METHOD("get_connection_input_height", "port"), &GraphNode::get_connection_input_height);
- ClassDB::bind_method(D_METHOD("get_connection_input_position", "port"), &GraphNode::get_connection_input_position);
- ClassDB::bind_method(D_METHOD("get_connection_input_type", "port"), &GraphNode::get_connection_input_type);
- ClassDB::bind_method(D_METHOD("get_connection_input_color", "port"), &GraphNode::get_connection_input_color);
- ClassDB::bind_method(D_METHOD("get_connection_input_slot", "port"), &GraphNode::get_connection_input_slot);
-
- ClassDB::bind_method(D_METHOD("get_connection_output_count"), &GraphNode::get_connection_output_count);
- ClassDB::bind_method(D_METHOD("get_connection_output_height", "port"), &GraphNode::get_connection_output_height);
- ClassDB::bind_method(D_METHOD("get_connection_output_position", "port"), &GraphNode::get_connection_output_position);
- ClassDB::bind_method(D_METHOD("get_connection_output_type", "port"), &GraphNode::get_connection_output_type);
- ClassDB::bind_method(D_METHOD("get_connection_output_color", "port"), &GraphNode::get_connection_output_color);
- ClassDB::bind_method(D_METHOD("get_connection_output_slot", "port"), &GraphNode::get_connection_output_slot);
-
- ClassDB::bind_method(D_METHOD("set_show_close_button", "show"), &GraphNode::set_show_close_button);
- ClassDB::bind_method(D_METHOD("is_close_button_visible"), &GraphNode::is_close_button_visible);
-
- ClassDB::bind_method(D_METHOD("set_overlay", "overlay"), &GraphNode::set_overlay);
- ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay);
+ GDVIRTUAL_BIND(_draw_port, "slot_index", "position", "left", "color")
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_position_offset", "get_position_offset");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draggable"), "set_draggable", "is_draggable");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selectable"), "set_selectable", "is_selectable");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selected"), "set_selected", "is_selected");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay");
-
- ADD_GROUP("BiDi", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
- ADD_GROUP("", "");
-
- ADD_SIGNAL(MethodInfo("position_offset_changed"));
- ADD_SIGNAL(MethodInfo("node_selected"));
- ADD_SIGNAL(MethodInfo("node_deselected"));
- ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx")));
- ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
- ADD_SIGNAL(MethodInfo("raise_request"));
- ADD_SIGNAL(MethodInfo("close_request"));
- ADD_SIGNAL(MethodInfo("resize_request", PropertyInfo(Variant::VECTOR2, "new_minsize")));
-
- BIND_ENUM_CONSTANT(OVERLAY_DISABLED);
- BIND_ENUM_CONSTANT(OVERLAY_BREAKPOINT);
- BIND_ENUM_CONSTANT(OVERLAY_POSITION);
+ ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index")));
}
GraphNode::GraphNode() {
- title_buf.instantiate();
+ titlebar_hbox = memnew(HBoxContainer);
+ titlebar_hbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(titlebar_hbox, false, INTERNAL_MODE_FRONT);
+
+ title_label = memnew(Label);
+ title_label->set_theme_type_variation("GraphNodeTitleLabel");
+ title_label->set_h_size_flags(SIZE_EXPAND_FILL);
+ titlebar_hbox->add_child(title_label);
+
set_mouse_filter(MOUSE_FILTER_STOP);
}
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 873683bc62..1178421819 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -31,170 +31,111 @@
#ifndef GRAPH_NODE_H
#define GRAPH_NODE_H
-#include "scene/gui/container.h"
-#include "scene/resources/text_line.h"
+#include "scene/gui/graph_element.h"
-class GraphNode : public Container {
- GDCLASS(GraphNode, Container);
+class HBoxContainer;
- struct _MinSizeCache {
- int min_size;
- bool will_stretch;
- int final_size;
- };
+class GraphNode : public GraphElement {
+ GDCLASS(GraphNode, GraphElement);
-public:
- enum Overlay {
- OVERLAY_DISABLED,
- OVERLAY_BREAKPOINT,
- OVERLAY_POSITION
- };
-
-private:
struct Slot {
bool enable_left = false;
int type_left = 0;
Color color_left = Color(1, 1, 1, 1);
+ Ref<Texture2D> custom_port_icon_left;
+
bool enable_right = false;
int type_right = 0;
Color color_right = Color(1, 1, 1, 1);
- Ref<Texture2D> custom_slot_left;
- Ref<Texture2D> custom_slot_right;
+ Ref<Texture2D> custom_port_icon_right;
+
bool draw_stylebox = true;
};
- String title;
- Ref<TextLine> title_buf;
-
- String language;
- TextDirection text_direction = TEXT_DIRECTION_AUTO;
-
- bool show_close = false;
- Vector2 position_offset;
- bool comment = false;
- bool resizable = false;
- bool draggable = true;
- bool selectable = true;
-
- bool resizing = false;
- Vector2 resizing_from;
- Vector2 resizing_from_size;
-
- Rect2 close_rect;
-
- Vector<int> cache_y;
-
struct PortCache {
- Vector2 position;
- int height;
-
- int slot_idx;
+ Vector2 pos;
+ int slot_index;
int type = 0;
Color color;
};
- Vector<PortCache> left_port_cache;
- Vector<PortCache> right_port_cache;
+ struct _MinSizeCache {
+ int min_size;
+ bool will_stretch;
+ int final_size;
+ };
- HashMap<int, Slot> slot_info;
+ HBoxContainer *titlebar_hbox = nullptr;
+ Label *title_label = nullptr;
- bool connpos_dirty = true;
+ String title;
- void _connpos_update();
- void _resort();
- void _shape();
+ Vector<PortCache> left_port_cache;
+ Vector<PortCache> right_port_cache;
- Vector2 drag_from;
- bool selected = false;
+ HashMap<int, Slot> slot_table;
- Overlay overlay = OVERLAY_DISABLED;
+ Vector<int> slot_y_cache;
-#ifdef TOOLS_ENABLED
- void _edit_set_position(const Point2 &p_position) override;
-#endif
+ bool port_pos_dirty = true;
+
+ void _port_pos_update();
protected:
- virtual void gui_input(const Ref<InputEvent> &p_ev) override;
void _notification(int p_what);
static void _bind_methods();
+ virtual void _resort() override;
+
+ virtual void draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color);
+ GDVIRTUAL4(_draw_port, int, Point2i, bool, const Color &);
+
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
- void _validate_property(PropertyInfo &p_property) const;
public:
- void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>(), bool p_draw_stylebox = true);
- void clear_slot(int p_idx);
- void clear_all_slots();
-
- bool is_slot_enabled_left(int p_idx) const;
- void set_slot_enabled_left(int p_idx, bool p_enable_left);
-
- void set_slot_type_left(int p_idx, int p_type_left);
- int get_slot_type_left(int p_idx) const;
-
- void set_slot_color_left(int p_idx, const Color &p_color_left);
- Color get_slot_color_left(int p_idx) const;
-
- bool is_slot_enabled_right(int p_idx) const;
- void set_slot_enabled_right(int p_idx, bool p_enable_right);
-
- void set_slot_type_right(int p_idx, int p_type_right);
- int get_slot_type_right(int p_idx) const;
-
- void set_slot_color_right(int p_idx, const Color &p_color_right);
- Color get_slot_color_right(int p_idx) const;
-
- bool is_slot_draw_stylebox(int p_idx) const;
- void set_slot_draw_stylebox(int p_idx, bool p_enable);
-
void set_title(const String &p_title);
String get_title() const;
- void set_text_direction(TextDirection p_text_direction);
- TextDirection get_text_direction() const;
-
- void set_language(const String &p_language);
- String get_language() const;
+ HBoxContainer *get_titlebar_hbox();
- void set_position_offset(const Vector2 &p_offset);
- Vector2 get_position_offset() const;
+ void set_slot(int p_slot_index, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>(), bool p_draw_stylebox = true);
+ void clear_slot(int p_slot_index);
+ void clear_all_slots();
- void set_selected(bool p_selected);
- bool is_selected();
+ bool is_slot_enabled_left(int p_slot_index) const;
+ void set_slot_enabled_left(int p_slot_index, bool p_enable);
- void set_drag(bool p_drag);
- Vector2 get_drag_from();
+ void set_slot_type_left(int p_slot_index, int p_type);
+ int get_slot_type_left(int p_slot_index) const;
- void set_show_close_button(bool p_enable);
- bool is_close_button_visible() const;
+ void set_slot_color_left(int p_slot_index, const Color &p_color);
+ Color get_slot_color_left(int p_slot_index) const;
- int get_connection_input_count();
- int get_connection_input_height(int p_port);
- Vector2 get_connection_input_position(int p_port);
- int get_connection_input_type(int p_port);
- Color get_connection_input_color(int p_port);
- int get_connection_input_slot(int p_port);
+ bool is_slot_enabled_right(int p_slot_index) const;
+ void set_slot_enabled_right(int p_slot_index, bool p_enable);
- int get_connection_output_count();
- int get_connection_output_height(int p_port);
- Vector2 get_connection_output_position(int p_port);
- int get_connection_output_type(int p_port);
- Color get_connection_output_color(int p_port);
- int get_connection_output_slot(int p_port);
+ void set_slot_type_right(int p_slot_index, int p_type);
+ int get_slot_type_right(int p_slot_index) const;
- void set_overlay(Overlay p_overlay);
- Overlay get_overlay() const;
+ void set_slot_color_right(int p_slot_index, const Color &p_color);
+ Color get_slot_color_right(int p_slot_index) const;
- void set_resizable(bool p_enable);
- bool is_resizable() const;
+ bool is_slot_draw_stylebox(int p_slot_index) const;
+ void set_slot_draw_stylebox(int p_slot_index, bool p_enable);
- void set_draggable(bool p_draggable);
- bool is_draggable();
+ int get_input_port_count();
+ Vector2 get_input_port_position(int p_port_idx);
+ int get_input_port_type(int p_port_idx);
+ Color get_input_port_color(int p_port_idx);
+ int get_input_port_slot(int p_port_idx);
- void set_selectable(bool p_selectable);
- bool is_selectable();
+ int get_output_port_count();
+ Vector2 get_output_port_position(int p_port_idx);
+ int get_output_port_type(int p_port_idx);
+ Color get_output_port_color(int p_port_idx);
+ int get_output_port_slot(int p_port_idx);
virtual Size2 get_minimum_size() const override;
@@ -203,13 +144,7 @@ public:
virtual Vector<int> get_allowed_size_flags_horizontal() const override;
virtual Vector<int> get_allowed_size_flags_vertical() const override;
- bool is_resizing() const {
- return resizing;
- }
-
GraphNode();
};
-VARIANT_ENUM_CAST(GraphNode::Overlay)
-
#endif // GRAPH_NODE_H
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 23b516192e..b03d3c52d2 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -1615,7 +1615,14 @@ bool ItemList::get_allow_search() const {
void ItemList::set_icon_scale(real_t p_scale) {
ERR_FAIL_COND(!Math::is_finite(p_scale));
+
+ if (icon_scale == p_scale) {
+ return;
+ }
+
icon_scale = p_scale;
+ queue_redraw();
+ shape_changed = true;
}
real_t ItemList::get_icon_scale() const {
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 4c1e591bd7..f74d6df158 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1513,11 +1513,7 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
text = text.left(p_from_column) + text.substr(p_to_column);
_shape();
- caret_column -= CLAMP(caret_column - p_from_column, 0, p_to_column - p_from_column);
-
- if (caret_column >= text.length()) {
- caret_column = text.length();
- }
+ set_caret_column(caret_column - CLAMP(caret_column - p_from_column, 0, p_to_column - p_from_column));
if (!text_changed_dirty) {
if (is_inside_tree()) {
diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h
index 0799abaffc..4befdd182f 100644
--- a/scene/gui/rich_text_effect.h
+++ b/scene/gui/rich_text_effect.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class CharFXTransform : public RefCounted {
GDCLASS(CharFXTransform, RefCounted);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index cffd9604f6..1d5cee61a3 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2943,7 +2943,11 @@ void TextEdit::_update_placeholder() {
placeholder_data_buf->clear();
placeholder_data_buf->set_width(text.get_width());
placeholder_data_buf->set_break_flags(text.get_brk_flags());
- placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
+ if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
+ placeholder_data_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
+ } else {
+ placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
+ }
placeholder_data_buf->set_preserve_control(draw_control_chars);
placeholder_data_buf->add_string(placeholder_text, theme_cache.font, theme_cache.font_size, language);
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index d94b11789f..c52f463905 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -189,10 +189,8 @@ bool TextureRect::_set(const StringName &p_name, const Variant &p_value) {
#endif
void TextureRect::_texture_changed() {
- if (texture.is_valid()) {
- queue_redraw();
- update_minimum_size();
- }
+ queue_redraw();
+ update_minimum_size();
}
void TextureRect::set_texture(const Ref<Texture2D> &p_tex) {
diff --git a/scene/main/multiplayer_peer.h b/scene/main/multiplayer_peer.h
index 99be9137f8..ed1d56839f 100644
--- a/scene/main/multiplayer_peer.h
+++ b/scene/main/multiplayer_peer.h
@@ -35,7 +35,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class MultiplayerPeer : public PacketPeer {
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index d8f38c9148..d8a50c4313 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -34,6 +34,7 @@
#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/object/message_queue.h"
+#include "core/object/script_language.h"
#include "core/string/print_string.h"
#include "instance_placeholder.h"
#include "scene/animation/tween.h"
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index cffbb794c5..ba53a5e3c3 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1269,7 +1269,9 @@ void Window::_notification(int p_what) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
- notification(NOTIFICATION_THEME_CHANGED);
+
+ // Emits NOTIFICATION_THEME_CHANGED internally.
+ set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
} break;
case NOTIFICATION_READY: {
@@ -1313,6 +1315,8 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ set_theme_context(nullptr, false);
+
if (transient) {
_clear_transient();
}
@@ -1889,6 +1893,11 @@ bool Window::has_theme_owner_node() const {
return theme_owner->has_owner_node();
}
+void Window::set_theme_context(ThemeContext *p_context, bool p_propagate) {
+ ERR_MAIN_THREAD_GUARD;
+ theme_owner->set_owner_context(p_context, p_propagate);
+}
+
void Window::set_theme(const Ref<Theme> &p_theme) {
ERR_MAIN_THREAD_GUARD;
if (theme == p_theme) {
@@ -2129,6 +2138,12 @@ int Window::get_theme_constant(const StringName &p_name, const StringName &p_the
return constant;
}
+#ifdef TOOLS_ENABLED
+Ref<Texture2D> Window::get_editor_theme_icon(const StringName &p_name) const {
+ return get_theme_icon(p_name, SNAME("EditorIcons"));
+}
+#endif
+
bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!initialized) {
@@ -2881,7 +2896,7 @@ Window::Window() {
max_size_used = max_size; // Update max_size_used.
}
- theme_owner = memnew(ThemeOwner);
+ theme_owner = memnew(ThemeOwner(this));
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}
diff --git a/scene/main/window.h b/scene/main/window.h
index d781f228d2..689fa754cb 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -39,6 +39,7 @@ class Font;
class Shortcut;
class StyleBox;
class ThemeOwner;
+class ThemeContext;
class Window : public Viewport {
GDCLASS(Window, Viewport)
@@ -365,6 +366,8 @@ public:
Node *get_theme_owner_node() const;
bool has_theme_owner_node() const;
+ void set_theme_context(ThemeContext *p_context, bool p_propagate = true);
+
void set_theme(const Ref<Theme> &p_theme);
Ref<Theme> get_theme() const;
@@ -394,6 +397,9 @@ public:
int get_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
Color get_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
int get_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
+#ifdef TOOLS_ENABLED
+ Ref<Texture2D> get_editor_theme_icon(const StringName &p_name) const;
+#endif
bool has_theme_icon_override(const StringName &p_name) const;
bool has_theme_stylebox_override(const StringName &p_name) const;
diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp
index bf98a8d292..063e91df67 100644
--- a/scene/property_utils.cpp
+++ b/scene/property_utils.cpp
@@ -31,6 +31,7 @@
#include "property_utils.h"
#include "core/config/engine.h"
+#include "core/object/script_language.h"
#include "core/templates/local_vector.h"
#include "scene/resources/packed_scene.h"
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 5a29e5ff37..19c4b62eaf 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -439,6 +439,7 @@ void register_scene_types() {
GDREGISTER_CLASS(HSplitContainer);
GDREGISTER_CLASS(VSplitContainer);
+ GDREGISTER_CLASS(GraphElement);
GDREGISTER_CLASS(GraphNode);
GDREGISTER_CLASS(GraphEdit);
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 860e48a361..c8e3741383 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -5579,8 +5579,8 @@ Variant Animation::subtract_variant(const Variant &a, const Variant &b) {
Variant Animation::blend_variant(const Variant &a, const Variant &b, float c) {
if (a.get_type() != b.get_type()) {
if (a.is_num() && b.is_num()) {
- real_t va = a;
- real_t vb = b;
+ double va = a;
+ double vb = b;
return va + vb * c;
}
return a;
@@ -5591,7 +5591,7 @@ Variant Animation::blend_variant(const Variant &a, const Variant &b, float c) {
return Variant();
}
case Variant::INT: {
- return int((a.operator int64_t()) + (b.operator int64_t()) * c + 0.5);
+ return int64_t((a.operator int64_t()) + (b.operator int64_t()) * c + 0.5);
}
case Variant::FLOAT: {
return (a.operator double()) + (b.operator double()) * c;
@@ -5664,8 +5664,8 @@ Variant Animation::blend_variant(const Variant &a, const Variant &b, float c) {
Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float c) {
if (a.get_type() != b.get_type()) {
if (a.is_num() && b.is_num()) {
- real_t va = a;
- real_t vb = b;
+ double va = a;
+ double vb = b;
return va + (vb - va) * c;
}
return a;
@@ -5677,11 +5677,11 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float
}
case Variant::INT: {
const int64_t va = a.operator int64_t();
- return int(va + ((b.operator int64_t()) - va) * c);
+ return int64_t(va + ((b.operator int64_t()) - va) * c);
}
case Variant::FLOAT: {
- const real_t va = a.operator real_t();
- return va + ((b.operator real_t()) - va) * c;
+ const double va = a.operator double();
+ return va + ((b.operator double()) - va) * c;
}
case Variant::VECTOR2: {
return (a.operator Vector2()).lerp(b.operator Vector2(), c);
@@ -5783,7 +5783,7 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float
case Variant::PACKED_INT32_ARRAY: {
const Vector<int32_t> arr_a = a;
const Vector<int32_t> arr_b = b;
- int32_t sz = arr_a.size();
+ int sz = arr_a.size();
if (sz == 0 || arr_b.size() != sz) {
return a;
} else {
@@ -5795,7 +5795,7 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float
const int32_t *br = arr_b.ptr();
Variant va;
- for (int32_t i = 0; i < sz; i++) {
+ for (int i = 0; i < sz; i++) {
va = interpolate_variant(ar[i], br[i], c);
vw[i] = va;
}
@@ -5806,7 +5806,7 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float
case Variant::PACKED_INT64_ARRAY: {
const Vector<int64_t> arr_a = a;
const Vector<int64_t> arr_b = b;
- int64_t sz = arr_a.size();
+ int sz = arr_a.size();
if (sz == 0 || arr_b.size() != sz) {
return a;
} else {
@@ -5818,7 +5818,7 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float
const int64_t *br = arr_b.ptr();
Variant va;
- for (int64_t i = 0; i < sz; i++) {
+ for (int i = 0; i < sz; i++) {
va = interpolate_variant(ar[i], br[i], c);
vw[i] = va;
}
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index f5edc8d5e9..7aa2f8e178 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -2779,48 +2779,25 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
return base_font;
}
- // Check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ StringName theme_name = "font";
+ List<StringName> theme_types;
+ ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
- for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f == this) {
- continue;
- }
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
- }
- return f;
- }
+ ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_null()) {
+ continue;
}
- }
-
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f == this) {
- continue;
- }
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
- }
- return f;
+ if (!theme->has_font(theme_name, E)) {
+ continue;
}
- }
- // If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
- if (f != this) {
+ Ref<Font> f = theme->get_font(theme_name, E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2829,18 +2806,27 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
}
}
+ Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
+ if (f != this) {
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
+ }
+
return Ref<Font>();
}
void FontVariation::set_variation_opentype(const Dictionary &p_coords) {
- if (variation.opentype != p_coords) {
- variation.opentype = p_coords;
+ if (!variation.opentype.recursive_equal(p_coords, 1)) {
+ variation.opentype = p_coords.duplicate();
_invalidate_rids();
}
}
Dictionary FontVariation::get_variation_opentype() const {
- return variation.opentype;
+ return variation.opentype.duplicate();
}
void FontVariation::set_variation_embolden(float p_strength) {
@@ -2877,14 +2863,14 @@ int FontVariation::get_variation_face_index() const {
}
void FontVariation::set_opentype_features(const Dictionary &p_features) {
- if (opentype_features != p_features) {
- opentype_features = p_features;
+ if (!opentype_features.recursive_equal(p_features, 1)) {
+ opentype_features = p_features.duplicate();
_invalidate_rids();
}
}
Dictionary FontVariation::get_opentype_features() const {
- return opentype_features;
+ return opentype_features.duplicate();
}
void FontVariation::set_spacing(TextServer::SpacingType p_spacing, int p_value) {
@@ -3135,48 +3121,25 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
return base_font;
}
- // Check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ StringName theme_name = "font";
+ List<StringName> theme_types;
+ ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
- for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f == this) {
- continue;
- }
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
- }
- return f;
- }
+ ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_null()) {
+ continue;
}
- }
-
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- if (f == this) {
- continue;
- }
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
- }
- return f;
+ if (!theme->has_font(theme_name, E)) {
+ continue;
}
- }
- // If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
- if (f != this) {
+ Ref<Font> f = theme->get_font(theme_name, E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -3185,6 +3148,15 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
}
}
+ Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
+ if (f != this) {
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
+ }
+
return Ref<Font>();
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 65da0bc3c8..39b3acfe3f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -777,6 +777,9 @@ void BaseMaterial3D::_update_shader() {
if (flags[FLAG_USE_SHADOW_TO_OPACITY]) {
code += ",shadow_to_opacity";
}
+ if (flags[FLAG_DISABLE_FOG]) {
+ code += ",fog_disabled";
+ }
if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
code += ",depth_prepass_alpha";
@@ -2725,6 +2728,7 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Toon"), "set_diffuse_mode", "get_diffuse_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Toon,Disabled"), "set_specular_mode", "get_specular_mode");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_fog"), "set_flag", "get_flag", FLAG_DISABLE_FOG);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
@@ -2977,6 +2981,7 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_SUBSURFACE_MODE_SKIN);
BIND_ENUM_CONSTANT(FLAG_PARTICLE_TRAILS_MODE);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF);
+ BIND_ENUM_CONSTANT(FLAG_DISABLE_FOG);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 28ceb1f119..18fbc02a12 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -256,6 +256,7 @@ public:
FLAG_SUBSURFACE_MODE_SKIN,
FLAG_PARTICLE_TRAILS_MODE,
FLAG_ALBEDO_TEXTURE_MSDF,
+ FLAG_DISABLE_FOG,
FLAG_MAX
};
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 359c4765a2..a857434b2a 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -74,6 +74,55 @@ static Array _sanitize_node_pinned_properties(Node *p_node) {
return pinned;
}
+Ref<Resource> SceneState::get_remap_resource(const Ref<Resource> &p_resource, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache, const Ref<Resource> &p_fallback, Node *p_for_scene) {
+ ERR_FAIL_COND_V(p_resource.is_null(), Ref<Resource>());
+
+ Ref<Resource> remap_resource;
+
+ // Find the shared copy of the source resource.
+ HashMap<Ref<Resource>, Ref<Resource>>::Iterator R = remap_cache.find(p_resource);
+ if (R) {
+ remap_resource = R->value;
+ } else if (p_fallback.is_valid() && p_fallback->is_local_to_scene() && p_fallback->get_class() == p_resource->get_class()) {
+ // Simply copy the data from the source resource to update the fallback resource that was previously set.
+
+ p_fallback->reset_state(); // May want to reset state.
+
+ List<PropertyInfo> pi;
+ p_resource->get_property_list(&pi);
+ for (const PropertyInfo &E : pi) {
+ if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
+ continue;
+ }
+ if (E.name == "resource_path") {
+ continue; // Do not change path.
+ }
+
+ Variant value = p_resource->get(E.name);
+
+ // The local-to-scene subresource instance is preserved, thus maintaining the previous sharing relationship.
+ // This is mainly used when the sub-scene root is reset in the main scene.
+ Ref<Resource> sub_res_of_from = value;
+ if (sub_res_of_from.is_valid() && sub_res_of_from->is_local_to_scene()) {
+ value = get_remap_resource(sub_res_of_from, remap_cache, p_fallback->get(E.name), p_fallback->get_local_scene());
+ }
+
+ p_fallback->set(E.name, value);
+ }
+
+ p_fallback->set_scene_unique_id(p_resource->get_scene_unique_id()); // Get the id from the main scene, in case the id changes again when saving the scene.
+
+ remap_cache[p_resource] = p_fallback;
+ remap_resource = p_fallback;
+ } else { // A copy of the source resource is required to overwrite the previous one.
+ Ref<Resource> local_dupe = p_resource->duplicate_for_local_scene(p_for_scene, remap_cache);
+ remap_cache[p_resource] = local_dupe;
+ remap_resource = local_dupe;
+ }
+
+ return remap_resource;
+}
+
Node *SceneState::instantiate(GenEditState p_edit_state) const {
// Nodes where instantiation failed (because something is missing.)
List<Node *> stray_instances;
@@ -234,6 +283,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
const NodeData::Property *nprops = &n.properties[0];
Dictionary missing_resource_properties;
+ HashMap<Ref<Resource>, Ref<Resource>> resources_local_to_sub_scene; // Record the mappings in the sub-scene.
for (int j = 0; j < nprop_count; j++) {
bool valid;
@@ -278,20 +328,8 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
Ref<Resource> res = value;
if (res.is_valid()) {
if (res->is_local_to_scene()) {
- // In a situation where a local-to-scene resource is used in a child node of a non-editable instance,
- // we need to avoid the parent scene from overriding the resource potentially also used in the root
- // of the instantiated scene. That would to the instance having two different instances of the resource.
- // Since at this point it's too late to propagate the resource instance in the parent scene to all the relevant
- // nodes in the instance (and that would require very complex bookkepping), what we do instead is
- // tampering the resource object already there with the values from the node in the parent scene and
- // then tell this node to reference that resource.
- if (n.instance >= 0) {
- Ref<Resource> node_res = node->get(snames[nprops[j].name]);
- if (node_res.is_valid()) {
- node_res->copy_from(res);
- node_res->configure_for_local_scene(node, resources_local_to_scene);
- value = node_res;
- }
+ if (n.instance >= 0) { // For the root node of a sub-scene, treat it as part of the sub-scene.
+ value = get_remap_resource(res, resources_local_to_sub_scene, node->get(snames[nprops[j].name]), node);
} else {
HashMap<Ref<Resource>, Ref<Resource>>::Iterator E = resources_local_to_scene.find(res);
Node *base = i == 0 ? node : ret_nodes[0];
@@ -346,6 +384,12 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
if (!missing_resource_properties.is_empty()) {
node->set_meta(META_MISSING_RESOURCES, missing_resource_properties);
}
+
+ for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_sub_scene) {
+ if (E.value->get_local_scene() == node) {
+ E.value->setup_local_to_scene(); // Setup may be required for the resource to work properly.
+ }
+ }
}
//name
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 2be3ac08af..4b436a8385 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -136,6 +136,7 @@ public:
};
static void set_disable_placeholders(bool p_disable);
+ static Ref<Resource> get_remap_resource(const Ref<Resource> &p_resource, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache, const Ref<Resource> &p_fallback, Node *p_for_scene);
int find_node_by_path(const NodePath &p_node) const;
Variant get_property_value(int p_node, const StringName &p_property, bool &found) const;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index a64ae07f05..6d848f5494 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -3466,32 +3466,24 @@ Ref<Font> TextMesh::_get_font_or_default() const {
return font_override;
}
- // Check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
-
- for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
- }
+ StringName theme_name = "font";
+ List<StringName> theme_types;
+ ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
+
+ ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_null()) {
+ continue;
}
- }
-
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- {
- List<StringName> theme_types;
- ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (theme->has_font(theme_name, E)) {
+ return theme->get_font(theme_name, E);
}
}
}
- // If they don't exist, use any type to return the default/empty value.
- return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ return global_context->get_fallback_theme()->get_font(theme_name, StringName());
}
void TextMesh::set_font_size(int p_size) {
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index a2c04698e1..31f6d6a84a 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -34,6 +34,7 @@
#include "core/io/dir_access.h"
#include "core/io/missing_resource.h"
#include "core/io/resource_format_binary.h"
+#include "core/object/script_language.h"
#include "core/version.h"
// Version 2: changed names for Basis, AABB, Vectors, etc.
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 7120b21190..5b375905cc 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -239,8 +239,10 @@ Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const Strin
ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot load shader: " + p_path);
String str;
- error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
- ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader: " + p_path);
+ if (buffer.size() > 0) {
+ error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
+ ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader: " + p_path);
+ }
Ref<Shader> shader;
shader.instantiate();
diff --git a/scene/resources/shader_include.cpp b/scene/resources/shader_include.cpp
index 323be6e491..0a2a686b4e 100644
--- a/scene/resources/shader_include.cpp
+++ b/scene/resources/shader_include.cpp
@@ -93,8 +93,10 @@ Ref<Resource> ResourceFormatLoaderShaderInclude::load(const String &p_path, cons
ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot load shader include: " + p_path);
String str;
- error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
- ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader include: " + p_path);
+ if (buffer.size() > 0) {
+ error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
+ ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader include: " + p_path);
+ }
Ref<ShaderInclude> shader_inc;
shader_inc.instantiate();
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 3f9a96be2f..3d3a059d0b 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -34,7 +34,6 @@
#include "core/io/resource.h"
#include "core/object/class_db.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class CanvasItem;
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
index bf263f9490..cac2807ee2 100644
--- a/scene/resources/syntax_highlighter.h
+++ b/scene/resources/syntax_highlighter.h
@@ -33,7 +33,6 @@
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
class TextEdit;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 799a8471b9..d2a1519d49 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -1263,11 +1263,7 @@ void Theme::get_type_dependencies(const StringName &p_base_type, const StringNam
}
// Continue building the chain using native class hierarchy.
- StringName class_name = p_base_type;
- while (class_name != StringName()) {
- p_list->push_back(class_name);
- class_name = ClassDB::get_parent_class_nocheck(class_name);
- }
+ ThemeDB::get_singleton()->get_native_type_dependencies(p_base_type, p_list);
}
// Internal methods for getting lists as a Vector of String (compatible with public API).
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 4f238f7334..f053740db1 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -50,7 +50,6 @@
#endif
class TileMap;
-struct TileMapQuadrant;
class TileSetSource;
class TileSetAtlasSource;
class TileData;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 7f1c322c8f..99f9418027 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -330,6 +330,14 @@ void VisualShaderNode::set_disabled(bool p_disabled) {
disabled = p_disabled;
}
+bool VisualShaderNode::is_closable() const {
+ return closable;
+}
+
+void VisualShaderNode::set_closable(bool p_closable) {
+ closable = p_closable;
+}
+
Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
return Vector<VisualShader::DefaultTextureParam>();
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index d3657eae07..1d23b80839 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -265,6 +265,7 @@ class VisualShaderNode : public Resource {
protected:
bool simple_decl = true;
bool disabled = false;
+ bool closable = false;
static void _bind_methods();
@@ -331,6 +332,9 @@ public:
bool is_disabled() const;
void set_disabled(bool p_disabled = true);
+ bool is_closable() const;
+ void set_closable(bool p_closable = true);
+
virtual Vector<StringName> get_editable_properties() const;
virtual HashMap<StringName, String> get_editable_properties_names() const;
diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp
index eef46a6798..3597eb3f78 100644
--- a/scene/theme/default_theme.cpp
+++ b/scene/theme/default_theme.cpp
@@ -699,40 +699,43 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("icon_max_width", "PopupMenu", 0);
// GraphNode
- Ref<StyleBoxFlat> graphnode_normal = make_flat_stylebox(style_normal_color, 18, 42, 18, 12);
- graphnode_normal->set_border_width(SIDE_TOP, 30);
+
+ Ref<StyleBoxFlat> graphnode_normal = make_flat_stylebox(style_normal_color, 18, 12, 18, 12);
graphnode_normal->set_border_color(Color(0.325, 0.325, 0.325, 0.6));
Ref<StyleBoxFlat> graphnode_selected = graphnode_normal->duplicate();
graphnode_selected->set_border_color(Color(0.625, 0.625, 0.625, 0.6));
- Ref<StyleBoxFlat> graphnode_comment_normal = make_flat_stylebox(style_pressed_color, 18, 42, 18, 12, 3, true, 2);
- graphnode_comment_normal->set_border_color(style_pressed_color);
- Ref<StyleBoxFlat> graphnode_comment_selected = graphnode_comment_normal->duplicate();
- graphnode_comment_selected->set_border_color(style_hover_color);
- Ref<StyleBoxFlat> graphnode_breakpoint = make_flat_stylebox(style_pressed_color, 18, 42, 18, 12, 6, true, 4);
- graphnode_breakpoint->set_border_color(Color(0.9, 0.29, 0.3));
- Ref<StyleBoxFlat> graphnode_position = make_flat_stylebox(style_pressed_color, 18, 42, 18, 12, 6, true, 4);
- graphnode_position->set_border_color(Color(0.98, 0.89, 0.27));
+
+ Ref<StyleBoxFlat> graphn_sb_titlebar = make_flat_stylebox(style_normal_color.lightened(0.3), 4, 4, 4, 4);
+ Ref<StyleBoxFlat> graphn_sb_titlebar_selected = graphnode_normal->duplicate();
+ graphn_sb_titlebar_selected->set_bg_color(Color(1.0, 0.625, 0.625, 0.6));
Ref<StyleBoxEmpty> graphnode_slot = make_empty_stylebox(0, 0, 0, 0);
- theme->set_stylebox("frame", "GraphNode", graphnode_normal);
- theme->set_stylebox("selected_frame", "GraphNode", graphnode_selected);
- theme->set_stylebox("breakpoint", "GraphNode", graphnode_breakpoint);
- theme->set_stylebox("position", "GraphNode", graphnode_position);
+ theme->set_stylebox("panel", "GraphNode", graphnode_normal);
+ theme->set_stylebox("panel_selected", "GraphNode", graphnode_selected);
+ theme->set_stylebox("titlebar", "GraphNode", graphn_sb_titlebar);
+ theme->set_stylebox("titlebar_selected", "GraphNode", graphn_sb_titlebar_selected);
theme->set_stylebox("slot", "GraphNode", graphnode_slot);
-
theme->set_icon("port", "GraphNode", icons["graph_port"]);
- theme->set_icon("close", "GraphNode", icons["close"]);
theme->set_icon("resizer", "GraphNode", icons["resizer_se"]);
- theme->set_font("title_font", "GraphNode", Ref<Font>());
- theme->set_color("title_color", "GraphNode", control_font_color);
- theme->set_color("close_color", "GraphNode", control_font_color);
theme->set_color("resizer_color", "GraphNode", control_font_color);
theme->set_constant("separation", "GraphNode", Math::round(2 * scale));
- theme->set_constant("title_offset", "GraphNode", Math::round(26 * scale));
- theme->set_constant("title_h_offset", "GraphNode", 0);
- theme->set_constant("close_offset", "GraphNode", Math::round(22 * scale));
- theme->set_constant("close_h_offset", "GraphNode", Math::round(12 * scale));
- theme->set_constant("port_offset", "GraphNode", 0);
+ theme->set_constant("port_h_offset", "GraphNode", 0);
+
+ // GraphNodes's title Label.
+
+ theme->set_type_variation("GraphNodeTitleLabel", "Label");
+
+ theme->set_stylebox("normal", "GraphNodeTitleLabel", make_empty_stylebox(0, 0, 0, 0));
+ theme->set_font("font", "GraphNodeTitleLabel", Ref<Font>());
+ theme->set_font_size("font_size", "GraphNodeTitleLabel", -1);
+ theme->set_color("font_color", "GraphNodeTitleLabel", control_font_color);
+ theme->set_color("font_shadow_color", "GraphNodeTitleLabel", Color(0, 0, 0, 0));
+ theme->set_color("font_outline_color", "GraphNodeTitleLabel", control_font_color);
+ theme->set_constant("shadow_offset_x", "GraphNodeTitleLabel", Math::round(1 * scale));
+ theme->set_constant("shadow_offset_y", "GraphNodeTitleLabel", Math::round(1 * scale));
+ theme->set_constant("outline_size", "GraphNodeTitleLabel", 0);
+ theme->set_constant("shadow_outline_size", "GraphNodeTitleLabel", Math::round(1 * scale));
+ theme->set_constant("line_spacing", "GraphNodeTitleLabel", Math::round(3 * scale));
// Tree
diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp
index 39a4f078b5..92f3dec5e2 100644
--- a/scene/theme/theme_db.cpp
+++ b/scene/theme/theme_db.cpp
@@ -32,6 +32,9 @@
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
+#include "scene/gui/control.h"
+#include "scene/main/node.h"
+#include "scene/main/window.h"
#include "scene/resources/font.h"
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
@@ -40,18 +43,18 @@
#include "servers/text_server.h"
// Default engine theme creation and configuration.
+
void ThemeDB::initialize_theme() {
+ // Default theme-related project settings.
+
// Allow creating the default theme at a different scale to suit higher/lower base resolutions.
float default_theme_scale = GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "gui/theme/default_theme_scale", PROPERTY_HINT_RANGE, "0.5,8,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), 1.0);
- String theme_path = GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), "");
-
- String font_path = GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.otf,*.ttf,*.woff,*.woff2,*.fnt,*.font,*.pfb,*.pfm", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), "");
+ String project_theme_path = GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), "");
+ String project_font_path = GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.otf,*.ttf,*.woff,*.woff2,*.fnt,*.font,*.pfb,*.pfm", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), "");
TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "gui/theme/default_font_antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD Subpixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), 1);
-
TextServer::Hinting font_hinting = (TextServer::Hinting)(int)GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "gui/theme/default_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), TextServer::HINTING_LIGHT);
-
TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED), TextServer::SUBPIXEL_POSITIONING_AUTO);
const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false);
@@ -60,38 +63,58 @@ void ThemeDB::initialize_theme() {
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "gui/theme/lcd_subpixel_layout", PROPERTY_HINT_ENUM, "Disabled,Horizontal RGB,Horizontal BGR,Vertical RGB,Vertical BGR"), 1);
ProjectSettings::get_singleton()->set_restart_if_changed("gui/theme/lcd_subpixel_layout", false);
- Ref<Font> font;
- if (!font_path.is_empty()) {
- font = ResourceLoader::load(font_path);
- if (font.is_valid()) {
- set_fallback_font(font);
+ // Attempt to load custom project theme and font.
+
+ if (!project_theme_path.is_empty()) {
+ Ref<Theme> theme = ResourceLoader::load(project_theme_path);
+ if (theme.is_valid()) {
+ set_project_theme(theme);
} else {
- ERR_PRINT("Error loading custom font '" + font_path + "'");
+ ERR_PRINT("Error loading custom project theme '" + project_theme_path + "'");
}
}
- // Always make the default theme to avoid invalid default font/icon/style in the given theme.
- if (RenderingServer::get_singleton()) {
- make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiasing, font_msdf, font_generate_mipmaps);
- }
-
- if (!theme_path.is_empty()) {
- Ref<Theme> theme = ResourceLoader::load(theme_path);
- if (theme.is_valid()) {
- set_project_theme(theme);
+ Ref<Font> project_font;
+ if (!project_font_path.is_empty()) {
+ project_font = ResourceLoader::load(project_font_path);
+ if (project_font.is_valid()) {
+ set_fallback_font(project_font);
} else {
- ERR_PRINT("Error loading custom theme '" + theme_path + "'");
+ ERR_PRINT("Error loading custom project font '" + project_font_path + "'");
}
}
+
+ // Always generate the default theme to serve as a fallback for all required theme definitions.
+
+ if (RenderingServer::get_singleton()) {
+ make_default_theme(default_theme_scale, project_font, font_subpixel_positioning, font_hinting, font_antialiasing, font_msdf, font_generate_mipmaps);
+ }
+
+ _init_default_theme_context();
}
void ThemeDB::initialize_theme_noproject() {
if (RenderingServer::get_singleton()) {
make_default_theme(1.0, Ref<Font>());
}
+
+ _init_default_theme_context();
}
-// Universal fallback Theme resources.
+void ThemeDB::finalize_theme() {
+ if (!RenderingServer::get_singleton()) {
+ WARN_PRINT("Finalizing theme when there is no RenderingServer is an error; check the order of operations.");
+ }
+
+ _finalize_theme_contexts();
+ default_theme.unref();
+
+ fallback_font.unref();
+ fallback_icon.unref();
+ fallback_stylebox.unref();
+}
+
+// Global Theme resources.
void ThemeDB::set_default_theme(const Ref<Theme> &p_default) {
default_theme = p_default;
@@ -176,7 +199,135 @@ Ref<StyleBox> ThemeDB::get_fallback_stylebox() {
return fallback_stylebox;
}
+void ThemeDB::get_native_type_dependencies(const StringName &p_base_type, List<StringName> *p_list) {
+ ERR_FAIL_NULL(p_list);
+
+ // TODO: It may make sense to stop at Control/Window, because their parent classes cannot be used in
+ // a meaningful way.
+ StringName class_name = p_base_type;
+ while (class_name != StringName()) {
+ p_list->push_back(class_name);
+ class_name = ClassDB::get_parent_class_nocheck(class_name);
+ }
+}
+
+// Global theme contexts.
+
+ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_themes) {
+ ERR_FAIL_COND_V(!p_node->is_inside_tree(), nullptr);
+ ERR_FAIL_COND_V(theme_contexts.has(p_node), nullptr);
+ ERR_FAIL_COND_V(p_themes.is_empty(), nullptr);
+
+ ThemeContext *context = memnew(ThemeContext);
+ context->node = p_node;
+ context->parent = get_nearest_theme_context(p_node);
+ context->set_themes(p_themes);
+
+ theme_contexts[p_node] = context;
+ _propagate_theme_context(p_node, context);
+
+ p_node->connect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context).bind(p_node));
+
+ return context;
+}
+
+void ThemeDB::destroy_theme_context(Node *p_node) {
+ ERR_FAIL_COND(!theme_contexts.has(p_node));
+
+ p_node->disconnect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context));
+
+ ThemeContext *context = theme_contexts[p_node];
+
+ theme_contexts.erase(p_node);
+ _propagate_theme_context(p_node, context->parent);
+
+ memdelete(context);
+}
+
+void ThemeDB::_propagate_theme_context(Node *p_from_node, ThemeContext *p_context) {
+ Control *from_control = Object::cast_to<Control>(p_from_node);
+ Window *from_window = from_control ? nullptr : Object::cast_to<Window>(p_from_node);
+
+ if (from_control) {
+ from_control->set_theme_context(p_context);
+ } else if (from_window) {
+ from_window->set_theme_context(p_context);
+ }
+
+ for (int i = 0; i < p_from_node->get_child_count(); i++) {
+ Node *child_node = p_from_node->get_child(i);
+
+ // If the child is the root of another global context, stop the propagation
+ // in this branch.
+ if (theme_contexts.has(child_node)) {
+ theme_contexts[child_node]->parent = p_context;
+ continue;
+ }
+
+ _propagate_theme_context(child_node, p_context);
+ }
+}
+
+void ThemeDB::_init_default_theme_context() {
+ default_theme_context = memnew(ThemeContext);
+
+ List<Ref<Theme>> themes;
+
+ // Only add the project theme to the default context when running projects.
+
+#ifdef TOOLS_ENABLED
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ themes.push_back(project_theme);
+ }
+#else
+ themes.push_back(project_theme);
+#endif
+
+ themes.push_back(default_theme);
+ default_theme_context->set_themes(themes);
+}
+
+void ThemeDB::_finalize_theme_contexts() {
+ if (default_theme_context) {
+ memdelete(default_theme_context);
+ default_theme_context = nullptr;
+ }
+ while (theme_contexts.size()) {
+ HashMap<Node *, ThemeContext *>::Iterator E = theme_contexts.begin();
+ memdelete(E->value);
+ theme_contexts.remove(E);
+ }
+}
+
+ThemeContext *ThemeDB::get_theme_context(Node *p_node) const {
+ if (!theme_contexts.has(p_node)) {
+ return nullptr;
+ }
+
+ return theme_contexts[p_node];
+}
+
+ThemeContext *ThemeDB::get_default_theme_context() const {
+ return default_theme_context;
+}
+
+ThemeContext *ThemeDB::get_nearest_theme_context(Node *p_for_node) const {
+ ERR_FAIL_COND_V(!p_for_node->is_inside_tree(), nullptr);
+
+ Node *parent_node = p_for_node->get_parent();
+ while (parent_node) {
+ if (theme_contexts.has(parent_node)) {
+ return theme_contexts[parent_node];
+ }
+
+ parent_node = parent_node->get_parent();
+ }
+
+ return nullptr;
+}
+
// Object methods.
+
void ThemeDB::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_default_theme"), &ThemeDB::get_default_theme);
ClassDB::bind_method(D_METHOD("get_project_theme"), &ThemeDB::get_project_theme);
@@ -202,7 +353,8 @@ void ThemeDB::_bind_methods() {
ADD_SIGNAL(MethodInfo("fallback_changed"));
}
-// Memory management, reference, and initialization
+// Memory management, reference, and initialization.
+
ThemeDB *ThemeDB::singleton = nullptr;
ThemeDB *ThemeDB::get_singleton() {
@@ -211,13 +363,15 @@ ThemeDB *ThemeDB::get_singleton() {
ThemeDB::ThemeDB() {
singleton = this;
-
- // Universal default values, final fallback for every theme.
- fallback_base_scale = 1.0;
- fallback_font_size = 16;
}
ThemeDB::~ThemeDB() {
+ // For technical reasons unit tests recreate and destroy the default
+ // theme over and over again. Make sure that finalize_theme() also
+ // frees any objects that can be recreated by initialize_theme*().
+
+ _finalize_theme_contexts();
+
default_theme.unref();
project_theme.unref();
@@ -227,3 +381,43 @@ ThemeDB::~ThemeDB() {
singleton = nullptr;
}
+
+void ThemeContext::_emit_changed() {
+ emit_signal(SNAME("changed"));
+}
+
+void ThemeContext::set_themes(List<Ref<Theme>> &p_themes) {
+ for (const Ref<Theme> &theme : themes) {
+ theme->disconnect_changed(callable_mp(this, &ThemeContext::_emit_changed));
+ }
+
+ themes.clear();
+
+ for (const Ref<Theme> &theme : p_themes) {
+ if (theme.is_null()) {
+ continue;
+ }
+
+ themes.push_back(theme);
+ theme->connect_changed(callable_mp(this, &ThemeContext::_emit_changed));
+ }
+
+ _emit_changed();
+}
+
+List<Ref<Theme>> ThemeContext::get_themes() const {
+ return themes;
+}
+
+Ref<Theme> ThemeContext::get_fallback_theme() const {
+ // We expect all contexts to be valid and non-empty, but just in case...
+ if (themes.size() == 0) {
+ return ThemeDB::get_singleton()->get_default_theme();
+ }
+
+ return themes.back()->get();
+}
+
+void ThemeContext::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("changed"));
+}
diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h
index f65899f5ea..40ae30ff81 100644
--- a/scene/theme/theme_db.h
+++ b/scene/theme/theme_db.h
@@ -35,34 +35,48 @@
#include "core/object/ref_counted.h"
class Font;
+class Node;
class StyleBox;
class Texture2D;
class Theme;
+class ThemeContext;
class ThemeDB : public Object {
GDCLASS(ThemeDB, Object);
static ThemeDB *singleton;
- // Universal Theme resources used when no other theme has the item.
+ // Global Theme resources used by the default theme context.
+
Ref<Theme> default_theme;
Ref<Theme> project_theme;
// Universal default values, final fallback for every theme.
- float fallback_base_scale;
+
+ float fallback_base_scale = 1.0;
Ref<Font> fallback_font;
- int fallback_font_size;
+ int fallback_font_size = 16;
Ref<Texture2D> fallback_icon;
Ref<StyleBox> fallback_stylebox;
+ // Global theme contexts used to scope global Theme resources.
+
+ ThemeContext *default_theme_context = nullptr;
+ HashMap<Node *, ThemeContext *> theme_contexts;
+
+ void _propagate_theme_context(Node *p_from_node, ThemeContext *p_context);
+ void _init_default_theme_context();
+ void _finalize_theme_contexts();
+
protected:
static void _bind_methods();
public:
void initialize_theme();
void initialize_theme_noproject();
+ void finalize_theme();
- // Universal Theme resources
+ // Global Theme resources.
void set_default_theme(const Ref<Theme> &p_default);
Ref<Theme> get_default_theme();
@@ -70,7 +84,7 @@ public:
void set_project_theme(const Ref<Theme> &p_project_default);
Ref<Theme> get_project_theme();
- // Universal default values.
+ // Universal fallback values.
void set_fallback_base_scale(float p_base_scale);
float get_fallback_base_scale();
@@ -87,9 +101,46 @@ public:
void set_fallback_stylebox(const Ref<StyleBox> &p_stylebox);
Ref<StyleBox> get_fallback_stylebox();
+ void get_native_type_dependencies(const StringName &p_base_type, List<StringName> *p_list);
+
+ // Global theme contexts.
+
+ ThemeContext *create_theme_context(Node *p_node, List<Ref<Theme>> &p_themes);
+ void destroy_theme_context(Node *p_node);
+
+ ThemeContext *get_theme_context(Node *p_node) const;
+ ThemeContext *get_default_theme_context() const;
+ ThemeContext *get_nearest_theme_context(Node *p_for_node) const;
+
+ // Memory management, reference, and initialization.
+
static ThemeDB *get_singleton();
ThemeDB();
~ThemeDB();
};
+class ThemeContext : public Object {
+ GDCLASS(ThemeContext, Object);
+
+ friend class ThemeDB;
+
+ Node *node = nullptr;
+ ThemeContext *parent = nullptr;
+
+ // Themes are stacked in the order of relevance, for easy iteration.
+ // This means that the first theme is the one you should check first,
+ // and the last theme is the fallback theme where every lookup ends.
+ List<Ref<Theme>> themes;
+
+ void _emit_changed();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_themes(List<Ref<Theme>> &p_themes);
+ List<Ref<Theme>> get_themes() const;
+ Ref<Theme> get_fallback_theme() const;
+};
+
#endif // THEME_DB_H
diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp
index 40855c6a3e..1ba9a055fc 100644
--- a/scene/theme/theme_owner.cpp
+++ b/scene/theme/theme_owner.cpp
@@ -66,6 +66,52 @@ bool ThemeOwner::has_owner_node() const {
return bool(owner_control || owner_window);
}
+void ThemeOwner::set_owner_context(ThemeContext *p_context, bool p_propagate) {
+ ThemeContext *default_context = ThemeDB::get_singleton()->get_default_theme_context();
+
+ if (owner_context && owner_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) {
+ owner_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ } else if (default_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) {
+ default_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ }
+
+ owner_context = p_context;
+
+ if (owner_context) {
+ owner_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ } else {
+ default_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ }
+
+ if (p_propagate) {
+ _owner_context_changed();
+ }
+}
+
+void ThemeOwner::_owner_context_changed() {
+ if (!holder->is_inside_tree()) {
+ // We ignore theme changes outside of tree, because NOTIFICATION_ENTER_TREE covers everything.
+ return;
+ }
+
+ Control *c = Object::cast_to<Control>(holder);
+ Window *w = c == nullptr ? Object::cast_to<Window>(holder) : nullptr;
+
+ if (c) {
+ c->notification(Control::NOTIFICATION_THEME_CHANGED);
+ } else if (w) {
+ w->notification(Window::NOTIFICATION_THEME_CHANGED);
+ }
+}
+
+ThemeContext *ThemeOwner::_get_active_owner_context() const {
+ if (owner_context) {
+ return owner_context;
+ }
+
+ return ThemeDB::get_singleton()->get_default_theme_context();
+}
+
// Theme propagation.
void ThemeOwner::assign_theme_on_parented(Node *p_for_node) {
@@ -158,9 +204,7 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin
const Window *for_w = Object::cast_to<Window>(p_for_node);
ERR_FAIL_COND_MSG(!for_c && !for_w, "Only Control and Window nodes and derivatives can be polled for theming.");
- Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
- Ref<Theme> project_theme = ThemeDB::get_singleton()->get_project_theme();
-
+ StringName type_name = p_for_node->get_class_name();
StringName type_variation;
if (for_c) {
type_variation = for_c->get_theme_type_variation();
@@ -168,31 +212,23 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin
type_variation = for_w->get_theme_type_variation();
}
- if (p_theme_type == StringName() || p_theme_type == p_for_node->get_class_name() || p_theme_type == type_variation) {
- if (project_theme.is_valid() && project_theme->get_type_variation_base(type_variation) != StringName()) {
- project_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list);
- } else {
- default_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list);
+ // If we are looking for dependencies of the current class (or a variantion of it), check themes from the context.
+ if (p_theme_type == StringName() || p_theme_type == type_name || p_theme_type == type_variation) {
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid() && theme->get_type_variation_base(type_variation) != StringName()) {
+ theme->get_type_dependencies(type_name, type_variation, r_list);
+ return;
+ }
}
- } else {
- default_theme->get_type_dependencies(p_theme_type, StringName(), r_list);
- }
-}
-Node *ThemeOwner::_get_next_owner_node(Node *p_from_node) const {
- Node *parent = p_from_node->get_parent();
-
- Control *parent_c = Object::cast_to<Control>(parent);
- if (parent_c) {
- return parent_c->get_theme_owner_node();
- } else {
- Window *parent_w = Object::cast_to<Window>(parent);
- if (parent_w) {
- return parent_w->get_theme_owner_node();
- }
+ // If nothing was found, get the native dependencies for the current class.
+ ThemeDB::get_singleton()->get_native_type_dependencies(type_name, r_list);
+ return;
}
- return nullptr;
+ // Otherwise, get the native dependencies for the provided theme type.
+ ThemeDB::get_singleton()->get_native_type_dependencies(p_theme_type, r_list);
}
Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) {
@@ -215,24 +251,20 @@ Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const S
owner_node = _get_next_owner_node(owner_node);
}
- // Secondly, check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- for (const StringName &E : p_theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) {
- return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E);
+ // Second, check global themes from the appropriate context.
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid()) {
+ for (const StringName &E : p_theme_types) {
+ if (theme->has_theme_item(p_data_type, p_name, E)) {
+ return theme->get_theme_item(p_data_type, p_name, E);
+ }
}
}
}
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- for (const StringName &E : p_theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) {
- return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E);
- }
- }
-
- // If they don't exist, use any type to return the default/empty value.
- return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]);
+ // Finally, if no match exists, use any type to return the default/empty value.
+ return global_context->get_fallback_theme()->get_theme_item(p_data_type, p_name, StringName());
}
bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) {
@@ -255,22 +287,19 @@ bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const Stri
owner_node = _get_next_owner_node(owner_node);
}
- // Secondly, check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- for (const StringName &E : p_theme_types) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) {
- return true;
+ // Second, check global themes from the appropriate context.
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid()) {
+ for (const StringName &E : p_theme_types) {
+ if (theme->has_theme_item(p_data_type, p_name, E)) {
+ return true;
+ }
}
}
}
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- for (const StringName &E : p_theme_types) {
- if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) {
- return true;
- }
- }
-
+ // Finally, if no match exists, return false.
return false;
}
@@ -290,17 +319,17 @@ float ThemeOwner::get_theme_default_base_scale() {
owner_node = _get_next_owner_node(owner_node);
}
- // Secondly, check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) {
- return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale();
+ // Second, check global themes from the appropriate context.
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid()) {
+ if (theme->has_default_base_scale()) {
+ return theme->get_default_base_scale();
+ }
}
}
- // Lastly, fall back on the default Theme.
- if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) {
- return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale();
- }
+ // Finally, if no match exists, return the universal default.
return ThemeDB::get_singleton()->get_fallback_base_scale();
}
@@ -320,17 +349,17 @@ Ref<Font> ThemeOwner::get_theme_default_font() {
owner_node = _get_next_owner_node(owner_node);
}
- // Secondly, check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) {
- return ThemeDB::get_singleton()->get_project_theme()->get_default_font();
+ // Second, check global themes from the appropriate context.
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid()) {
+ if (theme->has_default_font()) {
+ return theme->get_default_font();
+ }
}
}
- // Lastly, fall back on the default Theme.
- if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) {
- return ThemeDB::get_singleton()->get_default_theme()->get_default_font();
- }
+ // Finally, if no match exists, return the universal default.
return ThemeDB::get_singleton()->get_fallback_font();
}
@@ -350,17 +379,17 @@ int ThemeOwner::get_theme_default_font_size() {
owner_node = _get_next_owner_node(owner_node);
}
- // Secondly, check the project-defined Theme resource.
- if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
- if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) {
- return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size();
+ // Second, check global themes from the appropriate context.
+ ThemeContext *global_context = _get_active_owner_context();
+ for (const Ref<Theme> &theme : global_context->get_themes()) {
+ if (theme.is_valid()) {
+ if (theme->has_default_font_size()) {
+ return theme->get_default_font_size();
+ }
}
}
- // Lastly, fall back on the default Theme.
- if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) {
- return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size();
- }
+ // Finally, if no match exists, return the universal default.
return ThemeDB::get_singleton()->get_fallback_font_size();
}
@@ -377,3 +406,19 @@ Ref<Theme> ThemeOwner::_get_owner_node_theme(Node *p_owner_node) const {
return Ref<Theme>();
}
+
+Node *ThemeOwner::_get_next_owner_node(Node *p_from_node) const {
+ Node *parent = p_from_node->get_parent();
+
+ Control *parent_c = Object::cast_to<Control>(parent);
+ if (parent_c) {
+ return parent_c->get_theme_owner_node();
+ } else {
+ Window *parent_w = Object::cast_to<Window>(parent);
+ if (parent_w) {
+ return parent_w->get_theme_owner_node();
+ }
+ }
+
+ return nullptr;
+}
diff --git a/scene/theme/theme_owner.h b/scene/theme/theme_owner.h
index 7ebd53fde8..4923ccb00b 100644
--- a/scene/theme/theme_owner.h
+++ b/scene/theme/theme_owner.h
@@ -36,11 +36,18 @@
class Control;
class Node;
+class ThemeContext;
class Window;
class ThemeOwner : public Object {
+ Node *holder = nullptr;
+
Control *owner_control = nullptr;
Window *owner_window = nullptr;
+ ThemeContext *owner_context = nullptr;
+
+ void _owner_context_changed();
+ ThemeContext *_get_active_owner_context() const;
Node *_get_next_owner_node(Node *p_from_node) const;
Ref<Theme> _get_owner_node_theme(Node *p_owner_node) const;
@@ -52,6 +59,8 @@ public:
Node *get_owner_node() const;
bool has_owner_node() const;
+ void set_owner_context(ThemeContext *p_context, bool p_propagate = true);
+
// Theme propagation.
void assign_theme_on_parented(Node *p_for_node);
@@ -69,7 +78,7 @@ public:
Ref<Font> get_theme_default_font();
int get_theme_default_font_size();
- ThemeOwner() {}
+ ThemeOwner(Node *p_holder) { holder = p_holder; }
~ThemeOwner() {}
};
diff --git a/scu_builders.py b/scu_builders.py
index e76a58bd88..aaf83c30d5 100644
--- a/scu_builders.py
+++ b/scu_builders.py
@@ -288,7 +288,6 @@ def generate_scu_files(verbose, max_includes_per_scu):
process_folder(["platform/ios/export"])
process_folder(["platform/linuxbsd/export"])
process_folder(["platform/macos/export"])
- process_folder(["platform/uwp/export"])
process_folder(["platform/web/export"])
process_folder(["platform/windows/export"])
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index 11febade3a..9952246c20 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -34,7 +34,6 @@
#include "core/io/resource.h"
#include "core/math/audio_frame.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class AudioEffectInstance : public RefCounted {
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 983ca8892d..015e89fc8e 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -37,7 +37,6 @@
#include "servers/audio_server.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class AudioStream;
diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h
index 253a58d78e..6ddbb98766 100644
--- a/servers/extensions/physics_server_2d_extension.h
+++ b/servers/extensions/physics_server_2d_extension.h
@@ -33,7 +33,6 @@
#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
#include "core/variant/type_info.h"
#include "core/variant/typed_array.h"
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index cd96bf15fd..553d73b549 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -34,7 +34,6 @@
#include "core/io/resource.h"
#include "core/object/class_db.h"
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
class PhysicsDirectSpaceState3D;
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index f99a5254bb..7554e478bb 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -95,7 +95,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
0, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544
};
static const uint32_t icosphere_triangle_count = 80;
- static const uint32_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {
+ static const uint16_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {
0, 13, 12, 1, 13, 15, 0, 12, 17, 0, 17, 19, 0, 19, 16, 1, 15, 22, 2, 14, 24, 3, 18, 26, 4, 20, 28, 5, 21, 30, 1, 22, 25, 2, 24, 27, 3, 26, 29, 4, 28, 31, 5, 30, 23, 6, 32, 37, 7, 33, 39, 8, 34, 40, 9, 35, 41, 10, 36, 38, 38, 41, 11, 38, 36, 41, 36, 9, 41, 41, 40, 11, 41, 35, 40, 35, 8, 40, 40, 39, 11, 40, 34, 39, 34, 7, 39, 39, 37, 11, 39, 33, 37, 33, 6, 37, 37, 38, 11, 37, 32, 38, 32, 10, 38, 23, 36, 10, 23, 30, 36, 30, 9, 36, 31, 35, 9, 31, 28, 35, 28, 8, 35, 29, 34, 8, 29, 26, 34, 26, 7, 34, 27, 33, 7, 27, 24, 33, 24, 6, 33, 25, 32, 6, 25, 22, 32, 22, 10, 32, 30, 31, 9, 30, 21, 31, 21, 4, 31, 28, 29, 8, 28, 20, 29, 20, 3, 29, 26, 27, 7, 26, 18, 27, 18, 2, 27, 24, 25, 6, 24, 14, 25, 14, 1, 25, 22, 23, 10, 22, 15, 23, 15, 5, 23, 16, 21, 5, 16, 19, 21, 19, 4, 21, 19, 20, 4, 19, 17, 20, 17, 3, 20, 17, 18, 3, 17, 12, 18, 12, 2, 18, 15, 16, 5, 15, 13, 16, 13, 0, 16, 12, 14, 2, 12, 13, 14, 13, 1, 14
};
@@ -106,10 +106,10 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
Vector<uint8_t> index_data;
- index_data.resize(sizeof(uint32_t) * icosphere_triangle_count * 3);
+ index_data.resize(sizeof(uint16_t) * icosphere_triangle_count * 3);
memcpy(index_data.ptrw(), icosphere_triangle_indices, index_data.size());
- sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+ sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
Vector<RID> buffers;
buffers.push_back(sphere_vertex_buffer);
@@ -139,7 +139,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
0, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1
};
static const uint32_t cone_triangle_count = 62;
- static const uint32_t cone_triangle_indices[cone_triangle_count * 3] = {
+ static const uint16_t cone_triangle_indices[cone_triangle_count * 3] = {
0, 23, 1, 1, 23, 2, 2, 23, 3, 3, 23, 4, 4, 23, 5, 5, 23, 6, 6, 23, 7, 7, 23, 8, 8, 23, 9, 9, 23, 10, 10, 23, 11, 11, 23, 12, 12, 23, 13, 13, 23, 14, 14, 23, 15, 15, 23, 16, 16, 23, 17, 17, 23, 18, 18, 23, 19, 19, 23, 20, 20, 23, 21, 21, 23, 22, 22, 23, 24, 24, 23, 25, 25, 23, 26, 26, 23, 27, 27, 23, 28, 28, 23, 29, 29, 23, 30, 30, 23, 31, 31, 23, 32, 32, 23, 0, 7, 15, 24, 32, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 3, 6, 7, 3, 7, 8, 9, 9, 10, 7, 10, 11, 7, 11, 12, 15, 12, 13, 15, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 24, 20, 21, 24, 21, 22, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 1, 3, 15, 17, 24, 17, 19, 24, 24, 26, 32, 26, 28, 32, 28, 30, 32, 32, 3, 7, 7, 11, 15, 32, 7, 24
};
@@ -150,10 +150,10 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
Vector<uint8_t> index_data;
- index_data.resize(sizeof(uint32_t) * cone_triangle_count * 3);
+ index_data.resize(sizeof(uint16_t) * cone_triangle_count * 3);
memcpy(index_data.ptrw(), cone_triangle_indices, index_data.size());
- cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+ cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
Vector<RID> buffers;
buffers.push_back(cone_vertex_buffer);
@@ -193,7 +193,7 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1
};
static const uint32_t box_triangle_count = 12;
- static const uint32_t box_triangle_indices[box_triangle_count * 3] = {
+ static const uint16_t box_triangle_indices[box_triangle_count * 3] = {
1, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5
};
@@ -204,10 +204,10 @@ ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
Vector<uint8_t> index_data;
- index_data.resize(sizeof(uint32_t) * box_triangle_count * 3);
+ index_data.resize(sizeof(uint16_t) * box_triangle_count * 3);
memcpy(index_data.ptrw(), box_triangle_indices, index_data.size());
- box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+ box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
Vector<RID> buffers;
buffers.push_back(box_vertex_buffer);
diff --git a/servers/rendering/renderer_rd/effects/debug_effects.cpp b/servers/rendering/renderer_rd/effects/debug_effects.cpp
index 3d26a9a8df..357d035ae9 100644
--- a/servers/rendering/renderer_rd/effects/debug_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/debug_effects.cpp
@@ -85,7 +85,7 @@ void DebugEffects::_create_frustum_arrays() {
}
if (frustum.index_buffer.is_null()) {
- uint32_t indices[6 * 2 * 3] = {
+ uint16_t indices[6 * 2 * 3] = {
// Far
0, 1, 2, // FLT, FLB, FRT
1, 3, 2, // FLB, FRB, FRT
@@ -111,19 +111,19 @@ void DebugEffects::_create_frustum_arrays() {
data.resize(6 * 2 * 3 * 4);
{
uint8_t *w = data.ptrw();
- int *p32 = (int *)w;
+ uint16_t *p16 = (uint16_t *)w;
for (int i = 0; i < 6 * 2 * 3; i++) {
- *p32 = indices[i];
- p32++;
+ *p16 = indices[i];
+ p16++;
}
}
- frustum.index_buffer = RD::get_singleton()->index_buffer_create(6 * 2 * 3, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, data);
+ frustum.index_buffer = RD::get_singleton()->index_buffer_create(6 * 2 * 3, RenderingDevice::INDEX_BUFFER_FORMAT_UINT16, data);
frustum.index_array = RD::get_singleton()->index_array_create(frustum.index_buffer, 0, 6 * 2 * 3);
}
if (frustum.lines_buffer.is_null()) {
- uint32_t indices[12 * 2] = {
+ uint16_t indices[12 * 2] = {
0, 1, // FLT - FLB
1, 3, // FLB - FRB
3, 2, // FRB - FRT
@@ -145,14 +145,14 @@ void DebugEffects::_create_frustum_arrays() {
data.resize(12 * 2 * 4);
{
uint8_t *w = data.ptrw();
- int *p32 = (int *)w;
+ uint16_t *p16 = (uint16_t *)w;
for (int i = 0; i < 12 * 2; i++) {
- *p32 = indices[i];
- p32++;
+ *p16 = indices[i];
+ p16++;
}
}
- frustum.lines_buffer = RD::get_singleton()->index_buffer_create(12 * 2, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, data);
+ frustum.lines_buffer = RD::get_singleton()->index_buffer_create(12 * 2, RenderingDevice::INDEX_BUFFER_FORMAT_UINT16, data);
frustum.lines_array = RD::get_singleton()->index_array_create(frustum.lines_buffer, 0, 12 * 2);
}
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 12f8f6a366..509072bbec 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -707,6 +707,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
+ actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 32d2289f75..ffbe7f7e59 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -610,6 +610,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
+ actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardMobile::MATERIAL_UNIFORM_SET;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index d8c035a51c..b1ad7e16ed 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -2587,18 +2587,18 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
{ // default index buffer
Vector<uint8_t> pv;
- pv.resize(6 * 4);
+ pv.resize(6 * 2);
{
uint8_t *w = pv.ptrw();
- int *p32 = (int *)w;
- p32[0] = 0;
- p32[1] = 1;
- p32[2] = 2;
- p32[3] = 0;
- p32[4] = 2;
- p32[5] = 3;
+ uint16_t *p16 = (uint16_t *)w;
+ p16[0] = 0;
+ p16[1] = 1;
+ p16[2] = 2;
+ p16[3] = 0;
+ p16[4] = 2;
+ p16[5] = 3;
}
- shader.quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ shader.quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT16, pv);
shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 6);
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 4ccd2aa322..7eb8cbd02f 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -126,18 +126,18 @@ void RendererCompositorRD::initialize() {
//create index array for copy shader
Vector<uint8_t> pv;
- pv.resize(6 * 4);
+ pv.resize(6 * 2);
{
uint8_t *w = pv.ptrw();
- int *p32 = (int *)w;
- p32[0] = 0;
- p32[1] = 1;
- p32[2] = 2;
- p32[3] = 0;
- p32[4] = 2;
- p32[5] = 3;
+ uint16_t *p16 = (uint16_t *)w;
+ p16[0] = 0;
+ p16[1] = 1;
+ p16[2] = 2;
+ p16[3] = 0;
+ p16[4] = 2;
+ p16[5] = 3;
}
- blit.index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ blit.index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT16, pv);
blit.array = RD::get_singleton()->index_array_create(blit.index_buffer, 0, 6);
blit.sampler = RD::get_singleton()->sampler_create(RD::SamplerState());
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index 8f3c704afe..cfba408fe1 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -802,7 +802,9 @@ void fragment_shader(in SceneData scene_data) {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
+#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
+#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@@ -962,6 +964,7 @@ void fragment_shader(in SceneData scene_data) {
/////////////////////// FOG //////////////////////
#ifndef MODE_RENDER_DEPTH
+#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
// fog must be processed as early as possible and then packed.
// to maximize VGPR usage
@@ -997,6 +1000,7 @@ void fragment_shader(in SceneData scene_data) {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
+#endif //!FOG_DISABLED
#endif //!MODE_RENDER_DEPTH
/////////////////////// DECALS ////////////////////////////////
@@ -2250,8 +2254,10 @@ void fragment_shader(in SceneData scene_data) {
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
+#ifndef FOG_DISABLED
//restore fog
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
+#endif //!FOG_DISABLED
#ifdef MODE_SEPARATE_SPECULAR
@@ -2268,8 +2274,10 @@ void fragment_shader(in SceneData scene_data) {
specular_buffer = vec4(specular_light, metallic);
#endif
+#ifndef FOG_DISABLED
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
+#endif //!FOG_DISABLED
#else //MODE_SEPARATE_SPECULAR
@@ -2280,8 +2288,10 @@ void fragment_shader(in SceneData scene_data) {
//frag_color = vec4(1.0);
#endif //USE_NO_SHADING
+#ifndef FOG_DISABLED
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
+#endif //!FOG_DISABLED
#endif //MODE_SEPARATE_SPECULAR
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index 0283482d76..cdf81bb6ec 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -694,7 +694,9 @@ void main() {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
+#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
+#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@@ -860,6 +862,7 @@ void main() {
/////////////////////// FOG //////////////////////
#ifndef MODE_RENDER_DEPTH
+#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
// fog must be processed as early as possible and then packed.
// to maximize VGPR usage
@@ -874,6 +877,7 @@ void main() {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
+#endif //!FOG_DISABLED
#endif //!MODE_RENDER_DEPTH
/////////////////////// DECALS ////////////////////////////////
@@ -1744,8 +1748,10 @@ void main() {
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
+#ifndef FOG_DISABLED
//restore fog
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
+#endif // !FOG_DISABLED
#ifdef MODE_MULTIPLE_RENDER_TARGETS
@@ -1762,8 +1768,10 @@ void main() {
specular_buffer = vec4(specular_light, metallic);
#endif // MODE_UNSHADED
+#ifndef FOG_DISABLED
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
+#endif // !FOG_DISABLED
#else //MODE_MULTIPLE_RENDER_TARGETS
@@ -1773,8 +1781,10 @@ void main() {
frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
#endif // MODE_UNSHADED
+#ifndef FOG_DISABLED
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
+#endif // !FOG_DISABLED
// On mobile we use a UNORM buffer with 10bpp which results in a range from 0.0 - 1.0 resulting in HDR breaking
// We divide by sc_luminance_multiplier to support a range from 0.0 - 2.0 both increasing precision on bright and darker images
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index fda341bbc9..5c4fa1a47c 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -1191,18 +1191,18 @@ MaterialStorage::MaterialStorage() {
// buffers
{ //create index array for copy shaders
Vector<uint8_t> pv;
- pv.resize(6 * 4);
+ pv.resize(6 * 2);
{
uint8_t *w = pv.ptrw();
- int *p32 = (int *)w;
- p32[0] = 0;
- p32[1] = 1;
- p32[2] = 2;
- p32[3] = 0;
- p32[4] = 2;
- p32[5] = 3;
+ uint16_t *p16 = (uint16_t *)w;
+ p16[0] = 0;
+ p16[1] = 1;
+ p16[2] = 2;
+ p16[3] = 0;
+ p16[4] = 2;
+ p16[5] = 3;
}
- quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT16, pv);
quad_index_array = RD::get_singleton()->index_array_create(quad_index_buffer, 0, 6);
}
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index bf30efbcf6..737a874abc 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -696,7 +696,7 @@ public:
RD_SETGET(Color, blend_constant)
void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
- attachments.push_back(p_attachments);
+ attachments = p_attachments;
}
TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h
index 9448a97d68..b29239105a 100644
--- a/servers/rendering/shader_preprocessor.h
+++ b/servers/rendering/shader_preprocessor.h
@@ -39,6 +39,7 @@
#include "core/typedefs.h"
#include "core/io/resource_loader.h"
+#include "core/object/script_language.h"
#include "core/os/os.h"
#include "scene/resources/shader.h"
#include "scene/resources/shader_include.h"
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index c256d37344..728089f516 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -227,6 +227,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") });
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") });
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("debug_shadow_splits") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("fog_disabled") });
}
/************ CANVAS ITEM **************************/
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 1d475f13d4..0fa483f304 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -32,7 +32,6 @@
#define TEXT_SERVER_EXTENSION_H
#include "core/object/gdvirtual.gen.inc"
-#include "core/object/script_language.h"
#include "core/os/thread_safe.h"
#include "core/variant/native_ptr.h"
#include "core/variant/typed_array.h"
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index 659fb003d3..c10ad6e13d 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -805,6 +805,22 @@ TEST_CASE("[String] sprintf") {
REQUIRE(error == false);
CHECK(output == String("fish +99.990000 frog"));
+ // Real with sign (negative zero).
+ format = "fish %+f frog";
+ args.clear();
+ args.push_back(-0.0);
+ output = format.sprintf(args, &error);
+ REQUIRE(error == false);
+ CHECK(output == String("fish -0.000000 frog"));
+
+ // Real with sign (positive zero).
+ format = "fish %+f frog";
+ args.clear();
+ args.push_back(0.0);
+ output = format.sprintf(args, &error);
+ REQUIRE(error == false);
+ CHECK(output == String("fish +0.000000 frog"));
+
// Real with 1 decimal.
format = "fish %.1f frog";
args.clear();
diff --git a/tests/core/variant/test_dictionary.h b/tests/core/variant/test_dictionary.h
index 4571de6487..5bc56075da 100644
--- a/tests/core/variant/test_dictionary.h
+++ b/tests/core/variant/test_dictionary.h
@@ -90,7 +90,7 @@ TEST_CASE("[Dictionary] Assignment using bracket notation ([])") {
CHECK(int(map[false]) == 128);
// Ensure read-only maps aren't modified by non-existing keys.
- const auto length = map.size();
+ const int length = map.size();
map.make_read_only();
CHECK(int(map["This key does not exist"].get_type()) == Variant::NIL);
CHECK(map.size() == length);
diff --git a/tests/scene/test_arraymesh.h b/tests/scene/test_arraymesh.h
index 0e97e7d75f..1623b41300 100644
--- a/tests/scene/test_arraymesh.h
+++ b/tests/scene/test_arraymesh.h
@@ -195,7 +195,7 @@ TEST_CASE("[SceneTree][ArrayMesh] Surface metadata tests.") {
}
SUBCASE("Returns correct format for the mesh") {
- auto format = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX;
+ int format = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX;
CHECK((mesh->surface_get_format(0) & format) != 0);
CHECK((mesh->surface_get_format(1) & format) != 0);
}
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index d6858fbcb4..72421c9cc9 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -3446,7 +3446,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
}
SUBCASE("[CodeEdit] autocomplete suggestion order") {
- /* Favorize less fragmented suggestion. */
+ /* Prefer less fragmented suggestion. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3456,7 +3456,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "test");
- /* Favorize suggestion starting from the string to complete (matching start). */
+ /* Prefer suggestion starting with the string to complete (matching start). */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3466,7 +3466,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "test");
- /* Favorize less fragment to matching start. */
+ /* Prefer less fragment over matching start. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3476,37 +3476,37 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "stest");
- /* Favorize closer location. */
+ /* Prefer good capitalization. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test_bis", "test_bis", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test");
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
- CHECK(code_edit->get_line(0) == "test_bis");
+ CHECK(code_edit->get_line(0) == "test");
- /* Favorize matching start to location. */
+ /* Prefer matching start over good capitalization. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest_bis", "test_bis", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test");
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest_bis", "test_bis");
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
- CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_line(0) == "Test");
- /* Favorize good capitalization. */
+ /* Prefer closer location. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test");
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test_bis", "test_bis", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
- CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_line(0) == "test_bis");
- /* Favorize location to good capitalization. */
+ /* Prefer good capitalization over location. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3514,9 +3514,9 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
- CHECK(code_edit->get_line(0) == "Test");
+ CHECK(code_edit->get_line(0) == "test");
- /* Favorize string to complete being closest to the start of the suggestion (closest to start). */
+ /* Prefer the start of the string to complete being closest to the start of the suggestion (closest to start). */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3526,12 +3526,12 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "stest");
- /* Favorize good capitalization to closest to start. */
+ /* Prefer location over closest to start. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "sTest", "stest");
- code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "sstest", "sstest");
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest", "stest");
+ code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "sstest", "sstest", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
code_edit->update_code_completion_options();
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "sstest");
diff --git a/tests/scene/test_viewport.h b/tests/scene/test_viewport.h
index dd4786977e..0c53668c6d 100644
--- a/tests/scene/test_viewport.h
+++ b/tests/scene/test_viewport.h
@@ -43,8 +43,8 @@
namespace TestViewport {
-class NotificationControl : public Control {
- GDCLASS(NotificationControl, Control);
+class NotificationControlViewport : public Control {
+ GDCLASS(NotificationControlViewport, Control);
protected:
void _notification(int p_what) {
@@ -63,11 +63,11 @@ public:
bool mouse_over = false;
};
-// `NotificationControl`-derived class that additionally
+// `NotificationControlViewport`-derived class that additionally
// - allows start Dragging
// - stores mouse information of last event
-class DragStart : public NotificationControl {
- GDCLASS(DragStart, NotificationControl);
+class DragStart : public NotificationControlViewport {
+ GDCLASS(DragStart, NotificationControlViewport);
public:
MouseButton last_mouse_button;
@@ -93,9 +93,9 @@ public:
}
};
-// `NotificationControl`-derived class that acts as a Drag and Drop target.
-class DragTarget : public NotificationControl {
- GDCLASS(DragTarget, NotificationControl);
+// `NotificationControlViewport`-derived class that acts as a Drag and Drop target.
+class DragTarget : public NotificationControlViewport {
+ GDCLASS(DragTarget, NotificationControlViewport);
public:
Variant drag_data;
diff --git a/tests/scene/test_window.h b/tests/scene/test_window.h
index e0c55101de..592cccfd7e 100644
--- a/tests/scene/test_window.h
+++ b/tests/scene/test_window.h
@@ -38,8 +38,8 @@
namespace TestWindow {
-class NotificationControl : public Control {
- GDCLASS(NotificationControl, Control);
+class NotificationControlWindow : public Control {
+ GDCLASS(NotificationControlWindow, Control);
protected:
void _notification(int p_what) {
@@ -69,7 +69,7 @@ TEST_CASE("[SceneTree][Window]") {
w->set_content_scale_size(Size2i(200, 200));
w->set_content_scale_mode(Window::CONTENT_SCALE_MODE_CANVAS_ITEMS);
w->set_content_scale_aspect(Window::CONTENT_SCALE_ASPECT_KEEP);
- NotificationControl *c = memnew(NotificationControl);
+ NotificationControlWindow *c = memnew(NotificationControlWindow);
w->add_child(c);
c->set_size(Size2i(100, 100));
c->set_position(Size2i(-50, -50));
diff --git a/tests/servers/rendering/test_shader_preprocessor.h b/tests/servers/rendering/test_shader_preprocessor.h
index d65eb522e8..c8c143641b 100644
--- a/tests/servers/rendering/test_shader_preprocessor.h
+++ b/tests/servers/rendering/test_shader_preprocessor.h
@@ -66,7 +66,7 @@ String remove_spaces(String &p_str) {
for (int n = 0; n < p_str.size(); n++) {
// These test cases only use ASCII.
- auto c = static_cast<unsigned char>(p_str[n]);
+ unsigned char c = static_cast<unsigned char>(p_str[n]);
if (std::isblank(c)) {
has_removed = true;
} else {
@@ -92,7 +92,7 @@ String remove_spaces(String &p_str) {
String compact_spaces(String &p_str) {
Vector<String> lines = p_str.split("\n", false);
erase_all_empty(lines);
- for (auto &line : lines) {
+ for (String &line : lines) {
line = remove_spaces(line);
}
return String("\n").join(lines);
diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h
index eef5b850ca..0f23929e1e 100644
--- a/tests/servers/test_text_server.h
+++ b/tests/servers/test_text_server.h
@@ -70,7 +70,7 @@ TEST_SUITE("[TextServer]") {
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
ts->font_set_allow_system_fallback(font1, false);
RID font2 = ts->create_font();
- ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
+ ts->font_set_data_ptr(font2, _font_NotoSansThai_Regular, _font_NotoSansThai_Regular_size);
ts->font_set_allow_system_fallback(font2, false);
Array font;
@@ -177,7 +177,7 @@ TEST_SUITE("[TextServer]") {
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
ts->font_set_allow_system_fallback(font1, false);
RID font2 = ts->create_font();
- ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
+ ts->font_set_data_ptr(font2, _font_NotoSansThai_Regular, _font_NotoSansThai_Regular_size);
ts->font_set_allow_system_fallback(font2, false);
RID font3 = ts->create_font();
ts->font_set_data_ptr(font3, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
@@ -511,7 +511,7 @@ TEST_SUITE("[TextServer]") {
RID font1 = ts->create_font();
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
RID font2 = ts->create_font();
- ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
+ ts->font_set_data_ptr(font2, _font_NotoSansThai_Regular, _font_NotoSansThai_Regular_size);
Array font;
font.push_back(font1);
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 6cc7aad48e..3a80fc8c00 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -212,7 +212,6 @@ struct GodotTestCaseListener : public doctest::IReporter {
PhysicsServer2D *physics_server_2d = nullptr;
NavigationServer3D *navigation_server_3d = nullptr;
NavigationServer2D *navigation_server_2d = nullptr;
- ThemeDB *theme_db = nullptr;
void test_case_start(const doctest::TestCaseData &p_in) override {
reinitialize();
@@ -238,6 +237,12 @@ struct GodotTestCaseListener : public doctest::IReporter {
RenderingServerDefault::get_singleton()->init();
RenderingServerDefault::get_singleton()->set_render_loop_enabled(false);
+ // ThemeDB requires RenderingServer to initialize the default theme.
+ // So we have to do this for each test case. Also make sure there is
+ // no residual theme from something else.
+ ThemeDB::get_singleton()->finalize_theme();
+ ThemeDB::get_singleton()->initialize_theme_noproject();
+
physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server();
physics_server_3d->init();
@@ -252,9 +257,6 @@ struct GodotTestCaseListener : public doctest::IReporter {
memnew(InputMap);
InputMap::get_singleton()->load_default();
- theme_db = memnew(ThemeDB);
- theme_db->initialize_theme_noproject();
-
memnew(SceneTree);
SceneTree::get_singleton()->initialize();
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::Feature::FEATURE_SUBWINDOWS)) {
@@ -294,11 +296,6 @@ struct GodotTestCaseListener : public doctest::IReporter {
memdelete(SceneTree::get_singleton());
}
- if (theme_db) {
- memdelete(theme_db);
- theme_db = nullptr;
- }
-
if (navigation_server_3d) {
memdelete(navigation_server_3d);
navigation_server_3d = nullptr;
@@ -326,6 +323,10 @@ struct GodotTestCaseListener : public doctest::IReporter {
}
if (RenderingServer::get_singleton()) {
+ // ThemeDB requires RenderingServer to finalize the default theme.
+ // So we have to do this for each test case.
+ ThemeDB::get_singleton()->finalize_theme();
+
RenderingServer::get_singleton()->sync();
RenderingServer::get_singleton()->global_shader_parameters_clear();
RenderingServer::get_singleton()->finish();
diff --git a/thirdparty/README.md b/thirdparty/README.md
index ff8f1d5591..bd3c626b65 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -154,25 +154,68 @@ Files extracted from upstream source:
## fonts
-- `NotoSans*.woff2`, `NotoNaskhArabicUI_*.woff2`:
- * Upstream: https://github.com/googlefonts/noto-fonts
- * Version: v2017-10-24-phase3-second-cleanup
- * License: OFL-1.1
- * Comment: Use UI font variant if available, because it has tight vertical metrics and
- good for UI.
-- `JetBrainsMono_Regular.woff2`:
- * Upstream: https://github.com/JetBrains/JetBrainsMono
- * Version: 2.242
- * License: OFL-1.1
- `DroidSans*.woff2`:
* Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/
* Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted)
* License: Apache 2.0
+- `JetBrainsMono_Regular.woff2`:
+ * Upstream: https://github.com/JetBrains/JetBrainsMono
+ * Version: 2.304 (cd5227bd1f61dff3bbd6c814ceaf7ffd95e947d9, 2023)
+ * License: OFL-1.1
+- `NotoNaskhArabicUI*.woff2`:
+ * Upstream: https://github.com/notofonts/arabic
+ * Version: 2.014 (133ccaebf922ca080a7eef22998611ac3c242df9, 2022)
+ * License: OFL-1.1
+- `NotoSans*.woff2`:
+ * Upstream: https://github.com/notofonts/latin-greek-cyrillic
+ * Version: 2.012 (9ea0c8d37bff0c0067b03777f40aa04f2bf78f99, 2023)
+ * License: OFL-1.1
+- `NotoSansBengali*.woff2`:
+ * Upstream: https://github.com/notofonts/bengali
+ * Version: 2.003 (020a5701f6fc6a363d5eccbae45e37714c0ad686, 2022)
+ * License: OFL-1.1
+- `NotoSansDevanagari*.woff2`:
+ * Upstream: https://github.com/notofonts/devanagari
+ * Version: 2.004 (f8f27e49da0ec9e5e38ecf3628671f05b24dd955, 2023)
+ * License: OFL-1.1
+- `NotoSansGeorgian*.woff2`:
+ * Upstream: https://github.com/notofonts/georgian
+ * Version: 2.002 (243ec9aa1d4ec58cc42120d30faac1a102fbfeb9, 2022)
+ * License: OFL-1.1
+- `NotoSansHebrew*.woff2`:
+ * Upstream: https://github.com/notofonts/hebrew
+ * Version: 2.003 (caa7ab0614fb5b37cc003d9bf3d7d3e765331110, 2022)
+ * License: OFL-1.1
+- `NotoSansMalayalam*.woff2`:
+ * Upstream: https://github.com/notofonts/malayalam
+ * Version: 2.104 (0fd65e553a6af3dc1c09ed39dfe8933e01c17b32, 2023)
+ * License: OFL-1.1
+- `NotoSansOriya*.woff2`:
+ * Upstream: https://github.com/notofonts/oriya
+ * Version: 2.005 (9377f242b247df12d0bf4cecd93b9c4b18036fbd, 2023)
+ * License: OFL-1.1
+- `NotoSansSinhala*.woff2`:
+ * Upstream: https://github.com/notofonts/sinhala
+ * Version: 2.006 (66e5a2ed9797e575222d6e7c5b3710c7bf68be79, 2022)
+ * License: OFL-1.1
+- `NotoSansTamil*.woff2`:
+ * Upstream: https://github.com/notofonts/tamil
+ * Version: 2.004 (f34a08d1ae3fa810581f63410296d971bdcd62dc, 2023)
+ * License: OFL-1.1
+- `NotoSansTelugu*.woff2`:
+ * Upstream: https://github.com/notofonts/telugu
+ * Version: 2.004 (68a6a8170cba5b2e9b45029ef36994961e8f614c, 2023)
+ * License: OFL-1.1
+- `NotoSansThai*.woff2`:
+ * Upstream: https://github.com/notofonts/thai
+ * Version: 2.001 (09af528011390f35abf15cf86068dae208f512c4, 2022)
+ * License: OFL-1.1
- `OpenSans_SemiBold.woff2`:
* Upstream: https://fonts.google.com/specimen/Open+Sans
* Version: 1.10 (downloaded from Google Fonts in February 2021)
* License: Apache 2.0
-- All fonts are converted from the `.ttf` sources using `https://github.com/google/woff2` tool.
+- All fonts are converted from the unhinted `.ttf` sources using `https://github.com/google/woff2` tool.
+- Comment: Use UI font variant if available, because it has tight vertical metrics and good for UI.
## freetype
@@ -250,7 +293,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 8.0.0 (b4305532a7746422e0b615eee6304119c1092fd8, 2023)
+- Version: 8.1.1 (1d665c2b521512cdd56964138fc601debd1f1177, 2023)
- License: MIT
Files extracted from upstream source:
@@ -396,9 +439,8 @@ File extracted from upstream release tarball:
- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` except `config_psa.h` and `psa_util.h`.
- All `*.c` and `*.h` from `library/` to `thirdparty/mbedtls/library/` except those starting with `psa_*`.
- The `LICENSE` file.
-- Applied the patch in `patches/1453.diff` to fix UWP build (upstream PR:
- https://github.com/ARMmbed/mbedtls/pull/1453).
- Applied the patch in `patches/windows-arm64-hardclock.diff`
+- Applied the patch in `patches/windows-arm64-hardclock.diff`.
+ Applied the patch in `aesni-no-arm-intrinsics.patch` to fix MSVC ARM build.
- Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
providing configuration for light bundling with core.
- Added the file `godot_module_mbedtls_config.h` to customize the build configuration when bundling the full library.
diff --git a/thirdparty/fonts/JetBrainsMono_Regular.woff2 b/thirdparty/fonts/JetBrainsMono_Regular.woff2
index 490104645b..dc698ffb83 100644
--- a/thirdparty/fonts/JetBrainsMono_Regular.woff2
+++ b/thirdparty/fonts/JetBrainsMono_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoNaskhArabicUI_Bold.woff2 b/thirdparty/fonts/NotoNaskhArabicUI_Bold.woff2
index 72358d6eb1..e9a834ac69 100644
--- a/thirdparty/fonts/NotoNaskhArabicUI_Bold.woff2
+++ b/thirdparty/fonts/NotoNaskhArabicUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoNaskhArabicUI_Regular.woff2 b/thirdparty/fonts/NotoNaskhArabicUI_Regular.woff2
index 1195d4174e..b0c0aaf766 100644
--- a/thirdparty/fonts/NotoNaskhArabicUI_Regular.woff2
+++ b/thirdparty/fonts/NotoNaskhArabicUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansBengaliUI_Bold.woff2 b/thirdparty/fonts/NotoSansBengaliUI_Bold.woff2
index 03adf85fdc..c0087a2453 100644
--- a/thirdparty/fonts/NotoSansBengaliUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansBengaliUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansBengaliUI_Regular.woff2 b/thirdparty/fonts/NotoSansBengaliUI_Regular.woff2
index a6a3ffa3a7..219792295a 100644
--- a/thirdparty/fonts/NotoSansBengaliUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansBengaliUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansDevanagariUI_Bold.woff2 b/thirdparty/fonts/NotoSansDevanagariUI_Bold.woff2
index 6c835712cb..d3d34ff8e1 100644
--- a/thirdparty/fonts/NotoSansDevanagariUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansDevanagariUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansDevanagariUI_Regular.woff2 b/thirdparty/fonts/NotoSansDevanagariUI_Regular.woff2
index 486896e6e9..333562f449 100644
--- a/thirdparty/fonts/NotoSansDevanagariUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansDevanagariUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansGeorgian_Bold.woff2 b/thirdparty/fonts/NotoSansGeorgian_Bold.woff2
index 104afa150c..c5e25ffe22 100644
--- a/thirdparty/fonts/NotoSansGeorgian_Bold.woff2
+++ b/thirdparty/fonts/NotoSansGeorgian_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansGeorgian_Regular.woff2 b/thirdparty/fonts/NotoSansGeorgian_Regular.woff2
index 0a7b9e878b..64ff0e84d8 100644
--- a/thirdparty/fonts/NotoSansGeorgian_Regular.woff2
+++ b/thirdparty/fonts/NotoSansGeorgian_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansHebrew_Bold.woff2 b/thirdparty/fonts/NotoSansHebrew_Bold.woff2
index 96c5ae1349..01768b6416 100644
--- a/thirdparty/fonts/NotoSansHebrew_Bold.woff2
+++ b/thirdparty/fonts/NotoSansHebrew_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansHebrew_Regular.woff2 b/thirdparty/fonts/NotoSansHebrew_Regular.woff2
index 17eadedc6f..980b7d3bf8 100644
--- a/thirdparty/fonts/NotoSansHebrew_Regular.woff2
+++ b/thirdparty/fonts/NotoSansHebrew_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansMalayalamUI_Bold.woff2 b/thirdparty/fonts/NotoSansMalayalamUI_Bold.woff2
index 5f6bacb0c3..8757bf3584 100644
--- a/thirdparty/fonts/NotoSansMalayalamUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansMalayalamUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansMalayalamUI_Regular.woff2 b/thirdparty/fonts/NotoSansMalayalamUI_Regular.woff2
index c54a82a874..cd266fafd3 100644
--- a/thirdparty/fonts/NotoSansMalayalamUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansMalayalamUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansOriyaUI_Bold.woff2 b/thirdparty/fonts/NotoSansOriyaUI_Bold.woff2
deleted file mode 100644
index b7e34302e2..0000000000
--- a/thirdparty/fonts/NotoSansOriyaUI_Bold.woff2
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/NotoSansOriyaUI_Regular.woff2 b/thirdparty/fonts/NotoSansOriyaUI_Regular.woff2
deleted file mode 100644
index e64090cd77..0000000000
--- a/thirdparty/fonts/NotoSansOriyaUI_Regular.woff2
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/NotoSansOriya_Bold.woff2 b/thirdparty/fonts/NotoSansOriya_Bold.woff2
new file mode 100644
index 0000000000..333abfaae0
--- /dev/null
+++ b/thirdparty/fonts/NotoSansOriya_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansOriya_Regular.woff2 b/thirdparty/fonts/NotoSansOriya_Regular.woff2
new file mode 100644
index 0000000000..c9b7c4a74e
--- /dev/null
+++ b/thirdparty/fonts/NotoSansOriya_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansSinhalaUI_Bold.woff2 b/thirdparty/fonts/NotoSansSinhalaUI_Bold.woff2
index 01dbd1bc8f..7facb291bd 100644
--- a/thirdparty/fonts/NotoSansSinhalaUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansSinhalaUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansSinhalaUI_Regular.woff2 b/thirdparty/fonts/NotoSansSinhalaUI_Regular.woff2
index 504c9d0809..8059db385f 100644
--- a/thirdparty/fonts/NotoSansSinhalaUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansSinhalaUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansTamilUI_Bold.woff2 b/thirdparty/fonts/NotoSansTamilUI_Bold.woff2
index 96967b0cce..ed428dedbd 100644
--- a/thirdparty/fonts/NotoSansTamilUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansTamilUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansTamilUI_Regular.woff2 b/thirdparty/fonts/NotoSansTamilUI_Regular.woff2
index e9b2bee582..d32dc96ae6 100644
--- a/thirdparty/fonts/NotoSansTamilUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansTamilUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansTeluguUI_Bold.woff2 b/thirdparty/fonts/NotoSansTeluguUI_Bold.woff2
index 2885bf991d..4de7b9f28d 100644
--- a/thirdparty/fonts/NotoSansTeluguUI_Bold.woff2
+++ b/thirdparty/fonts/NotoSansTeluguUI_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansTeluguUI_Regular.woff2 b/thirdparty/fonts/NotoSansTeluguUI_Regular.woff2
index ac5e66d8f6..0d9fe71d3a 100644
--- a/thirdparty/fonts/NotoSansTeluguUI_Regular.woff2
+++ b/thirdparty/fonts/NotoSansTeluguUI_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansThaiUI_Bold.woff2 b/thirdparty/fonts/NotoSansThaiUI_Bold.woff2
deleted file mode 100644
index 202995c066..0000000000
--- a/thirdparty/fonts/NotoSansThaiUI_Bold.woff2
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/NotoSansThaiUI_Regular.woff2 b/thirdparty/fonts/NotoSansThaiUI_Regular.woff2
deleted file mode 100644
index 2fb284f21f..0000000000
--- a/thirdparty/fonts/NotoSansThaiUI_Regular.woff2
+++ /dev/null
Binary files differ
diff --git a/thirdparty/fonts/NotoSansThai_Bold.woff2 b/thirdparty/fonts/NotoSansThai_Bold.woff2
new file mode 100644
index 0000000000..68dc6c1392
--- /dev/null
+++ b/thirdparty/fonts/NotoSansThai_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSansThai_Regular.woff2 b/thirdparty/fonts/NotoSansThai_Regular.woff2
new file mode 100644
index 0000000000..ae29cbdb10
--- /dev/null
+++ b/thirdparty/fonts/NotoSansThai_Regular.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSans_Bold.woff2 b/thirdparty/fonts/NotoSans_Bold.woff2
index 36a5b89999..09a3297a6a 100644
--- a/thirdparty/fonts/NotoSans_Bold.woff2
+++ b/thirdparty/fonts/NotoSans_Bold.woff2
Binary files differ
diff --git a/thirdparty/fonts/NotoSans_Regular.woff2 b/thirdparty/fonts/NotoSans_Regular.woff2
index d449eed8d7..59c252ede1 100644
--- a/thirdparty/fonts/NotoSans_Regular.woff2
+++ b/thirdparty/fonts/NotoSans_Regular.woff2
Binary files differ
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
index d995ba0d4c..4f85d3ce5e 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
@@ -439,6 +439,16 @@ struct MarkGlyphSetsFormat1
bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+ template <typename set_t>
+ void collect_coverage (hb_vector_t<set_t> &sets) const
+ {
+ for (const auto &offset : coverage)
+ {
+ const auto &cov = this+offset;
+ cov.collect_coverage (sets.push ());
+ }
+ }
+
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
@@ -492,6 +502,15 @@ struct MarkGlyphSets
}
}
+ template <typename set_t>
+ void collect_coverage (hb_vector_t<set_t> &sets) const
+ {
+ switch (u.format) {
+ case 1: u.format1.collect_coverage (sets); return;
+ default:return;
+ }
+ }
+
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
@@ -856,6 +875,10 @@ struct GDEF
hb_blob_destroy (table.get_blob ());
table = hb_blob_get_empty ();
}
+
+#ifndef HB_NO_GDEF_CACHE
+ table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
+#endif
}
~accelerator_t () { table.destroy (); }
@@ -879,8 +902,18 @@ struct GDEF
}
+ bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ {
+ return
+#ifndef HB_NO_GDEF_CACHE
+ mark_glyph_set_digests[set_index].may_have (glyph_id) &&
+#endif
+ table->mark_set_covers (set_index, glyph_id);
+ }
+
hb_blob_ptr_t<GDEF> table;
#ifndef HB_NO_GDEF_CACHE
+ hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
mutable hb_cache_t<21, 3, 8> glyph_props_cache;
#endif
};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
index a459124dfe..54852aae75 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -91,7 +91,13 @@ struct CursivePosFormat1
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+ if (unlikely (!coverage.sanitize (c, this)))
+ return_trace (false);
+
+ if (c->lazy_some_gpos)
+ return_trace (entryExitRecord.sanitize_shallow (c));
+ else
+ return_trace (entryExitRecord.sanitize (c, this));
}
bool intersects (const hb_set_t *glyphs) const
@@ -119,10 +125,11 @@ struct CursivePosFormat1
hb_buffer_t *buffer = c->buffer;
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
- if (!this_record.entryAnchor) return_trace (false);
+ if (!this_record.entryAnchor ||
+ unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset_fast (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx);
unsigned unsafe_from;
if (unlikely (!skippy_iter.prev (&unsafe_from)))
{
@@ -131,7 +138,8 @@ struct CursivePosFormat1
}
const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
- if (!prev_record.exitAnchor)
+ if (!prev_record.exitAnchor ||
+ unlikely (!prev_record.exitAnchor.sanitize (&c->sanitizer, this)))
{
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
@@ -200,8 +208,8 @@ struct CursivePosFormat1
* Arabic. */
unsigned int child = i;
unsigned int parent = j;
- hb_position_t x_offset = entry_x - exit_x;
- hb_position_t y_offset = entry_y - exit_y;
+ hb_position_t x_offset = roundf (entry_x - exit_x);
+ hb_position_t y_offset = roundf (entry_y - exit_y);
if (!(c->lookup_props & LookupFlag::RightToLeft))
{
unsigned int k = child;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index 9dae5ce5da..72535f4c98 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset_fast (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx);
skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
unsigned unsafe_from;
if (unlikely (!skippy_iter.prev (&unsafe_from)))
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
index 714b4bec72..e4a2006fb9 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -110,7 +110,7 @@ struct PairPosFormat1_3
if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset_fast (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx);
unsigned unsafe_to;
if (unlikely (!skippy_iter.next (&unsafe_to)))
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
index 05e6c0fa54..1bde9e755e 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -131,7 +131,7 @@ struct PairPosFormat2_4
if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset_fast (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx);
unsigned unsafe_to;
if (unlikely (!skippy_iter.next (&unsafe_to)))
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
index 3222477764..72bf0e99b5 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
@@ -22,7 +22,7 @@ struct PairValueRecord
ValueRecord values; /* Positioning data for the first glyph
* followed by for second glyph */
public:
- DEFINE_SIZE_ARRAY (Types::size, values);
+ DEFINE_SIZE_ARRAY (Types::HBGlyphID::static_size, values);
int cmp (hb_codepoint_t k) const
{ return secondGlyph.cmp (k); }
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
index db3fc55f77..402ed12ae2 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
@@ -19,7 +19,6 @@ struct Ligature
* in writing direction */
public:
DEFINE_SIZE_ARRAY (Types::size + 2, component);
- DEFINE_SIZE_MAX (65536 * Types::HBGlyphID::static_size);
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
index 0ba262e901..08665438c4 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
@@ -72,19 +72,14 @@ struct LigatureSet
;
}
- static bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED)
- {
- return true;
- }
-
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int num_ligs = ligature.len;
-#ifndef HB_NO_OT_LIGATURES_FAST_PATH
- if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 2)
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+ if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4)
#endif
{
slow:
@@ -97,10 +92,12 @@ struct LigatureSet
}
/* This version is optimized for speed by matching the first component
- * of the ligature here, instead of calling into the ligation code. */
+ * of the ligature here, instead of calling into the ligation code.
+ *
+ * This is replicated in ChainRuleSet and RuleSet. */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (c->buffer->idx, 1);
+ skippy_iter.reset (c->buffer->idx);
skippy_iter.set_match_func (match_always, nullptr);
skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
unsigned unsafe_to;
@@ -118,6 +115,8 @@ struct LigatureSet
goto slow;
}
}
+ else
+ goto slow;
bool unsafe_to_concat = false;
@@ -125,7 +124,7 @@ struct LigatureSet
{
const auto &lig = this+ligature.arrayZ[i];
if (unlikely (lig.component.lenP1 <= 1) ||
- lig.component[1] == first)
+ lig.component.arrayZ[0] == first)
{
if (lig.apply (c))
{
diff --git a/thirdparty/harfbuzz/src/graph/classdef-graph.hh b/thirdparty/harfbuzz/src/graph/classdef-graph.hh
index 4ae0c13acc..c1432883ff 100644
--- a/thirdparty/harfbuzz/src/graph/classdef-graph.hh
+++ b/thirdparty/harfbuzz/src/graph/classdef-graph.hh
@@ -72,7 +72,7 @@ struct ClassDef : public OT::ClassDef
class_def_link->width = SmallTypes::size;
class_def_link->objidx = class_def_prime_id;
class_def_link->position = link_position;
- class_def_prime_vertex.parents.push (parent_id);
+ class_def_prime_vertex.add_parent (parent_id);
return true;
}
diff --git a/thirdparty/harfbuzz/src/graph/coverage-graph.hh b/thirdparty/harfbuzz/src/graph/coverage-graph.hh
index bd6e91a1f2..4f44e076d1 100644
--- a/thirdparty/harfbuzz/src/graph/coverage-graph.hh
+++ b/thirdparty/harfbuzz/src/graph/coverage-graph.hh
@@ -96,7 +96,7 @@ struct Coverage : public OT::Layout::Common::Coverage
coverage_link->width = SmallTypes::size;
coverage_link->objidx = coverage_prime_id;
coverage_link->position = link_position;
- coverage_prime_vertex.parents.push (parent_id);
+ coverage_prime_vertex.add_parent (parent_id);
return (Coverage*) coverage_prime_vertex.obj.head;
}
diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh
index 53d0bc94e1..0680958190 100644
--- a/thirdparty/harfbuzz/src/graph/graph.hh
+++ b/thirdparty/harfbuzz/src/graph/graph.hh
@@ -43,12 +43,28 @@ struct graph_t
{
hb_serialize_context_t::object_t obj;
int64_t distance = 0 ;
- int64_t space = 0 ;
- hb_vector_t<unsigned> parents;
+ unsigned space = 0 ;
unsigned start = 0;
unsigned end = 0;
unsigned priority = 0;
-
+ private:
+ unsigned incoming_edges_ = 0;
+ unsigned single_parent = (unsigned) -1;
+ hb_hashmap_t<unsigned, unsigned> parents;
+ public:
+
+ auto parents_iter () const HB_AUTO_RETURN
+ (
+ hb_concat (
+ hb_iter (&single_parent, single_parent != (unsigned) -1),
+ parents.keys_ref ()
+ )
+ )
+
+ bool in_error () const
+ {
+ return parents.in_error ();
+ }
bool link_positions_valid (unsigned num_objects, bool removed_nil)
{
@@ -143,7 +159,9 @@ struct graph_t
hb_swap (a.obj, b.obj);
hb_swap (a.distance, b.distance);
hb_swap (a.space, b.space);
+ hb_swap (a.single_parent, b.single_parent);
hb_swap (a.parents, b.parents);
+ hb_swap (a.incoming_edges_, b.incoming_edges_);
hb_swap (a.start, b.start);
hb_swap (a.end, b.end);
hb_swap (a.priority, b.priority);
@@ -154,6 +172,7 @@ struct graph_t
{
hb_hashmap_t<unsigned, unsigned> result;
+ result.alloc (obj.real_links.length);
for (const auto& l : obj.real_links) {
result.set (l.position, l.objidx);
}
@@ -163,22 +182,76 @@ struct graph_t
bool is_shared () const
{
- return parents.length > 1;
+ return parents.get_population () > 1;
}
unsigned incoming_edges () const
{
- return parents.length;
+ if (HB_DEBUG_SUBSET_REPACK)
+ {
+ assert (incoming_edges_ == (single_parent != (unsigned) -1) +
+ (parents.values_ref () | hb_reduce (hb_add, 0)));
+ }
+ return incoming_edges_;
+ }
+
+ void reset_parents ()
+ {
+ incoming_edges_ = 0;
+ single_parent = (unsigned) -1;
+ parents.reset ();
+ }
+
+ void add_parent (unsigned parent_index)
+ {
+ assert (parent_index != (unsigned) -1);
+ if (incoming_edges_ == 0)
+ {
+ single_parent = parent_index;
+ incoming_edges_ = 1;
+ return;
+ }
+ else if (single_parent != (unsigned) -1)
+ {
+ assert (incoming_edges_ == 1);
+ if (!parents.set (single_parent, 1))
+ return;
+ single_parent = (unsigned) -1;
+ }
+
+ unsigned *v;
+ if (parents.has (parent_index, &v))
+ {
+ (*v)++;
+ incoming_edges_++;
+ }
+ else if (parents.set (parent_index, 1))
+ incoming_edges_++;
}
void remove_parent (unsigned parent_index)
{
- unsigned count = parents.length;
- for (unsigned i = 0; i < count; i++)
+ if (parent_index == single_parent)
{
- if (parents.arrayZ[i] != parent_index) continue;
- parents.remove_unordered (i);
- break;
+ single_parent = (unsigned) -1;
+ incoming_edges_--;
+ return;
+ }
+
+ unsigned *v;
+ if (parents.has (parent_index, &v))
+ {
+ incoming_edges_--;
+ if (*v > 1)
+ (*v)--;
+ else
+ parents.del (parent_index);
+
+ if (incoming_edges_ == 1)
+ {
+ single_parent = *parents.keys ();
+ parents.reset ();
+ }
}
}
@@ -199,20 +272,46 @@ struct graph_t
}
}
- void remap_parents (const hb_vector_t<unsigned>& id_map)
+ bool remap_parents (const hb_vector_t<unsigned>& id_map)
{
- unsigned count = parents.length;
- for (unsigned i = 0; i < count; i++)
- parents.arrayZ[i] = id_map[parents.arrayZ[i]];
+ if (single_parent != (unsigned) -1)
+ {
+ assert (single_parent < id_map.length);
+ single_parent = id_map[single_parent];
+ return true;
+ }
+
+ hb_hashmap_t<unsigned, unsigned> new_parents;
+ new_parents.alloc (parents.get_population ());
+ for (auto _ : parents)
+ {
+ assert (_.first < id_map.length);
+ assert (!new_parents.has (id_map[_.first]));
+ new_parents.set (id_map[_.first], _.second);
+ }
+
+ if (new_parents.in_error ())
+ return false;
+
+ parents = std::move (new_parents);
+ return true;
}
void remap_parent (unsigned old_index, unsigned new_index)
{
- unsigned count = parents.length;
- for (unsigned i = 0; i < count; i++)
+ if (single_parent != (unsigned) -1)
+ {
+ if (single_parent == old_index)
+ single_parent = new_index;
+ return;
+ }
+
+ const unsigned *pv;
+ if (parents.has (old_index, &pv))
{
- if (parents.arrayZ[i] == old_index)
- parents.arrayZ[i] = new_index;
+ unsigned v = *pv;
+ parents.set (new_index, v);
+ parents.del (old_index);
}
}
@@ -419,7 +518,7 @@ struct graph_t
link->width = 2;
link->objidx = child_id;
link->position = (char*) offset - (char*) v.obj.head;
- vertices_[child_id].parents.push (parent_id);
+ vertices_[child_id].add_parent (parent_id);
}
/*
@@ -465,7 +564,7 @@ struct graph_t
{
unsigned next_id = queue.pop_minimum().second;
- hb_swap (sorted_graph[new_id], vertices_[next_id]);
+ sorted_graph[new_id] = std::move (vertices_[next_id]);
const vertex_t& next = sorted_graph[new_id];
if (unlikely (!check_success(new_id >= 0))) {
@@ -493,8 +592,8 @@ struct graph_t
check_success (!queue.in_error ());
check_success (!sorted_graph.in_error ());
- remap_all_obj_indices (id_map, &sorted_graph);
- hb_swap (vertices_, sorted_graph);
+ check_success (remap_all_obj_indices (id_map, &sorted_graph));
+ vertices_ = std::move (sorted_graph);
if (!check_success (new_id == -1))
print_orphaned_nodes ();
@@ -605,7 +704,7 @@ struct graph_t
{
unsigned child_idx = index_for_offset (node_idx, offset);
auto& child = vertices_[child_idx];
- for (unsigned p : child.parents)
+ for (unsigned p : child.parents_iter ())
{
if (p != node_idx) {
return duplicate (node_idx, child_idx);
@@ -688,12 +787,15 @@ struct graph_t
subgraph.set (root_idx, wide_parents (root_idx, parents));
find_subgraph (root_idx, subgraph);
}
+ if (subgraph.in_error ())
+ return false;
unsigned original_root_idx = root_idx ();
hb_map_t index_map;
bool made_changes = false;
for (auto entry : subgraph.iter ())
{
+ assert (entry.first < vertices_.length);
const auto& node = vertices_[entry.first];
unsigned subgraph_incoming_edges = entry.second;
@@ -749,10 +851,10 @@ struct graph_t
{
for (const auto& link : vertices_[node_idx].obj.all_links ())
{
- const uint32_t *v;
+ hb_codepoint_t *v;
if (subgraph.has (link.objidx, &v))
{
- subgraph.set (link.objidx, *v + 1);
+ (*v)++;
continue;
}
subgraph.set (link.objidx, 1);
@@ -824,7 +926,7 @@ struct graph_t
new_link->position = (const char*) new_offset - (const char*) new_v.obj.head;
auto& child = vertices_[child_id];
- child.parents.push (new_parent_idx);
+ child.add_parent (new_parent_idx);
old_v.remove_real_link (child_id, old_offset);
child.remove_parent (old_parent_idx);
@@ -868,18 +970,18 @@ struct graph_t
clone->obj.tail = child.obj.tail;
clone->distance = child.distance;
clone->space = child.space;
- clone->parents.reset ();
+ clone->reset_parents ();
unsigned clone_idx = vertices_.length - 2;
for (const auto& l : child.obj.real_links)
{
clone->obj.real_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
+ vertices_[l.objidx].add_parent (clone_idx);
}
for (const auto& l : child.obj.virtual_links)
{
clone->obj.virtual_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
+ vertices_[l.objidx].add_parent (clone_idx);
}
check_success (!clone->obj.real_links.in_error ());
@@ -1008,13 +1110,13 @@ struct graph_t
{
update_parents();
- if (root().parents)
+ if (root().incoming_edges ())
// Root cannot have parents.
return false;
for (unsigned i = 0; i < root_idx (); i++)
{
- if (!vertices_[i].parents)
+ if (!vertices_[i].incoming_edges ())
return false;
}
return true;
@@ -1078,14 +1180,14 @@ struct graph_t
parents_invalid = true;
update_parents();
- if (root().parents) {
+ if (root().incoming_edges ()) {
DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
}
for (unsigned i = 0; i < root_idx (); i++)
{
const auto& v = vertices_[i];
- if (!v.parents)
+ if (!v.incoming_edges ())
DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
}
}
@@ -1117,6 +1219,8 @@ struct graph_t
unsigned space_for (unsigned index, unsigned* root = nullptr) const
{
+ loop:
+ assert (index < vertices_.length);
const auto& node = vertices_[index];
if (node.space)
{
@@ -1125,14 +1229,15 @@ struct graph_t
return node.space;
}
- if (!node.parents)
+ if (!node.incoming_edges ())
{
if (root)
*root = index;
return 0;
}
- return space_for (node.parents[0], root);
+ index = *node.parents_iter ();
+ goto loop;
}
void err_other_error () { this->successful = false; }
@@ -1156,12 +1261,8 @@ struct graph_t
unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
{
unsigned count = 0;
- hb_set_t visited;
- for (unsigned p : vertices_[node_idx].parents)
+ for (unsigned p : vertices_[node_idx].parents_iter ())
{
- if (visited.has (p)) continue;
- visited.add (p);
-
// Only real links can be wide
for (const auto& l : vertices_[p].obj.real_links)
{
@@ -1191,20 +1292,18 @@ struct graph_t
unsigned count = vertices_.length;
for (unsigned i = 0; i < count; i++)
- vertices_.arrayZ[i].parents.reset ();
+ vertices_.arrayZ[i].reset_parents ();
for (unsigned p = 0; p < count; p++)
{
for (auto& l : vertices_.arrayZ[p].obj.all_links ())
- {
- vertices_[l.objidx].parents.push (p);
- }
+ vertices_[l.objidx].add_parent (p);
}
for (unsigned i = 0; i < count; i++)
// parents arrays must be accurate or downstream operations like cycle detection
// and sorting won't work correctly.
- check_success (!vertices_.arrayZ[i].parents.in_error ());
+ check_success (!vertices_.arrayZ[i].in_error ());
parents_invalid = false;
}
@@ -1248,12 +1347,8 @@ struct graph_t
// (such as a fibonacci queue) with a fast decrease priority.
unsigned count = vertices_.length;
for (unsigned i = 0; i < count; i++)
- {
- if (i == vertices_.length - 1)
- vertices_.arrayZ[i].distance = 0;
- else
- vertices_.arrayZ[i].distance = hb_int_max (int64_t);
- }
+ vertices_.arrayZ[i].distance = hb_int_max (int64_t);
+ vertices_.tail ().distance = 0;
hb_priority_queue_t queue;
queue.insert (0, vertices_.length - 1);
@@ -1273,15 +1368,15 @@ struct graph_t
{
if (visited[link.objidx]) continue;
- const auto& child = vertices_[link.objidx].obj;
+ const auto& child = vertices_.arrayZ[link.objidx].obj;
unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
int64_t child_weight = (child.tail - child.head) +
- ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
+ ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1);
int64_t child_distance = next_distance + child_weight;
- if (child_distance < vertices_[link.objidx].distance)
+ if (child_distance < vertices_.arrayZ[link.objidx].distance)
{
- vertices_[link.objidx].distance = child_distance;
+ vertices_.arrayZ[link.objidx].distance = child_distance;
queue.insert (child_distance, link.objidx);
}
}
@@ -1309,7 +1404,7 @@ struct graph_t
unsigned old_idx = link.objidx;
link.objidx = new_idx;
vertices_[old_idx].remove_parent (parent_idx);
- vertices_[new_idx].parents.push (parent_idx);
+ vertices_[new_idx].add_parent (parent_idx);
}
/*
@@ -1337,18 +1432,20 @@ struct graph_t
/*
* Updates all objidx's in all links using the provided mapping.
*/
- void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
+ bool remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
hb_vector_t<vertex_t>* sorted_graph) const
{
unsigned count = sorted_graph->length;
for (unsigned i = 0; i < count; i++)
{
- (*sorted_graph)[i].remap_parents (id_map);
+ if (!(*sorted_graph)[i].remap_parents (id_map))
+ return false;
for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ())
{
link.objidx = id_map[link.objidx];
}
}
+ return true;
}
/*
@@ -1379,7 +1476,7 @@ struct graph_t
for (const auto& l : v.obj.all_links ())
find_connected_nodes (l.objidx, targets, visited, connected);
- for (unsigned p : v.parents)
+ for (unsigned p : v.parents_iter ())
find_connected_nodes (p, targets, visited, connected);
}
diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh
index 78d5096325..303517f687 100644
--- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh
+++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh
@@ -225,7 +225,7 @@ struct Lookup : public OT::Lookup
if (is_ext)
{
unsigned ext_id = create_extension_subtable (c, subtable_id, type);
- c.graph.vertices_[subtable_id].parents.push (ext_id);
+ c.graph.vertices_[subtable_id].add_parent (ext_id);
subtable_id = ext_id;
}
@@ -234,7 +234,7 @@ struct Lookup : public OT::Lookup
link->objidx = subtable_id;
link->position = (char*) &new_lookup->subTable[offset_index++] -
(char*) new_lookup;
- c.graph.vertices_[subtable_id].parents.push (this_index);
+ c.graph.vertices_[subtable_id].add_parent (this_index);
}
}
@@ -315,7 +315,7 @@ struct Lookup : public OT::Lookup
// Make extension point at the subtable.
auto& ext_vertex = c.graph.vertices_[ext_index];
auto& subtable_vertex = c.graph.vertices_[subtable_index];
- ext_vertex.parents.push (lookup_index);
+ ext_vertex.add_parent (lookup_index);
subtable_vertex.remap_parent (lookup_index, ext_index);
return true;
diff --git a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh
index f655b71558..ad158cc9e8 100644
--- a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh
+++ b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh
@@ -419,7 +419,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
class_def_link->width = SmallTypes::size;
class_def_link->objidx = class_def_2_id;
class_def_link->position = 10;
- graph.vertices_[class_def_2_id].parents.push (pair_pos_prime_id);
+ graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id);
graph.duplicate (pair_pos_prime_id, class_def_2_id);
return pair_pos_prime_id;
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh
index 2ba9355b06..c72c0865d3 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh
@@ -111,13 +111,13 @@ struct TrackData
break;
}
}
- if (!trackTableEntry) return 0.;
+ if (!trackTableEntry) return 0;
/*
* Choose size.
*/
unsigned int sizes = nSizes;
- if (!sizes) return 0.;
+ if (!sizes) return 0;
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh
index 374965d56e..6cabc7fb02 100644
--- a/thirdparty/harfbuzz/src/hb-algs.hh
+++ b/thirdparty/harfbuzz/src/hb-algs.hh
@@ -283,8 +283,8 @@ HB_FUNCOBJ (hb_bool);
// Compression function for Merkle-Damgard construction.
// This function is generated using the framework provided.
#define mix(h) ( \
- (h) ^= (h) >> 23, \
- (h) *= 0x2127599bf4325c37ULL, \
+ (void) ((h) ^= (h) >> 23), \
+ (void) ((h) *= 0x2127599bf4325c37ULL), \
(h) ^= (h) >> 47)
static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
@@ -362,10 +362,10 @@ struct
// https://github.com/harfbuzz/harfbuzz/pull/4228#issuecomment-1565079537
template <typename T,
hb_enable_if (std::is_integral<T>::value && sizeof (T) <= sizeof (uint32_t))> constexpr auto
- impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, v * 2654435761u /* Knuh's multiplicative hash */)
+ impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) v * 2654435761u /* Knuh's multiplicative hash */)
template <typename T,
hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto
- impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */)
+ impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */)
template <typename T> constexpr auto
impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh
index 4006fc4ebd..64dbf2e869 100644
--- a/thirdparty/harfbuzz/src/hb-bimap.hh
+++ b/thirdparty/harfbuzz/src/hb-bimap.hh
@@ -143,6 +143,7 @@ struct hb_inc_bimap_t
hb_codepoint_t skip (unsigned count)
{
hb_codepoint_t start = back_map.length;
+ back_map.alloc (back_map.length + count);
for (unsigned i = 0; i < count; i++)
back_map.push (HB_MAP_VALUE_INVALID);
return start;
diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh
index e578d2643f..e1826e12a5 100644
--- a/thirdparty/harfbuzz/src/hb-bit-page.hh
+++ b/thirdparty/harfbuzz/src/hb-bit-page.hh
@@ -89,14 +89,17 @@ struct hb_vector_size_t
struct hb_bit_page_t
{
- void init0 () { v.init0 (); }
- void init1 () { v.init1 (); }
+ void init0 () { v.init0 (); population = 0; }
+ void init1 () { v.init1 (); population = PAGE_BITS; }
+
+ void dirty () { population = UINT_MAX; }
static inline constexpr unsigned len ()
{ return ARRAY_LENGTH_CONST (v); }
bool is_empty () const
{
+ if (has_population ()) return !population;
return
+ hb_iter (v)
| hb_none
@@ -107,8 +110,8 @@ struct hb_bit_page_t
return hb_bytes_t ((const char *) &v, sizeof (v)).hash ();
}
- void add (hb_codepoint_t g) { elt (g) |= mask (g); }
- void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
+ void add (hb_codepoint_t g) { elt (g) |= mask (g); dirty (); }
+ void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); }
void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
@@ -120,20 +123,21 @@ struct hb_bit_page_t
*la |= (mask (b) << 1) - mask(a);
else
{
- *la |= ~(mask (a) - 1);
+ *la |= ~(mask (a) - 1llu);
la++;
hb_memset (la, 0xff, (char *) lb - (char *) la);
- *lb |= ((mask (b) << 1) - 1);
+ *lb |= ((mask (b) << 1) - 1llu);
}
+ dirty ();
}
void del_range (hb_codepoint_t a, hb_codepoint_t b)
{
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
- *la &= ~((mask (b) << 1) - mask(a));
+ *la &= ~((mask (b) << 1llu) - mask(a));
else
{
*la &= mask (a) - 1;
@@ -141,8 +145,9 @@ struct hb_bit_page_t
hb_memset (la, 0, (char *) lb - (char *) la);
- *lb &= ~((mask (b) << 1) - 1);
+ *lb &= ~((mask (b) << 1) - 1llu);
}
+ dirty ();
}
void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
{ if (v) add_range (a, b); else del_range (a, b); }
@@ -222,18 +227,25 @@ struct hb_bit_page_t
}
bool is_subset (const hb_bit_page_t &larger_page) const
{
+ if (has_population () && larger_page.has_population () &&
+ population > larger_page.population)
+ return false;
+
for (unsigned i = 0; i < len (); i++)
if (~larger_page.v[i] & v[i])
return false;
return true;
}
+ bool has_population () const { return population != UINT_MAX; }
unsigned int get_population () const
{
- return
+ if (has_population ()) return population;
+ population =
+ hb_iter (v)
| hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
;
+ return population;
}
bool next (hb_codepoint_t *codepoint) const
@@ -329,9 +341,9 @@ struct hb_bit_page_t
const elt_t& elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
static constexpr elt_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); }
+ mutable unsigned population;
vector_t v;
};
-static_assert (hb_bit_page_t::PAGE_BITS == sizeof (hb_bit_page_t) * 8, "");
#endif /* HB_BIT_PAGE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh
index a84d751fb3..9e60cb934a 100644
--- a/thirdparty/harfbuzz/src/hb-bit-set.hh
+++ b/thirdparty/harfbuzz/src/hb-bit-set.hh
@@ -30,7 +30,6 @@
#include "hb.hh"
#include "hb-bit-page.hh"
-#include "hb-machinery.hh"
struct hb_bit_set_t
@@ -183,6 +182,16 @@ struct hb_bit_set_t
return true;
}
+ /* Duplicated here from hb-machinery.hh to avoid including it. */
+ template<typename Type>
+ static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int offset)
+ {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+ return * reinterpret_cast<const Type*> ((const char *) P + offset);
+#pragma GCC diagnostic pop
+ }
+
template <typename T>
void set_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
{
@@ -553,6 +562,7 @@ struct hb_bit_set_t
count--;
page_map.arrayZ[count] = page_map.arrayZ[a];
page_at (count).v = op (page_at (a).v, other.page_at (b).v);
+ page_at (count).dirty ();
}
else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
{
@@ -571,7 +581,7 @@ struct hb_bit_set_t
count--;
page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
page_map.arrayZ[count].index = next_page++;
- page_at (count).v = other.page_at (b).v;
+ page_at (count) = other.page_at (b);
}
}
}
@@ -589,7 +599,7 @@ struct hb_bit_set_t
count--;
page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
page_map.arrayZ[count].index = next_page++;
- page_at (count).v = other.page_at (b).v;
+ page_at (count) = other.page_at (b);
}
assert (!count);
resize (newCount);
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index ace2a104fd..749ef9bd49 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -499,12 +499,12 @@ hb_buffer_t::set_masks (hb_mask_t value,
unsigned int cluster_start,
unsigned int cluster_end)
{
- hb_mask_t not_mask = ~mask;
- value &= mask;
-
if (!mask)
return;
+ hb_mask_t not_mask = ~mask;
+ value &= mask;
+
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh
index 4d48b7f167..f04ad58f11 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer.hh
@@ -464,13 +464,16 @@ struct hb_buffer_t
start, end,
true);
}
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
{
if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
return;
_set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
start, end,
- true);
+ false);
}
void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
{
@@ -478,6 +481,9 @@ struct hb_buffer_t
start, end,
true, true);
}
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
{
if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh
index 335c6976f6..816c55c7d3 100644
--- a/thirdparty/harfbuzz/src/hb-config.hh
+++ b/thirdparty/harfbuzz/src/hb-config.hh
@@ -183,7 +183,7 @@
#endif
#ifdef HB_OPTIMIZE_SIZE_MORE
-#define HB_NO_OT_LIGATURES_FAST_PATH
+#define HB_NO_OT_RULESETS_FAST_PATH
#endif
#ifdef HB_MINIMIZE_MEMORY_USAGE
diff --git a/thirdparty/harfbuzz/src/hb-kern.hh b/thirdparty/harfbuzz/src/hb-kern.hh
index 9ac744c9dd..0462a0ea8e 100644
--- a/thirdparty/harfbuzz/src/hb-kern.hh
+++ b/thirdparty/harfbuzz/src/hb-kern.hh
@@ -70,7 +70,7 @@ struct hb_kern_machine_t
continue;
}
- skippy_iter.reset (idx, 1);
+ skippy_iter.reset (idx);
unsigned unsafe_to;
if (!skippy_iter.next (&unsafe_to))
{
diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh
index cde1e99d6f..ecff94f1b6 100644
--- a/thirdparty/harfbuzz/src/hb-machinery.hh
+++ b/thirdparty/harfbuzz/src/hb-machinery.hh
@@ -131,10 +131,6 @@ static inline Type& StructAfter(TObject &X)
unsigned int get_size () const { return (size - (array).min_size + (array).get_size ()); } \
DEFINE_SIZE_ARRAY(size, array)
-#define DEFINE_SIZE_MAX(size) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) <= (size)) \
- static constexpr unsigned max_size = (size)
-
/*
diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh
index e8abeec636..42604ef7c2 100644
--- a/thirdparty/harfbuzz/src/hb-map.hh
+++ b/thirdparty/harfbuzz/src/hb-map.hh
@@ -78,6 +78,10 @@ struct hb_hashmap_t
hash (0),
value () {}
+ // Needed for https://github.com/harfbuzz/harfbuzz/issues/4138
+ K& get_key () { return key; }
+ V& get_value () { return value; }
+
bool is_used () const { return is_used_; }
void set_used (bool is_used) { is_used_ = is_used; }
void set_real (bool is_real) { is_real_ = is_real; }
@@ -405,23 +409,21 @@ struct hb_hashmap_t
auto keys_ref () const HB_AUTO_RETURN
(
+ iter_items ()
- | hb_map (&item_t::key)
+ | hb_map (&item_t::get_key)
)
auto keys () const HB_AUTO_RETURN
(
- + iter_items ()
- | hb_map (&item_t::key)
+ + keys_ref ()
| hb_map (hb_ridentity)
)
auto values_ref () const HB_AUTO_RETURN
(
+ iter_items ()
- | hb_map (&item_t::value)
+ | hb_map (&item_t::get_value)
)
auto values () const HB_AUTO_RETURN
(
- + iter_items ()
- | hb_map (&item_t::value)
+ + values_ref ()
| hb_map (hb_ridentity)
)
diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh
index 2982516283..6796906ba8 100644
--- a/thirdparty/harfbuzz/src/hb-null.hh
+++ b/thirdparty/harfbuzz/src/hb-null.hh
@@ -37,7 +37,7 @@
/* Global nul-content Null pool. Enlarge as necessary. */
-#define HB_NULL_POOL_SIZE 520
+#define HB_NULL_POOL_SIZE 640
template <typename T, typename>
struct _hb_has_min_size : hb_false_type {};
@@ -49,15 +49,6 @@ using hb_has_min_size = _hb_has_min_size<T, void>;
#define hb_has_min_size(T) hb_has_min_size<T>::value
template <typename T, typename>
-struct _hb_has_max_size : hb_false_type {};
-template <typename T>
-struct _hb_has_max_size<T, hb_void_t<decltype (T::max_size)>>
- : hb_true_type {};
-template <typename T>
-using hb_has_max_size = _hb_has_max_size<T, void>;
-#define hb_has_max_size(T) hb_has_max_size<T>::value
-
-template <typename T, typename>
struct _hb_has_null_size : hb_false_type {};
template <typename T>
struct _hb_has_null_size<T, hb_void_t<decltype (T::null_size)>>
diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh
index 6d464a3535..d3fdd1caf5 100644
--- a/thirdparty/harfbuzz/src/hb-open-type.hh
+++ b/thirdparty/harfbuzz/src/hb-open-type.hh
@@ -718,30 +718,6 @@ struct ArrayOf
return_trace (out);
}
- /* Special-case ArrayOf Offset16To structs with a maximum size. */
- template <typename T = Type,
- typename Base = void,
- hb_enable_if (hb_has_max_size (typename T::target_t) &&
- sizeof (T) == 2)>
- HB_ALWAYS_INLINE
- bool sanitize (hb_sanitize_context_t *c, const Base *base) const
- {
- TRACE_SANITIZE (this);
-
- if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
- unsigned max_len = 65536 + Type::target_t::max_size;
-
- if (unlikely (c->check_range_fast (base, max_len)))
- return_trace (true);
-
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!c->dispatch (arrayZ[i], base)))
- return_trace (false);
- return_trace (true);
- }
-
template <typename ...Ts>
HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
index a2f90c8f5e..923a32b26f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
@@ -94,10 +94,10 @@ struct CFFIndex
for (const auto &_ : +it)
{
unsigned len = _.length;
+ if (!len)
+ continue;
if (len <= 1)
{
- if (!len)
- continue;
*ret++ = *_.arrayZ;
continue;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
index 3d658ac626..1e81dcb5e3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
@@ -1061,6 +1061,8 @@ struct cff1
template <typename PRIVOPSET, typename PRIVDICTVAL>
struct accelerator_templ_t
{
+ static constexpr hb_tag_t tableTag = cff1::tableTag;
+
accelerator_templ_t (hb_face_t *face)
{
if (!face) return;
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
index 9913cdad0c..af24bb9986 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
@@ -390,6 +390,8 @@ struct cff2
template <typename PRIVOPSET, typename PRIVDICTVAL>
struct accelerator_templ_t
{
+ static constexpr hb_tag_t tableTag = cff2::tableTag;
+
accelerator_templ_t (hb_face_t *face)
{
if (!face) return;
diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
index fed6ca1c7a..89640b43f1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
@@ -179,6 +179,7 @@ struct hmtxvmtx
lm.advance = mtx.first;
lm.sb = mtx.second;
}
+ // TODO(beyond-64k): This assumes that maxp.numGlyphs is 0xFFFF.
else if (gid < 0x10000u)
short_metrics[gid] = mtx.second;
else
@@ -199,6 +200,8 @@ struct hmtxvmtx
/* Determine num_long_metrics to encode. */
auto& plan = c->plan;
+ // TODO Don't consider retaingid holes here.
+
num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
while (num_long_metrics > 1 &&
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index b3af128e02..0831e4499e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -1937,13 +1937,22 @@ struct ClassDefFormat2_4
{
/* Match if there's any glyph that is not listed! */
hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (auto &range : rangeRecord)
+ hb_codepoint_t last = HB_SET_VALUE_INVALID;
+ auto it = hb_iter (rangeRecord);
+ for (auto &range : it)
{
+ if (it->first == last + 1)
+ {
+ it++;
+ continue;
+ }
+
if (!glyphs->next (&g))
break;
if (g < range.first)
return true;
g = range.last;
+ last = g;
}
if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
return true;
@@ -2928,9 +2937,29 @@ struct ConditionFormat1
const hb_map_t *index_map = &c->plan->axes_index_map;
if (index_map->is_empty ()) return_trace (true);
- if (!index_map->has (axisIndex))
+ const hb_map_t& axes_old_index_tag_map = c->plan->axes_old_index_tag_map;
+ hb_codepoint_t *axis_tag;
+ if (!axes_old_index_tag_map.has (axisIndex, &axis_tag) ||
+ !index_map->has (axisIndex))
return_trace (false);
+ const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location = c->plan->axes_location;
+ Triple axis_limit{-1.f, 0.f, 1.f};
+ Triple *normalized_limit;
+ if (normalized_axes_location.has (*axis_tag, &normalized_limit))
+ axis_limit = *normalized_limit;
+
+ const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances = c->plan->axes_triple_distances;
+ TripleDistances axis_triple_distances{1.f, 1.f};
+ TripleDistances *triple_dists;
+ if (axes_triple_distances.has (*axis_tag, &triple_dists))
+ axis_triple_distances = *triple_dists;
+
+ float normalized_min = renormalizeValue (filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false);
+ float normalized_max = renormalizeValue (filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false);
+ out->filterRangeMinValue.set_float (normalized_min);
+ out->filterRangeMaxValue.set_float (normalized_max);
+
return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
@@ -2946,15 +2975,16 @@ struct ConditionFormat1
hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
Triple axis_range (-1.f, 0.f, 1.f);
- if (c->axes_location->has (axis_tag))
- axis_range = c->axes_location->get (axis_tag);
+ Triple *axis_limit;
+ if (c->axes_location->has (axis_tag, &axis_limit))
+ axis_range = *axis_limit;
- int axis_min_val = axis_range.minimum;
- int axis_default_val = axis_range.middle;
- int axis_max_val = axis_range.maximum;
+ float axis_min_val = axis_range.minimum;
+ float axis_default_val = axis_range.middle;
+ float axis_max_val = axis_range.maximum;
- int16_t filter_min_val = filterRangeMinValue.to_int ();
- int16_t filter_max_val = filterRangeMaxValue.to_int ();
+ float filter_min_val = filterRangeMinValue.to_float ();
+ float filter_max_val = filterRangeMaxValue.to_float ();
if (axis_default_val < filter_min_val ||
axis_default_val > filter_max_val)
@@ -2974,7 +3004,9 @@ struct ConditionFormat1
{
// add axisIndex->value into the hashmap so we can check if the record is
// unique with variations
- hb_codepoint_t val = (filter_max_val << 16) + filter_min_val;
+ int16_t int_filter_max_val = filterRangeMaxValue.to_int ();
+ int16_t int_filter_min_val = filterRangeMinValue.to_int ();
+ hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val;
condition_map->set (axisIndex, val);
return KEEP_COND_WITH_VAR;
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index e10adb78be..662ec9d3e8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -402,16 +402,6 @@ struct hb_ot_apply_context_t :
{
struct matcher_t
{
- matcher_t () :
- lookup_props (0),
- mask (-1),
- ignore_zwnj (false),
- ignore_zwj (false),
- per_syllable (false),
- syllable {0},
- match_func (nullptr),
- match_data (nullptr) {}
-
typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
@@ -470,14 +460,14 @@ struct hb_ot_apply_context_t :
}
protected:
- unsigned int lookup_props;
- hb_mask_t mask;
- bool ignore_zwnj;
- bool ignore_zwj;
- bool per_syllable;
- uint8_t syllable;
- match_func_t match_func;
- const void *match_data;
+ unsigned int lookup_props = 0;
+ hb_mask_t mask = -1;
+ bool ignore_zwnj = false;
+ bool ignore_zwj = false;
+ bool per_syllable = false;
+ uint8_t syllable = 0;
+ match_func_t match_func = nullptr;
+ const void *match_data = nullptr;
};
struct skipping_iterator_t
@@ -528,11 +518,9 @@ struct hb_ot_apply_context_t :
#ifndef HB_OPTIMIZE_SIZE
HB_ALWAYS_INLINE
#endif
- void reset (unsigned int start_index_,
- unsigned int num_items_)
+ void reset (unsigned int start_index_)
{
idx = start_index_;
- num_items = num_items_;
end = c->buffer->len;
matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
}
@@ -540,17 +528,14 @@ struct hb_ot_apply_context_t :
#ifndef HB_OPTIMIZE_SIZE
HB_ALWAYS_INLINE
#endif
- void reset_fast (unsigned int start_index_,
- unsigned int num_items_)
+ void reset_fast (unsigned int start_index_)
{
// Doesn't set end or syllable. Used by GPOS which doesn't care / change.
idx = start_index_;
- num_items = num_items_;
}
void reject ()
{
- num_items++;
backup_glyph_data ();
}
@@ -593,12 +578,7 @@ struct hb_ot_apply_context_t :
#endif
bool next (unsigned *unsafe_to = nullptr)
{
- assert (num_items > 0);
- /* The alternate condition below is faster at string boundaries,
- * but produces subpar "unsafe-to-concat" values. */
- signed stop = (signed) end - (signed) num_items;
- if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
- stop = (signed) end - 1;
+ const signed stop = (signed) end - 1;
while ((signed) idx < stop)
{
idx++;
@@ -606,7 +586,6 @@ struct hb_ot_apply_context_t :
{
case MATCH:
{
- num_items--;
advance_glyph_data ();
return true;
}
@@ -629,12 +608,7 @@ struct hb_ot_apply_context_t :
#endif
bool prev (unsigned *unsafe_from = nullptr)
{
- assert (num_items > 0);
- /* The alternate condition below is faster at string boundaries,
- * but produces subpar "unsafe-to-concat" values. */
- unsigned stop = num_items - 1;
- if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
- stop = 1 - 1;
+ const unsigned stop = 0;
while (idx > stop)
{
idx--;
@@ -642,7 +616,6 @@ struct hb_ot_apply_context_t :
{
case MATCH:
{
- num_items--;
advance_glyph_data ();
return true;
}
@@ -661,6 +634,7 @@ struct hb_ot_apply_context_t :
return false;
}
+ HB_ALWAYS_INLINE
hb_codepoint_t
get_glyph_data ()
{
@@ -671,6 +645,7 @@ struct hb_ot_apply_context_t :
#endif
return 0;
}
+ HB_ALWAYS_INLINE
void
advance_glyph_data ()
{
@@ -699,7 +674,6 @@ struct hb_ot_apply_context_t :
const HBUINT24 *match_glyph_data24;
#endif
- unsigned int num_items;
unsigned int end;
};
@@ -826,7 +800,7 @@ struct hb_ot_apply_context_t :
* match_props has the set index.
*/
if (match_props & LookupFlag::UseMarkFilteringSet)
- return gdef.mark_set_covers (match_props >> 16, glyph);
+ return gdef_accel.mark_set_covers (match_props >> 16, glyph);
/* The second byte of match_props has the meaning
* "ignore marks of attachment type different than
@@ -1198,6 +1172,10 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
}
+static inline bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED)
+{
+ return true;
+}
static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED)
{
return info.codepoint == value;
@@ -1218,6 +1196,28 @@ static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, co
info.syllable() = klass;
return klass == value;
}
+static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+ unsigned klass = info.syllable() & 0x0F;
+ if (klass < 15)
+ return klass == value;
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ klass = class_def.get_class (info.codepoint);
+ if (likely (klass < 15))
+ info.syllable() = (info.syllable() & 0xF0) | klass;
+ return klass == value;
+}
+static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+ unsigned klass = (info.syllable() & 0xF0) >> 4;
+ if (klass < 15)
+ return klass == value;
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ klass = class_def.get_class (info.codepoint);
+ if (likely (klass < 15))
+ info.syllable() = (info.syllable() & 0x0F) | (klass << 4);
+ return klass == value;
+}
static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data)
{
Offset16To<Coverage> coverage;
@@ -1265,7 +1265,7 @@ static bool match_input (hb_ot_apply_context_t *c,
hb_buffer_t *buffer = c->buffer;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, count - 1);
+ skippy_iter.reset (buffer->idx);
skippy_iter.set_match_func (match_func, match_data);
skippy_iter.set_glyph_data (input);
@@ -1505,7 +1505,7 @@ static bool match_backtrack (hb_ot_apply_context_t *c,
TRACE_APPLY (nullptr);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
- skippy_iter.reset (c->buffer->backtrack_len (), count);
+ skippy_iter.reset (c->buffer->backtrack_len ());
skippy_iter.set_match_func (match_func, match_data);
skippy_iter.set_glyph_data (backtrack);
@@ -1538,7 +1538,7 @@ static bool match_lookahead (hb_ot_apply_context_t *c,
TRACE_APPLY (nullptr);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
- skippy_iter.reset (start_index - 1, count);
+ skippy_iter.reset (start_index - 1);
skippy_iter.set_match_func (match_func, match_data);
skippy_iter.set_glyph_data (lookahead);
@@ -1913,12 +1913,13 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
}
template <typename HBUINT>
-static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- const ContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool context_apply_lookup (hb_ot_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const HBUINT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ const ContextApplyLookupContext &lookup_context)
{
unsigned match_end = 0;
unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
@@ -1944,6 +1945,9 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
template <typename Types>
struct Rule
{
+ template <typename T>
+ friend struct RuleSet;
+
bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
{
return context_intersects (glyphs,
@@ -2065,7 +2069,6 @@ struct Rule
* design order */
public:
DEFINE_SIZE_ARRAY (4, inputZ);
- DEFINE_SIZE_MAX (65536 * (Types::HBUINT::static_size + LookupRecord::static_size));
};
template <typename Types>
@@ -2131,13 +2134,105 @@ struct RuleSet
const ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
- return_trace (
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
- | hb_any
- )
- ;
+
+ unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+ if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+ {
+ slow:
+ return_trace (
+ + hb_iter (rule)
+ | hb_map (hb_add (this))
+ | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+ | hb_any
+ )
+ ;
+ }
+
+ /* This version is optimized for speed by matching the first & second
+ * components of the rule here, instead of calling into the matching code.
+ *
+ * Replicated from LigatureSet::apply(). */
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (c->buffer->idx);
+ skippy_iter.set_match_func (match_always, nullptr);
+ skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+ unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+ hb_glyph_info_t *first = nullptr, *second = nullptr;
+ bool matched = skippy_iter.next ();
+ if (likely (matched))
+ {
+ first = &c->buffer->info[skippy_iter.idx];
+ unsafe_to = skippy_iter.idx + 1;
+
+ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+ {
+ /* Can't use the fast path if eg. the next char is a default-ignorable
+ * or other skippable. */
+ goto slow;
+ }
+ }
+ else
+ {
+ /* Failed to match a next glyph. Only try applying rules that have
+ * no further input. */
+ return_trace (
+ + hb_iter (rule)
+ | hb_map (hb_add (this))
+ | hb_filter ([&] (const Rule &_) { return _.inputCount <= 1; })
+ | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+ | hb_any
+ )
+ ;
+ }
+ matched = skippy_iter.next ();
+ if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+ {
+ second = &c->buffer->info[skippy_iter.idx];
+ unsafe_to2 = skippy_iter.idx + 1;
+ }
+
+ auto match_input = lookup_context.funcs.match;
+ auto *input_data = lookup_context.match_data;
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ const auto &r = this+rule.arrayZ[i];
+
+ const auto &input = r.inputZ;
+
+ if (r.inputCount <= 1 ||
+ (!match_input ||
+ match_input (*first, input.arrayZ[0], input_data)))
+ {
+ if (!second ||
+ (r.inputCount <= 2 ||
+ (!match_input ||
+ match_input (*second, input.arrayZ[1], input_data)))
+ )
+ {
+ if (r.apply (c, lookup_context))
+ {
+ if (unsafe_to != (unsigned) -1)
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+ return_trace (true);
+ }
+ }
+ else
+ unsafe_to = unsafe_to2;
+ }
+ else
+ {
+ if (unsafe_to == (unsigned) -1)
+ unsafe_to = unsafe_to1;
+ }
+ }
+ if (likely (unsafe_to != (unsigned) -1))
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+ return_trace (false);
}
bool subset (hb_subset_context_t *c,
@@ -2516,11 +2611,7 @@ struct ContextFormat2_5
if (cached && c->buffer->cur().syllable() < 255)
index = c->buffer->cur().syllable ();
else
- {
index = class_def.get_class (c->buffer->cur().codepoint);
- if (cached && index < 255)
- c->buffer->cur().syllable() = index;
- }
const RuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -2914,16 +3005,17 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c
}
template <typename HBUINT>
-static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
- unsigned int backtrackCount,
- const HBUINT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- const ChainContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
+ unsigned int backtrackCount,
+ const HBUINT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const HBUINT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const HBUINT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ const ChainContextApplyLookupContext &lookup_context)
{
unsigned end_index = c->buffer->idx;
unsigned match_end = 0;
@@ -2962,6 +3054,9 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
template <typename Types>
struct ChainRule
{
+ template <typename T>
+ friend struct ChainRuleSet;
+
bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
{
const auto &input = StructAfter<decltype (inputX)> (backtrack);
@@ -3148,7 +3243,6 @@ struct ChainRule
* design order) */
public:
DEFINE_SIZE_MIN (8);
- DEFINE_SIZE_MAX (65536 * (3 * Types::HBUINT::static_size + LookupRecord::static_size));
};
template <typename Types>
@@ -3211,13 +3305,119 @@ struct ChainRuleSet
const ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
- return_trace (
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
- | hb_any
- )
- ;
+
+ unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+ if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+ {
+ slow:
+ return_trace (
+ + hb_iter (rule)
+ | hb_map (hb_add (this))
+ | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+ | hb_any
+ )
+ ;
+ }
+
+ /* This version is optimized for speed by matching the first & second
+ * components of the rule here, instead of calling into the matching code.
+ *
+ * Replicated from LigatureSet::apply(). */
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (c->buffer->idx);
+ skippy_iter.set_match_func (match_always, nullptr);
+ skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+ unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+ hb_glyph_info_t *first = nullptr, *second = nullptr;
+ bool matched = skippy_iter.next ();
+ if (likely (matched))
+ {
+ first = &c->buffer->info[skippy_iter.idx];
+ unsafe_to1 = skippy_iter.idx + 1;
+
+ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+ {
+ /* Can't use the fast path if eg. the next char is a default-ignorable
+ * or other skippable. */
+ goto slow;
+ }
+ }
+ else
+ {
+ /* Failed to match a next glyph. Only try applying rules that have
+ * no further input and lookahead. */
+ return_trace (
+ + hb_iter (rule)
+ | hb_map (hb_add (this))
+ | hb_filter ([&] (const ChainRule &_)
+ {
+ const auto &input = StructAfter<decltype (_.inputX)> (_.backtrack);
+ const auto &lookahead = StructAfter<decltype (_.lookaheadX)> (input);
+ return input.lenP1 <= 1 && lookahead.len == 0;
+ })
+ | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+ | hb_any
+ )
+ ;
+ }
+ matched = skippy_iter.next ();
+ if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+ {
+ second = &c->buffer->info[skippy_iter.idx];
+ unsafe_to2 = skippy_iter.idx + 1;
+ }
+
+ auto match_input = lookup_context.funcs.match[1];
+ auto match_lookahead = lookup_context.funcs.match[2];
+ auto *input_data = lookup_context.match_data[1];
+ auto *lookahead_data = lookup_context.match_data[2];
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ const auto &r = this+rule.arrayZ[i];
+
+ const auto &input = StructAfter<decltype (r.inputX)> (r.backtrack);
+ const auto &lookahead = StructAfter<decltype (r.lookaheadX)> (input);
+
+ unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u);
+ if (lenP1 > 1 ?
+ (!match_input ||
+ match_input (*first, input.arrayZ[0], input_data))
+ :
+ (!lookahead.len || !match_lookahead ||
+ match_lookahead (*first, lookahead.arrayZ[0], lookahead_data)))
+ {
+ if (!second ||
+ (lenP1 > 2 ?
+ (!match_input ||
+ match_input (*second, input.arrayZ[1], input_data))
+ :
+ (lookahead.len <= 2 - lenP1 || !match_lookahead ||
+ match_lookahead (*second, lookahead.arrayZ[2 - lenP1], lookahead_data))))
+ {
+ if (r.apply (c, lookup_context))
+ {
+ if (unsafe_to != (unsigned) -1)
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+ return_trace (true);
+ }
+ }
+ else
+ unsafe_to = unsafe_to2;
+ }
+ else
+ {
+ if (unsafe_to == (unsigned) -1)
+ unsafe_to = unsafe_to1;
+ }
+ }
+ if (likely (unsafe_to != (unsigned) -1))
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+ return_trace (false);
}
bool subset (hb_subset_context_t *c,
@@ -3616,26 +3816,22 @@ struct ChainContextFormat2_5
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
- /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef.
- * The reason is that most heavy fonts want to identify a glyph in context and apply
- * a lookup to it. In this scenario, the length of the input sequence is one, whereas
- * the lookahead / backtrack are typically longer. The one glyph in input sequence is
- * looked-up below and no input glyph is looked up in individual rules, whereas the
- * lookahead and backtrack glyphs are tried. Since we match lookahead before backtrack,
- * we should cache lookahead. This decisions showed a 20% improvement in shaping of
- * the Gulzar font.
- */
-
+ /* match_class_caches1 is slightly faster. Use it for lookahead,
+ * which is typically longer. */
struct ChainContextApplyLookupContext lookup_context = {
- {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached : match_class,
- cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
- cached ? match_class_cached : match_class}},
+ {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached1 : match_class,
+ cached ? match_class_cached2 : match_class,
+ cached ? match_class_cached1 : match_class}},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
};
- index = input_class_def.get_class (c->buffer->cur().codepoint);
+ // Note: Corresponds to match_class_cached2
+ if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15)
+ index = (c->buffer->cur().syllable () & 0xF0) >> 4;
+ else
+ index = input_class_def.get_class (c->buffer->cur().codepoint);
const ChainRuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -4139,6 +4335,9 @@ struct hb_ot_layout_lookup_accelerator_t
bool may_have (hb_codepoint_t g) const
{ return digest.may_have (g); }
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index 020b8a6c82..5ce36693a8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -1241,7 +1241,7 @@ script_collect_features (hb_collect_features_context_t *c,
* terminated by %HB_TAG_NONE
* @features: (nullable) (array zero-terminated=1): The array of features to collect,
* terminated by %HB_TAG_NONE
- * @feature_indexes: (out): The array of feature indexes found for the query
+ * @feature_indexes: (out): The set of feature indexes found for the query
*
* Fetches a list of all feature indexes in the specified face's GSUB table
* or GPOS table, underneath the specified scripts, languages, and features.
@@ -1282,6 +1282,44 @@ hb_ot_layout_collect_features (hb_face_t *face,
}
}
+/**
+ * hb_ot_layout_collect_features_map:
+ * @face: #hb_face_t to work upon
+ * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_map: (out): The map of feature tag to feature index.
+ *
+ * Fetches the mapping from feature tags to feature indexes for
+ * the specified script and language.
+ *
+ * Since: 8.1.0
+ **/
+void
+hb_ot_layout_collect_features_map (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned script_index,
+ unsigned language_index,
+ hb_map_t *feature_map /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+ unsigned int count = l.get_feature_indexes (0, nullptr, nullptr);
+ feature_map->alloc (count);
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ unsigned feature_index = 0;
+ unsigned feature_count = 1;
+ l.get_feature_indexes (i, &feature_count, &feature_index);
+ if (!feature_count)
+ break;
+ hb_tag_t feature_tag = g.get_feature_tag (feature_index);
+ feature_map->set (feature_tag, feature_index);
+ }
+}
+
/**
* hb_ot_layout_collect_lookups:
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.h b/thirdparty/harfbuzz/src/hb-ot-layout.h
index b0fae3707f..386b98d580 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.h
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.h
@@ -325,6 +325,13 @@ hb_ot_layout_collect_features (hb_face_t *face,
hb_set_t *feature_indexes /* OUT */);
HB_EXTERN void
+hb_ot_layout_collect_features_map (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned script_index,
+ unsigned language_index,
+ hb_map_t *feature_map /* OUT */);
+
+HB_EXTERN void
hb_ot_layout_collect_lookups (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *scripts,
diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc
index bacd56ef3f..fac73eb34e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-map.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-map.cc
@@ -239,6 +239,13 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
feature_infos.shrink (j + 1);
}
+ hb_map_t feature_indices[2];
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ hb_ot_layout_collect_features_map (face,
+ table_tags[table_index],
+ script_index[table_index],
+ language_index[table_index],
+ &feature_indices[table_index]);
/* Allocate bits now */
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
@@ -261,7 +268,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
if (!info->max_value || next_bit + bits_needed >= global_bit_shift)
continue; /* Feature disabled, or not enough bits. */
-
bool found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
@@ -269,12 +275,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
if (required_feature_tag[table_index] == info->tag)
required_feature_stage[table_index] = info->stage[table_index];
- found |= (bool) hb_ot_layout_language_find_feature (face,
- table_tags[table_index],
- script_index[table_index],
- language_index[table_index],
- info->tag,
- &feature_index[table_index]);
+ hb_codepoint_t *index;
+ if (feature_indices[table_index].has (info->tag, &index))
+ {
+ feature_index[table_index] = *index;
+ found = true;
+ }
+ else
+ feature_index[table_index] = HB_OT_LAYOUT_NO_FEATURE_INDEX;
}
if (!found && (info->flags & F_GLOBAL_SEARCH))
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc
index d84313f190..9c1c2a950e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc
@@ -476,9 +476,18 @@ hb_set_unicode_props (hb_buffer_t *buffer)
{
_hb_glyph_info_set_unicode_props (&info[i], buffer);
+ unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]);
+ if (FLAG_UNSAFE (gen_cat) &
+ (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR)))
+ continue;
+
/* Marks are already set as continuation by the above line.
* Handle Emoji_Modifier and ZWJ-continuation. */
- if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
+ if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu)))
{
_hb_glyph_info_set_continuation (&info[i]);
@@ -756,6 +765,14 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
_hb_glyph_info_get_general_category (&info[end]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
end++;
+ if (start == i || end == i + 1)
+ {
+ if (start == i)
+ buffer->unsafe_to_concat (start, start + 1);
+ if (end == i + 1)
+ buffer->unsafe_to_concat (end - 1, end);
+ continue;
+ }
buffer->unsafe_to_break (start, end);
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh
index 7249c33356..80a9b09d8e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh
@@ -1,32 +1,31 @@
-
#line 1 "hb-ot-shaper-use-machine.rl"
/*
- * Copyright © 2015 Mozilla Foundation.
- * Copyright © 2015 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Mozilla Author(s): Jonathan Kew
- * Google Author(s): Behdad Esfahbod
- */
+* Copyright © 2015 Mozilla Foundation.
+* Copyright © 2015 Google, Inc.
+*
+* This is part of HarfBuzz, a text shaping library.
+*
+* Permission is hereby granted, without written agreement and without
+* license or royalty fees, to use, copy, modify, and distribute this
+* software and its documentation for any purpose, provided that the
+* above copyright notice and the following two paragraphs appear in
+* all copies of this software.
+*
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*
+* Mozilla Author(s): Jonathan Kew
+* Google Author(s): Behdad Esfahbod
+*/
#ifndef HB_OT_SHAPER_USE_MACHINE_HH
#define HB_OT_SHAPER_USE_MACHINE_HH
@@ -41,15 +40,15 @@
#define USE(Cat) use_syllable_machine_ex_##Cat
enum use_syllable_type_t {
- use_virama_terminated_cluster,
- use_sakot_terminated_cluster,
- use_standard_cluster,
- use_number_joiner_terminated_cluster,
- use_numeral_cluster,
- use_symbol_cluster,
- use_hieroglyph_cluster,
- use_broken_cluster,
- use_non_cluster,
+ use_virama_terminated_cluster,
+ use_sakot_terminated_cluster,
+ use_standard_cluster,
+ use_number_joiner_terminated_cluster,
+ use_numeral_cluster,
+ use_symbol_cluster,
+ use_hieroglyph_cluster,
+ use_broken_cluster,
+ use_non_cluster,
};
@@ -99,724 +98,592 @@ enum use_syllable_type_t {
#line 96 "hb-ot-shaper-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
- 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
- 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
- 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
- 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 11u, 53u, 14u, 42u, 14u, 42u, 11u, 53u,
- 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u,
- 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u,
- 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u,
- 1u, 14u, 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u,
- 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u,
- 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u,
- 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u,
- 1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
- 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
- 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
- 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 11u, 53u,
- 14u, 42u, 14u, 42u, 1u, 5u, 14u, 52u, 14u, 52u, 14u, 51u, 0
+ 0u, 39u, 5u, 39u, 5u, 39u, 1u, 39u,
+ 8u, 34u, 8u, 33u, 8u, 33u, 8u, 33u,
+ 8u, 32u, 8u, 32u, 8u, 8u, 8u, 34u,
+ 8u, 34u, 8u, 34u, 1u, 8u, 8u, 34u,
+ 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+ 6u, 39u, 8u, 39u, 6u, 39u, 6u, 39u,
+ 6u, 39u, 5u, 39u, 1u, 8u, 1u, 34u,
+ 8u, 28u, 8u, 28u, 5u, 39u, 1u, 39u,
+ 8u, 34u, 8u, 33u, 8u, 33u, 8u, 33u,
+ 8u, 32u, 8u, 32u, 8u, 8u, 8u, 34u,
+ 8u, 34u, 8u, 34u, 1u, 8u, 8u, 34u,
+ 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+ 6u, 39u, 8u, 39u, 6u, 39u, 6u, 39u,
+ 6u, 39u, 5u, 39u, 1u, 8u, 1u, 8u,
+ 1u, 34u, 7u, 8u, 3u, 8u, 5u, 39u,
+ 5u, 39u, 1u, 39u, 8u, 34u, 8u, 33u,
+ 8u, 33u, 8u, 33u, 8u, 32u, 8u, 32u,
+ 8u, 8u, 8u, 34u, 8u, 34u, 8u, 34u,
+ 1u, 8u, 8u, 34u, 8u, 39u, 8u, 39u,
+ 8u, 39u, 8u, 39u, 6u, 39u, 8u, 39u,
+ 6u, 39u, 6u, 39u, 6u, 39u, 5u, 39u,
+ 1u, 8u, 1u, 8u, 1u, 34u, 5u, 39u,
+ 1u, 39u, 8u, 34u, 8u, 33u, 8u, 33u,
+ 8u, 33u, 8u, 32u, 8u, 32u, 8u, 8u,
+ 8u, 34u, 8u, 34u, 8u, 34u, 1u, 8u,
+ 8u, 34u, 8u, 39u, 8u, 39u, 8u, 39u,
+ 8u, 39u, 6u, 39u, 8u, 39u, 6u, 39u,
+ 6u, 39u, 6u, 39u, 5u, 39u, 1u, 8u,
+ 1u, 34u, 3u, 8u, 7u, 8u, 1u, 39u,
+ 8u, 28u, 8u, 28u, 1u, 4u, 8u, 38u,
+ 8u, 38u, 8u, 37u, 0u
};
-static const char _use_syllable_machine_key_spans[] = {
- 54, 43, 43, 53, 35, 34, 34, 34,
- 33, 33, 1, 35, 35, 35, 14, 35,
- 40, 40, 40, 40, 42, 40, 42, 42,
- 42, 43, 14, 48, 43, 29, 29, 43,
- 43, 53, 35, 34, 34, 34, 33, 33,
- 1, 35, 35, 35, 14, 35, 40, 40,
- 40, 40, 42, 40, 42, 42, 42, 43,
- 14, 14, 48, 2, 11, 43, 43, 53,
- 35, 34, 34, 34, 33, 33, 1, 35,
- 35, 35, 14, 35, 40, 40, 40, 40,
- 42, 40, 42, 42, 42, 43, 14, 14,
- 48, 43, 43, 53, 35, 34, 34, 34,
- 33, 33, 1, 35, 35, 35, 14, 35,
- 40, 40, 40, 40, 42, 40, 42, 42,
- 42, 43, 14, 48, 11, 2, 53, 43,
- 29, 29, 5, 39, 39, 38
+static const signed char _use_syllable_machine_char_class[] = {
+ 0, 1, 2, 2, 3, 4, 2, 2,
+ 2, 2, 2, 5, 6, 7, 8, 2,
+ 2, 2, 9, 2, 2, 2, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 2, 24, 25, 26,
+ 2, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 0
};
static const short _use_syllable_machine_index_offsets[] = {
- 0, 55, 99, 143, 197, 233, 268, 303,
- 338, 372, 406, 408, 444, 480, 516, 531,
- 567, 608, 649, 690, 731, 774, 815, 858,
- 901, 944, 988, 1003, 1052, 1096, 1126, 1156,
- 1200, 1244, 1298, 1334, 1369, 1404, 1439, 1473,
- 1507, 1509, 1545, 1581, 1617, 1632, 1668, 1709,
- 1750, 1791, 1832, 1875, 1916, 1959, 2002, 2045,
- 2089, 2104, 2119, 2168, 2171, 2183, 2227, 2271,
- 2325, 2361, 2396, 2431, 2466, 2500, 2534, 2536,
- 2572, 2608, 2644, 2659, 2695, 2736, 2777, 2818,
- 2859, 2902, 2943, 2986, 3029, 3072, 3116, 3131,
- 3146, 3195, 3239, 3283, 3337, 3373, 3408, 3443,
- 3478, 3512, 3546, 3548, 3584, 3620, 3656, 3671,
- 3707, 3748, 3789, 3830, 3871, 3914, 3955, 3998,
- 4041, 4084, 4128, 4143, 4192, 4204, 4207, 4261,
- 4305, 4335, 4365, 4371, 4411, 4451
+ 0, 40, 75, 110, 149, 176, 202, 228,
+ 254, 279, 304, 305, 332, 359, 386, 394,
+ 421, 453, 485, 517, 549, 583, 615, 649,
+ 683, 717, 752, 760, 794, 815, 836, 871,
+ 910, 937, 963, 989, 1015, 1040, 1065, 1066,
+ 1093, 1120, 1147, 1155, 1182, 1214, 1246, 1278,
+ 1310, 1344, 1376, 1410, 1444, 1478, 1513, 1521,
+ 1529, 1563, 1565, 1571, 1606, 1641, 1680, 1707,
+ 1733, 1759, 1785, 1810, 1835, 1836, 1863, 1890,
+ 1917, 1925, 1952, 1984, 2016, 2048, 2080, 2114,
+ 2146, 2180, 2214, 2248, 2283, 2291, 2299, 2333,
+ 2368, 2407, 2434, 2460, 2486, 2512, 2537, 2562,
+ 2563, 2590, 2617, 2644, 2652, 2679, 2711, 2743,
+ 2775, 2807, 2841, 2873, 2907, 2941, 2975, 3010,
+ 3018, 3052, 3058, 3060, 3099, 3120, 3141, 3145,
+ 3176, 3207, 0
+};
+
+static const short _use_syllable_machine_indicies[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 6, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 30, 34, 3, 35, 3, 36,
+ 38, 39, 37, 40, 37, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 38, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58,
+ 37, 59, 60, 61, 62, 59, 37, 37,
+ 37, 37, 63, 38, 39, 37, 40, 37,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 38, 50, 51, 52, 53, 54, 55,
+ 56, 37, 37, 37, 59, 60, 61, 62,
+ 59, 37, 37, 37, 37, 63, 38, 37,
+ 37, 37, 37, 37, 37, 40, 37, 37,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 40, 37, 37,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 40, 37, 37, 37, 43, 44, 45, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 60,
+ 61, 62, 40, 37, 37, 37, 37, 44,
+ 45, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 60, 61, 62, 40, 37, 37, 37,
+ 37, 37, 45, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 60, 61, 62, 40, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 60, 61, 40,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 61,
+ 40, 40, 37, 37, 37, 43, 44, 45,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 54, 55, 56, 37, 37, 37, 37,
+ 60, 61, 62, 64, 40, 37, 37, 37,
+ 43, 44, 45, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 55, 56, 37,
+ 37, 37, 37, 60, 61, 62, 64, 40,
+ 37, 37, 37, 43, 44, 45, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 56, 37, 37, 37, 37, 60, 61,
+ 62, 64, 65, 37, 37, 37, 37, 37,
+ 37, 40, 40, 37, 37, 37, 43, 44,
+ 45, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 60, 61, 62, 64, 40, 37, 41,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 51, 52, 53, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 40, 37, 37,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 51, 52, 53, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 40, 37, 37,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 37, 52, 53, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 40, 37, 37,
+ 42, 43, 44, 45, 37, 37, 37, 37,
+ 37, 37, 37, 37, 53, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 66, 37, 40,
+ 37, 41, 42, 43, 44, 45, 37, 47,
+ 48, 37, 37, 37, 51, 52, 53, 54,
+ 55, 56, 37, 37, 37, 37, 60, 61,
+ 62, 64, 37, 37, 37, 37, 42, 40,
+ 37, 37, 42, 43, 44, 45, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 54,
+ 55, 56, 37, 37, 37, 37, 60, 61,
+ 62, 64, 37, 37, 37, 37, 42, 66,
+ 37, 40, 37, 41, 42, 43, 44, 45,
+ 37, 37, 48, 37, 37, 37, 51, 52,
+ 53, 54, 55, 56, 37, 37, 37, 37,
+ 60, 61, 62, 64, 37, 37, 37, 37,
+ 42, 66, 37, 40, 37, 41, 42, 43,
+ 44, 45, 37, 37, 37, 37, 37, 37,
+ 51, 52, 53, 54, 55, 56, 37, 37,
+ 37, 37, 60, 61, 62, 64, 37, 37,
+ 37, 37, 42, 66, 37, 40, 37, 41,
+ 42, 43, 44, 45, 46, 47, 48, 37,
+ 37, 37, 51, 52, 53, 54, 55, 56,
+ 37, 37, 37, 37, 60, 61, 62, 64,
+ 37, 37, 37, 37, 42, 38, 39, 37,
+ 40, 37, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 37, 50, 51, 52, 53,
+ 54, 55, 56, 37, 37, 37, 59, 60,
+ 61, 62, 59, 37, 37, 37, 37, 63,
+ 38, 37, 37, 37, 37, 37, 37, 40,
+ 38, 37, 37, 37, 37, 37, 37, 40,
+ 37, 37, 42, 43, 44, 45, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 54,
+ 55, 56, 37, 37, 37, 37, 60, 61,
+ 62, 64, 40, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 57, 58, 40,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 58, 2, 68, 67, 69,
+ 67, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 2, 79, 80, 81, 82, 83,
+ 84, 85, 67, 67, 67, 86, 87, 88,
+ 89, 90, 67, 67, 67, 67, 91, 2,
+ 67, 67, 67, 67, 67, 67, 69, 67,
+ 67, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 69, 67,
+ 67, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 69, 67, 67, 67, 72, 73, 74,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 87, 88, 89, 69, 67, 67, 67, 67,
+ 73, 74, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 87, 88, 89, 69, 67, 67,
+ 67, 67, 67, 74, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 87, 88, 89, 69,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 87, 88,
+ 69, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 88, 69, 69, 67, 67, 67, 72, 73,
+ 74, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 83, 84, 85, 67, 67, 67,
+ 67, 87, 88, 89, 92, 69, 67, 67,
+ 67, 72, 73, 74, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 84, 85,
+ 67, 67, 67, 67, 87, 88, 89, 92,
+ 69, 67, 67, 67, 72, 73, 74, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 85, 67, 67, 67, 67, 87,
+ 88, 89, 92, 94, 93, 93, 93, 93,
+ 93, 93, 95, 69, 67, 67, 67, 72,
+ 73, 74, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 87, 88, 89, 92, 69, 67,
+ 70, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 80, 81, 82, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 69, 67,
+ 67, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 80, 81, 82, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 69, 67,
+ 67, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 67, 81, 82, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 69, 67,
+ 67, 71, 72, 73, 74, 67, 67, 67,
+ 67, 67, 67, 67, 67, 82, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 96, 67,
+ 69, 67, 70, 71, 72, 73, 74, 67,
+ 76, 77, 67, 67, 67, 80, 81, 82,
+ 83, 84, 85, 67, 67, 67, 67, 87,
+ 88, 89, 92, 67, 67, 67, 67, 71,
+ 69, 67, 67, 71, 72, 73, 74, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 83, 84, 85, 67, 67, 67, 67, 87,
+ 88, 89, 92, 67, 67, 67, 67, 71,
+ 96, 67, 69, 67, 70, 71, 72, 73,
+ 74, 67, 67, 77, 67, 67, 67, 80,
+ 81, 82, 83, 84, 85, 67, 67, 67,
+ 67, 87, 88, 89, 92, 67, 67, 67,
+ 67, 71, 96, 67, 69, 67, 70, 71,
+ 72, 73, 74, 67, 67, 67, 67, 67,
+ 67, 80, 81, 82, 83, 84, 85, 67,
+ 67, 67, 67, 87, 88, 89, 92, 67,
+ 67, 67, 67, 71, 96, 67, 69, 67,
+ 70, 71, 72, 73, 74, 75, 76, 77,
+ 67, 67, 67, 80, 81, 82, 83, 84,
+ 85, 67, 67, 67, 67, 87, 88, 89,
+ 92, 67, 67, 67, 67, 71, 2, 68,
+ 67, 69, 67, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 67, 79, 80, 81,
+ 82, 83, 84, 85, 67, 67, 67, 86,
+ 87, 88, 89, 90, 67, 67, 67, 67,
+ 91, 2, 97, 97, 97, 97, 97, 97,
+ 98, 2, 93, 93, 93, 93, 93, 93,
+ 95, 2, 67, 67, 67, 67, 67, 67,
+ 69, 67, 67, 71, 72, 73, 74, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 83, 84, 85, 67, 67, 67, 67, 87,
+ 88, 89, 92, 100, 101, 4, 102, 102,
+ 102, 102, 103, 104, 105, 67, 69, 67,
+ 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 104, 115, 116, 117, 118, 119, 120,
+ 121, 57, 58, 67, 122, 123, 124, 125,
+ 126, 67, 67, 67, 67, 127, 104, 105,
+ 67, 69, 67, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 104, 115, 116, 117,
+ 118, 119, 120, 121, 67, 67, 67, 122,
+ 123, 124, 125, 126, 67, 67, 67, 67,
+ 127, 104, 67, 67, 67, 67, 67, 67,
+ 69, 67, 67, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 69, 67, 67, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 69, 67, 67, 67, 108,
+ 109, 110, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 123, 124, 125, 69, 67, 67,
+ 67, 67, 109, 110, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 123, 124, 125, 69,
+ 67, 67, 67, 67, 67, 110, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 123, 124,
+ 125, 69, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 123, 124, 69, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 124, 69, 69, 67, 67, 67,
+ 108, 109, 110, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 119, 120, 121, 67,
+ 67, 67, 67, 123, 124, 125, 128, 69,
+ 67, 67, 67, 108, 109, 110, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 120, 121, 67, 67, 67, 67, 123, 124,
+ 125, 128, 69, 67, 67, 67, 108, 109,
+ 110, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 121, 67, 67, 67,
+ 67, 123, 124, 125, 128, 129, 93, 93,
+ 93, 93, 93, 93, 95, 69, 67, 67,
+ 67, 108, 109, 110, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 123, 124, 125, 128,
+ 69, 67, 106, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 116, 117, 118,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 69, 67, 67, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 116, 117, 118,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 69, 67, 67, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 67, 117, 118,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 69, 67, 67, 107, 108, 109, 110, 67,
+ 67, 67, 67, 67, 67, 67, 67, 118,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 130, 67, 69, 67, 106, 107, 108, 109,
+ 110, 67, 112, 113, 67, 67, 67, 116,
+ 117, 118, 119, 120, 121, 67, 67, 67,
+ 67, 123, 124, 125, 128, 67, 67, 67,
+ 67, 107, 69, 67, 67, 107, 108, 109,
+ 110, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 119, 120, 121, 67, 67, 67,
+ 67, 123, 124, 125, 128, 67, 67, 67,
+ 67, 107, 130, 67, 69, 67, 106, 107,
+ 108, 109, 110, 67, 67, 113, 67, 67,
+ 67, 116, 117, 118, 119, 120, 121, 67,
+ 67, 67, 67, 123, 124, 125, 128, 67,
+ 67, 67, 67, 107, 130, 67, 69, 67,
+ 106, 107, 108, 109, 110, 67, 67, 67,
+ 67, 67, 67, 116, 117, 118, 119, 120,
+ 121, 67, 67, 67, 67, 123, 124, 125,
+ 128, 67, 67, 67, 67, 107, 130, 67,
+ 69, 67, 106, 107, 108, 109, 110, 111,
+ 112, 113, 67, 67, 67, 116, 117, 118,
+ 119, 120, 121, 67, 67, 67, 67, 123,
+ 124, 125, 128, 67, 67, 67, 67, 107,
+ 104, 105, 67, 69, 67, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 67, 115,
+ 116, 117, 118, 119, 120, 121, 67, 67,
+ 67, 122, 123, 124, 125, 126, 67, 67,
+ 67, 67, 127, 104, 97, 97, 97, 97,
+ 97, 97, 98, 104, 93, 93, 93, 93,
+ 93, 93, 95, 104, 67, 67, 67, 67,
+ 67, 67, 69, 67, 67, 107, 108, 109,
+ 110, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 119, 120, 121, 67, 67, 67,
+ 67, 123, 124, 125, 128, 6, 7, 131,
+ 9, 131, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 6, 20, 21, 22, 23,
+ 24, 25, 26, 131, 131, 131, 30, 31,
+ 32, 33, 30, 131, 131, 131, 131, 36,
+ 6, 131, 131, 131, 131, 131, 131, 9,
+ 131, 131, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 9,
+ 131, 131, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 9, 131, 131, 131, 13, 14,
+ 15, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 31, 32, 33, 9, 131, 131, 131,
+ 131, 14, 15, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 31, 32, 33, 9, 131,
+ 131, 131, 131, 131, 15, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 31, 32, 33,
+ 9, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 31,
+ 32, 9, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 32, 9, 9, 131, 131, 131, 13,
+ 14, 15, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 24, 25, 26, 131, 131,
+ 131, 131, 31, 32, 33, 132, 9, 131,
+ 131, 131, 13, 14, 15, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 25,
+ 26, 131, 131, 131, 131, 31, 32, 33,
+ 132, 9, 131, 131, 131, 13, 14, 15,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 26, 131, 131, 131, 131,
+ 31, 32, 33, 132, 133, 131, 131, 131,
+ 131, 131, 131, 9, 9, 131, 131, 131,
+ 13, 14, 15, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 31, 32, 33, 132, 9,
+ 131, 11, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 21, 22, 23, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 9,
+ 131, 131, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 21, 22, 23, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 9,
+ 131, 131, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 131, 22, 23, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 9,
+ 131, 131, 12, 13, 14, 15, 131, 131,
+ 131, 131, 131, 131, 131, 131, 23, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 134,
+ 131, 9, 131, 11, 12, 13, 14, 15,
+ 131, 17, 18, 131, 131, 131, 21, 22,
+ 23, 24, 25, 26, 131, 131, 131, 131,
+ 31, 32, 33, 132, 131, 131, 131, 131,
+ 12, 9, 131, 131, 12, 13, 14, 15,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 24, 25, 26, 131, 131, 131, 131,
+ 31, 32, 33, 132, 131, 131, 131, 131,
+ 12, 134, 131, 9, 131, 11, 12, 13,
+ 14, 15, 131, 131, 18, 131, 131, 131,
+ 21, 22, 23, 24, 25, 26, 131, 131,
+ 131, 131, 31, 32, 33, 132, 131, 131,
+ 131, 131, 12, 134, 131, 9, 131, 11,
+ 12, 13, 14, 15, 131, 131, 131, 131,
+ 131, 131, 21, 22, 23, 24, 25, 26,
+ 131, 131, 131, 131, 31, 32, 33, 132,
+ 131, 131, 131, 131, 12, 134, 131, 9,
+ 131, 11, 12, 13, 14, 15, 16, 17,
+ 18, 131, 131, 131, 21, 22, 23, 24,
+ 25, 26, 131, 131, 131, 131, 31, 32,
+ 33, 132, 131, 131, 131, 131, 12, 6,
+ 7, 131, 9, 131, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 131, 20, 21,
+ 22, 23, 24, 25, 26, 131, 131, 131,
+ 30, 31, 32, 33, 30, 131, 131, 131,
+ 131, 36, 6, 131, 131, 131, 131, 131,
+ 131, 9, 6, 131, 131, 131, 131, 131,
+ 131, 9, 131, 131, 12, 13, 14, 15,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 24, 25, 26, 131, 131, 131, 131,
+ 31, 32, 33, 132, 135, 131, 131, 131,
+ 131, 9, 8, 9, 2, 131, 131, 2,
+ 6, 7, 8, 9, 131, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 6, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28,
+ 131, 30, 31, 32, 33, 30, 131, 131,
+ 131, 131, 36, 9, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 27, 28,
+ 9, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 28, 2, 136, 136,
+ 2, 138, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 139, 137, 34,
+ 138, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 34, 139, 137, 139, 138,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 34, 137, 35, 0
};
-static const unsigned char _use_syllable_machine_indicies[] = {
- 0, 1, 2, 2, 3, 4, 2, 2,
- 2, 2, 2, 5, 6, 7, 8, 2,
- 2, 2, 9, 2, 2, 2, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 2, 24, 25, 26,
- 2, 27, 28, 29, 30, 31, 32, 33,
- 30, 34, 2, 35, 2, 36, 2, 38,
- 39, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54,
- 37, 55, 56, 57, 37, 58, 59, 37,
- 60, 61, 62, 63, 60, 37, 37, 37,
- 37, 64, 37, 38, 39, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 51,
- 51, 52, 53, 54, 37, 55, 56, 57,
- 37, 37, 37, 37, 60, 61, 62, 63,
- 60, 37, 37, 37, 37, 64, 37, 38,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 42, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 55, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 37, 37, 37, 42, 37, 40, 37, 37,
- 37, 37, 37, 37, 37, 37, 42, 43,
- 44, 45, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 55, 56, 57, 37,
- 37, 37, 37, 37, 61, 62, 63, 65,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 43, 44, 45, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 61, 62, 63, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 61, 62, 63, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 45, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 61, 62,
- 63, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 61, 62, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 62, 37, 40, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 66, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 40, 37, 40, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 43, 44, 45,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 61, 62, 63, 65, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 37, 37, 37, 37,
- 37, 37, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 37, 61, 62,
- 63, 65, 37, 37, 37, 37, 42, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 42, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 52, 53, 54, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 37, 37, 37, 42,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 37, 42, 43, 44, 45, 37, 37,
- 37, 37, 37, 37, 37, 53, 54, 37,
- 55, 56, 57, 37, 37, 37, 37, 37,
- 61, 62, 63, 65, 37, 37, 37, 37,
- 42, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 37, 42, 43, 44, 45, 37,
- 37, 37, 37, 37, 37, 37, 37, 54,
- 37, 55, 56, 57, 37, 37, 37, 37,
- 37, 61, 62, 63, 65, 37, 37, 37,
- 37, 42, 37, 67, 37, 40, 37, 37,
- 37, 37, 37, 37, 37, 41, 42, 43,
- 44, 45, 37, 47, 48, 37, 37, 37,
- 52, 53, 54, 37, 55, 56, 57, 37,
- 37, 37, 37, 37, 61, 62, 63, 65,
- 37, 37, 37, 37, 42, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 37, 42,
- 43, 44, 45, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 55, 56, 57,
- 37, 37, 37, 37, 37, 61, 62, 63,
- 65, 37, 37, 37, 37, 42, 37, 67,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 41, 42, 43, 44, 45, 37, 37,
- 48, 37, 37, 37, 52, 53, 54, 37,
- 55, 56, 57, 37, 37, 37, 37, 37,
- 61, 62, 63, 65, 37, 37, 37, 37,
- 42, 37, 67, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 41, 42, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 52,
- 53, 54, 37, 55, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 37, 37, 37, 42, 37, 67, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 46, 47, 48, 37,
- 37, 37, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 37, 61, 62,
- 63, 65, 37, 37, 37, 37, 42, 37,
- 38, 39, 37, 40, 37, 37, 37, 37,
- 37, 37, 37, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 37, 51, 52, 53,
- 54, 37, 55, 56, 57, 37, 37, 37,
- 37, 60, 61, 62, 63, 60, 37, 37,
- 37, 37, 64, 37, 38, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 40, 37, 38, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 42, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 38, 39, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 60, 61, 62,
- 63, 60, 37, 37, 37, 37, 64, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 58, 59, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 59, 37, 69, 70, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 1, 81, 82, 83, 84, 68, 85, 86,
- 87, 68, 68, 68, 68, 88, 89, 90,
- 91, 92, 68, 68, 68, 68, 93, 68,
- 69, 70, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 81, 82, 83,
- 84, 68, 85, 86, 87, 68, 68, 68,
- 68, 88, 89, 90, 91, 92, 68, 68,
- 68, 68, 93, 68, 69, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 73, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 85, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 68, 68, 68,
- 73, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 73, 74, 75, 76, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 85, 86, 87, 68, 68, 68, 68,
- 68, 89, 90, 91, 94, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 74, 75, 76, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 89, 90, 91, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 76, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 89, 90, 91, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 89, 90,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 90, 68, 71, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 85, 86, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 96, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 97, 95,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 74, 75, 76, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 89,
- 90, 91, 94, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 72, 73, 74, 75,
- 76, 68, 68, 68, 68, 68, 68, 82,
- 83, 84, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 68, 68, 68, 73, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 73, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 82, 83, 84, 68, 85, 86, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 68, 68, 68, 73, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 73,
- 74, 75, 76, 68, 68, 68, 68, 68,
- 68, 68, 83, 84, 68, 85, 86, 87,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 94, 68, 68, 68, 68, 73, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 73, 74, 75, 76, 68, 68, 68, 68,
- 68, 68, 68, 68, 84, 68, 85, 86,
- 87, 68, 68, 68, 68, 68, 89, 90,
- 91, 94, 68, 68, 68, 68, 73, 68,
- 98, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 72, 73, 74, 75, 76, 68,
- 78, 79, 68, 68, 68, 82, 83, 84,
- 68, 85, 86, 87, 68, 68, 68, 68,
- 68, 89, 90, 91, 94, 68, 68, 68,
- 68, 73, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 68, 73, 74, 75, 76,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 85, 86, 87, 68, 68, 68,
- 68, 68, 89, 90, 91, 94, 68, 68,
- 68, 68, 73, 68, 98, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 72, 73,
- 74, 75, 76, 68, 68, 79, 68, 68,
- 68, 82, 83, 84, 68, 85, 86, 87,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 94, 68, 68, 68, 68, 73, 68, 98,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 72, 73, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 82, 83, 84, 68,
- 85, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 68, 68, 68,
- 73, 68, 98, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 72, 73, 74, 75,
- 76, 77, 78, 79, 68, 68, 68, 82,
- 83, 84, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 68, 68, 68, 73, 68, 69, 70, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 68, 81, 82, 83, 84, 68, 85,
- 86, 87, 68, 68, 68, 68, 88, 89,
- 90, 91, 92, 68, 68, 68, 68, 93,
- 68, 69, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 100, 99,
- 69, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 97, 95, 69,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 73, 74, 75,
- 76, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 102, 103, 101, 3, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 105, 104, 106,
- 107, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 108, 109, 110, 111, 112, 113,
- 114, 115, 116, 117, 118, 119, 120, 121,
- 68, 122, 123, 124, 68, 58, 59, 68,
- 125, 126, 127, 128, 129, 68, 68, 68,
- 68, 130, 68, 106, 107, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 118,
- 118, 119, 120, 121, 68, 122, 123, 124,
- 68, 68, 68, 68, 125, 126, 127, 128,
- 129, 68, 68, 68, 68, 130, 68, 106,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 109, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 122, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 68, 68, 68, 109, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 109, 110,
- 111, 112, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 122, 123, 124, 68,
- 68, 68, 68, 68, 126, 127, 128, 131,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 110, 111, 112, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 126, 127, 128, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 126, 127, 128, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 112, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 126, 127,
- 128, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 126, 127, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 127, 68, 71, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 122,
- 123, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 132, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 97, 95, 71, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 110, 111, 112,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 126, 127, 128, 131, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 108,
- 109, 110, 111, 112, 68, 68, 68, 68,
- 68, 68, 119, 120, 121, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 68, 68, 68, 109, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 109, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 119, 120, 121, 68, 122,
- 123, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 68, 68, 68, 109,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 109, 110, 111, 112, 68, 68,
- 68, 68, 68, 68, 68, 120, 121, 68,
- 122, 123, 124, 68, 68, 68, 68, 68,
- 126, 127, 128, 131, 68, 68, 68, 68,
- 109, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 109, 110, 111, 112, 68,
- 68, 68, 68, 68, 68, 68, 68, 121,
- 68, 122, 123, 124, 68, 68, 68, 68,
- 68, 126, 127, 128, 131, 68, 68, 68,
- 68, 109, 68, 133, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 108, 109, 110,
- 111, 112, 68, 114, 115, 68, 68, 68,
- 119, 120, 121, 68, 122, 123, 124, 68,
- 68, 68, 68, 68, 126, 127, 128, 131,
- 68, 68, 68, 68, 109, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 109,
- 110, 111, 112, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 122, 123, 124,
- 68, 68, 68, 68, 68, 126, 127, 128,
- 131, 68, 68, 68, 68, 109, 68, 133,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 108, 109, 110, 111, 112, 68, 68,
- 115, 68, 68, 68, 119, 120, 121, 68,
- 122, 123, 124, 68, 68, 68, 68, 68,
- 126, 127, 128, 131, 68, 68, 68, 68,
- 109, 68, 133, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 108, 109, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 119,
- 120, 121, 68, 122, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 68, 68, 68, 109, 68, 133, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 108,
- 109, 110, 111, 112, 113, 114, 115, 68,
- 68, 68, 119, 120, 121, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 68, 68, 68, 109, 68,
- 106, 107, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 68, 118, 119, 120,
- 121, 68, 122, 123, 124, 68, 68, 68,
- 68, 125, 126, 127, 128, 129, 68, 68,
- 68, 68, 130, 68, 106, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 100, 99, 106, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 97, 95, 106, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 109, 110, 111, 112, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 106, 107, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117,
- 118, 119, 120, 121, 68, 122, 123, 124,
- 68, 68, 68, 68, 125, 126, 127, 128,
- 129, 68, 68, 68, 68, 130, 68, 5,
- 6, 134, 8, 134, 134, 134, 134, 134,
- 134, 134, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 20, 20, 21, 22, 23,
- 134, 24, 25, 26, 134, 134, 134, 134,
- 30, 31, 32, 33, 30, 134, 134, 134,
- 134, 36, 134, 5, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 11, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 24,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 134, 134, 134, 11,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 134, 11, 12, 13, 14, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 24, 25, 26, 134, 134, 134, 134, 134,
- 31, 32, 33, 135, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 12,
- 13, 14, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 31, 32, 33, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 31,
- 32, 33, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 14,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 31, 32, 33, 134, 8, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 31, 32, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 32, 134, 8, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 136, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 8, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 12, 13, 14, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 31, 32,
- 33, 135, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 10, 11, 12, 13, 14,
- 134, 134, 134, 134, 134, 134, 21, 22,
- 23, 134, 24, 25, 26, 134, 134, 134,
- 134, 134, 31, 32, 33, 135, 134, 134,
- 134, 134, 11, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 11, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 21,
- 22, 23, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 134, 134, 134, 11, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 134, 11, 12,
- 13, 14, 134, 134, 134, 134, 134, 134,
- 134, 22, 23, 134, 24, 25, 26, 134,
- 134, 134, 134, 134, 31, 32, 33, 135,
- 134, 134, 134, 134, 11, 134, 8, 134,
- 134, 134, 134, 134, 134, 134, 134, 11,
- 12, 13, 14, 134, 134, 134, 134, 134,
- 134, 134, 134, 23, 134, 24, 25, 26,
- 134, 134, 134, 134, 134, 31, 32, 33,
- 135, 134, 134, 134, 134, 11, 134, 137,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 10, 11, 12, 13, 14, 134, 16,
- 17, 134, 134, 134, 21, 22, 23, 134,
- 24, 25, 26, 134, 134, 134, 134, 134,
- 31, 32, 33, 135, 134, 134, 134, 134,
- 11, 134, 8, 134, 134, 134, 134, 134,
- 134, 134, 134, 11, 12, 13, 14, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 24, 25, 26, 134, 134, 134, 134,
- 134, 31, 32, 33, 135, 134, 134, 134,
- 134, 11, 134, 137, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 10, 11, 12,
- 13, 14, 134, 134, 17, 134, 134, 134,
- 21, 22, 23, 134, 24, 25, 26, 134,
- 134, 134, 134, 134, 31, 32, 33, 135,
- 134, 134, 134, 134, 11, 134, 137, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 10, 11, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 21, 22, 23, 134, 24,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 134, 134, 134, 11,
- 134, 137, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 10, 11, 12, 13, 14,
- 15, 16, 17, 134, 134, 134, 21, 22,
- 23, 134, 24, 25, 26, 134, 134, 134,
- 134, 134, 31, 32, 33, 135, 134, 134,
- 134, 134, 11, 134, 5, 6, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 10,
- 11, 12, 13, 14, 15, 16, 17, 18,
- 134, 20, 21, 22, 23, 134, 24, 25,
- 26, 134, 134, 134, 134, 30, 31, 32,
- 33, 30, 134, 134, 134, 134, 36, 134,
- 5, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 8, 134, 5,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 11, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 138, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 8, 134, 7, 8, 134, 1,
- 134, 134, 134, 1, 134, 134, 134, 134,
- 134, 5, 6, 7, 8, 134, 134, 134,
- 134, 134, 134, 134, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 134, 24, 25, 26, 134, 27,
- 28, 134, 30, 31, 32, 33, 30, 134,
- 134, 134, 134, 36, 134, 5, 6, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 134, 24,
- 25, 26, 134, 134, 134, 134, 30, 31,
- 32, 33, 30, 134, 134, 134, 134, 36,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 27, 28, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 28, 134, 1, 139, 139,
- 139, 1, 139, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 142,
- 140, 34, 140, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 34, 142,
- 140, 142, 140, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 34, 140,
- 35, 140, 0
+static const short _use_syllable_machine_index_defaults[] = {
+ 3, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 93, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 97, 93,
+ 67, 99, 102, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 93, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 97, 93, 67, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 136, 137,
+ 137, 137, 0
};
-static const char _use_syllable_machine_trans_targs[] = {
- 1, 31, 0, 59, 61, 90, 91, 116,
- 0, 118, 104, 92, 93, 94, 95, 108,
- 110, 111, 112, 119, 113, 105, 106, 107,
- 99, 100, 101, 120, 121, 122, 114, 96,
- 97, 98, 123, 125, 115, 0, 2, 3,
- 0, 16, 4, 5, 6, 7, 20, 22,
- 23, 24, 28, 25, 17, 18, 19, 11,
- 12, 13, 29, 30, 26, 8, 9, 10,
- 27, 14, 15, 21, 0, 32, 33, 0,
- 46, 34, 35, 36, 37, 50, 52, 53,
- 54, 55, 47, 48, 49, 41, 42, 43,
- 56, 38, 39, 40, 57, 58, 44, 0,
- 45, 0, 51, 0, 0, 0, 60, 0,
- 0, 0, 62, 63, 76, 64, 65, 66,
- 67, 80, 82, 83, 84, 89, 85, 77,
- 78, 79, 71, 72, 73, 86, 68, 69,
- 70, 87, 88, 74, 75, 81, 0, 102,
- 103, 109, 117, 0, 0, 0, 124
+static const signed char _use_syllable_machine_cond_targs[] = {
+ 0, 1, 30, 0, 57, 59, 87, 88,
+ 113, 0, 115, 101, 89, 90, 91, 92,
+ 105, 107, 108, 109, 110, 102, 103, 104,
+ 96, 97, 98, 116, 117, 118, 111, 93,
+ 94, 95, 119, 121, 112, 0, 2, 3,
+ 0, 16, 4, 5, 6, 7, 20, 22,
+ 23, 24, 25, 17, 18, 19, 11, 12,
+ 13, 28, 29, 26, 8, 9, 10, 27,
+ 14, 15, 21, 0, 31, 0, 44, 32,
+ 33, 34, 35, 48, 50, 51, 52, 53,
+ 45, 46, 47, 39, 40, 41, 54, 36,
+ 37, 38, 55, 56, 42, 0, 43, 0,
+ 49, 0, 0, 0, 58, 0, 0, 0,
+ 60, 61, 74, 62, 63, 64, 65, 78,
+ 80, 81, 82, 83, 75, 76, 77, 69,
+ 70, 71, 84, 66, 67, 68, 85, 86,
+ 72, 73, 79, 0, 99, 100, 106, 114,
+ 0, 0, 0, 120, 0
};
-static const char _use_syllable_machine_trans_actions[] = {
- 0, 0, 3, 0, 0, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 5, 0, 0,
- 6, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 0, 0, 8,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 9,
- 0, 10, 0, 11, 12, 13, 0, 14,
- 15, 16, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 17, 0,
- 0, 0, 0, 18, 19, 20, 0
+static const signed char _use_syllable_machine_cond_actions[] = {
+ 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 0, 8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 10,
+ 0, 11, 12, 13, 0, 14, 15, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 17, 0, 0, 0, 0,
+ 18, 19, 20, 0, 0
};
-static const char _use_syllable_machine_to_state_actions[] = {
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0
+static const signed char _use_syllable_machine_to_state_actions[] = {
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
};
-static const char _use_syllable_machine_from_state_actions[] = {
- 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0
+static const signed char _use_syllable_machine_from_state_actions[] = {
+ 2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
};
static const short _use_syllable_machine_eof_trans[] = {
- 0, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 96, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 100, 96, 69, 102, 105, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 96, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 100, 96,
- 69, 69, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 140, 141, 141, 141
+ 1, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 94, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 98, 94,
+ 68, 100, 103, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 94, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 98, 94, 68, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 137, 138,
+ 138, 138, 0
};
static const int use_syllable_machine_start = 0;
@@ -834,65 +701,65 @@ static const int use_syllable_machine_en_main = 0;
#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
- for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (syllable_serial == 16) syllable_serial = 1; \
- } HB_STMT_END
+HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
+ for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ syllable_serial++; \
+ if (syllable_serial == 16) syllable_serial = 1; \
+ } HB_STMT_END
template <typename Iter>
struct machine_index_t :
- hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t>
+hb_iter_with_fallback_t<machine_index_t<Iter>,
+typename Iter::item_t>
{
- machine_index_t (const Iter& it) : it (it) {}
- machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t> (),
- it (o.it), is_null (o.is_null) {}
-
- static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
- static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
-
- typename Iter::item_t __item__ () const { return *it; }
- typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
- unsigned __len__ () const { return it.len (); }
- void __next__ () { ++it; }
- void __forward__ (unsigned n) { it += n; }
- void __prev__ () { --it; }
- void __rewind__ (unsigned n) { it -= n; }
-
- void operator = (unsigned n)
- {
- assert (n == 0);
- is_null = true;
- }
- explicit operator bool () { return !is_null; }
-
- void operator = (const machine_index_t& o)
- {
- is_null = o.is_null;
- unsigned index = (*it).first;
- unsigned n = (*o.it).first;
- if (index < n) it += n - index; else if (index > n) it -= index - n;
- }
- bool operator == (const machine_index_t& o) const
- { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
- bool operator != (const machine_index_t& o) const { return !(*this == o); }
-
- private:
- Iter it;
- bool is_null = false;
+ machine_index_t (const Iter& it) : it (it) {}
+ machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
+ typename Iter::item_t> (),
+ it (o.it), is_null (o.is_null) {}
+
+ static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
+ static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+
+ typename Iter::item_t __item__ () const { return *it; }
+ typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
+ unsigned __len__ () const { return it.len (); }
+ void __next__ () { ++it; }
+ void __forward__ (unsigned n) { it += n; }
+ void __prev__ () { --it; }
+ void __rewind__ (unsigned n) { it -= n; }
+
+ void operator = (unsigned n)
+ {
+ assert (n == 0);
+ is_null = true;
+ }
+ explicit operator bool () { return !is_null; }
+
+ void operator = (const machine_index_t& o)
+ {
+ is_null = o.is_null;
+ unsigned index = (*it).first;
+ unsigned n = (*o.it).first;
+ if (index < n) it += n - index; else if (index > n) it -= index - n;
+ }
+ bool operator == (const machine_index_t& o) const
+ { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
+ bool operator != (const machine_index_t& o) const { return !(*this == o); }
+
+ private:
+ Iter it;
+ bool is_null = false;
};
struct
{
- template <typename Iter,
- hb_requires (hb_is_iterable (Iter))>
- machine_index_t<hb_iter_type<Iter>>
- operator () (Iter&& it) const
- { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
+ template <typename Iter,
+ hb_requires (hb_is_iterable (Iter))>
+ machine_index_t<hb_iter_type<Iter>>
+ operator () (Iter&& it) const
+ { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
}
HB_FUNCOBJ (machine_index);
@@ -905,172 +772,352 @@ not_ccs_default_ignorable (const hb_glyph_info_t &i)
static inline void
find_syllables_use (hb_buffer_t *buffer)
{
- hb_glyph_info_t *info = buffer->info;
- auto p =
- + hb_iter (info, buffer->len)
- | hb_enumerate
- | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
- hb_second)
- | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
- {
- if (p.second.use_category() == USE(ZWNJ))
- for (unsigned i = p.first + 1; i < buffer->len; ++i)
- if (not_ccs_default_ignorable (info[i]))
- return !_hb_glyph_info_is_unicode_mark (&info[i]);
- return true;
- })
- | hb_enumerate
- | machine_index
- ;
- auto pe = p + p.len ();
- auto eof = +pe;
- auto ts = +p;
- auto te = +p;
- unsigned int act HB_UNUSED;
- int cs;
-
-#line 922 "hb-ot-shaper-use-machine.hh"
+ hb_glyph_info_t *info = buffer->info;
+ auto p =
+ + hb_iter (info, buffer->len)
+ | hb_enumerate
+ | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
+ hb_second)
+ | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
{
- cs = use_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
+ if (p.second.use_category() == USE(ZWNJ))
+ for (unsigned i = p.first + 1; i < buffer->len; ++i)
+ if (not_ccs_default_ignorable (info[i]))
+ return !_hb_glyph_info_is_unicode_mark (&info[i]);
+ return true;
+ })
+ | hb_enumerate
+ | machine_index
+ ;
+ auto pe = p + p.len ();
+ auto eof = +pe;
+ auto ts = +p;
+ auto te = +p;
+ unsigned int act HB_UNUSED;
+ int cs;
+#line 792 "hb-ot-shaper-use-machine.hh"
+ {
+ cs = (int)use_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ }
+
#line 282 "hb-ot-shaper-use-machine.rl"
+
+ unsigned int syllable_serial = 1;
- unsigned int syllable_serial = 1;
-
-#line 931 "hb-ot-shaper-use-machine.hh"
+#line 801 "hb-ot-shaper-use-machine.hh"
{
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const unsigned char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _use_syllable_machine_from_state_actions[cs] ) {
- case 2:
+ unsigned int _trans = 0;
+ const unsigned char * _keys;
+ const short * _inds;
+ int _ic;
+ _resume: {}
+ if ( p == pe && p != eof )
+ goto _out;
+ switch ( _use_syllable_machine_from_state_actions[cs] ) {
+ case 2: {
+ {
#line 1 "NONE"
- {ts = p;}
- break;
-#line 943 "hb-ot-shaper-use-machine.hh"
- }
-
- _keys = _use_syllable_machine_trans_keys + (cs<<1);
- _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
+ {ts = p;}}
+
+#line 815 "hb-ot-shaper-use-machine.hh"
- _slen = _use_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) &&
- ( (*p).second.second.use_category()) <= _keys[1] ?
- ( (*p).second.second.use_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _use_syllable_machine_trans_targs[_trans];
-
- if ( _use_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _use_syllable_machine_trans_actions[_trans] ) {
- case 12:
+
+ break;
+ }
+ }
+
+ if ( p == eof ) {
+ if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = (unsigned int)_use_syllable_machine_eof_trans[cs] - 1;
+ }
+ }
+ else {
+ _keys = ( _use_syllable_machine_trans_keys + ((cs<<1)));
+ _inds = ( _use_syllable_machine_indicies + (_use_syllable_machine_index_offsets[cs]));
+
+ if ( ((*p).second.second.use_category()) <= 53 ) {
+ _ic = (int)_use_syllable_machine_char_class[(int)((*p).second.second.use_category()) - 0];
+ if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
+ _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
+ else
+ _trans = (unsigned int)_use_syllable_machine_index_defaults[cs];
+ }
+ else {
+ _trans = (unsigned int)_use_syllable_machine_index_defaults[cs];
+ }
+
+ }
+ cs = (int)_use_syllable_machine_cond_targs[_trans];
+
+ if ( _use_syllable_machine_cond_actions[_trans] != 0 ) {
+
+ switch ( _use_syllable_machine_cond_actions[_trans] ) {
+ case 12: {
+ {
+#line 170 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 170 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
- break;
- case 10:
+ found_syllable (use_virama_terminated_cluster); }
+ }}
+
+#line 855 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 10: {
+ {
+#line 171 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 171 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
- break;
- case 8:
+ found_syllable (use_sakot_terminated_cluster); }
+ }}
+
+#line 867 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 8: {
+ {
+#line 172 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 172 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_standard_cluster); }}
- break;
- case 16:
+ found_syllable (use_standard_cluster); }
+ }}
+
+#line 879 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 16: {
+ {
+#line 173 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 173 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
- break;
- case 14:
+ found_syllable (use_number_joiner_terminated_cluster); }
+ }}
+
+#line 891 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 14: {
+ {
+#line 174 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 174 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_numeral_cluster); }}
- break;
- case 6:
+ found_syllable (use_numeral_cluster); }
+ }}
+
+#line 903 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 6: {
+ {
+#line 175 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{
#line 175 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_symbol_cluster); }}
- break;
- case 20:
+ found_syllable (use_symbol_cluster); }
+ }}
+
+#line 915 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 20: {
+ {
#line 176 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
- break;
- case 4:
+ {te = p+1;{
+#line 176 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_hieroglyph_cluster); }
+ }}
+
+#line 927 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 4: {
+ {
#line 177 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 3:
+ {te = p+1;{
+#line 177 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
+ }}
+
+#line 939 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 3: {
+ {
#line 178 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_non_cluster); }}
- break;
- case 11:
+ {te = p+1;{
+#line 178 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_non_cluster); }
+ }}
+
+#line 951 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 11: {
+ {
#line 170 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
- break;
- case 9:
+ {te = p;p = p - 1;{
+#line 170 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_virama_terminated_cluster); }
+ }}
+
+#line 963 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 9: {
+ {
#line 171 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
- break;
- case 7:
+ {te = p;p = p - 1;{
+#line 171 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_sakot_terminated_cluster); }
+ }}
+
+#line 975 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 7: {
+ {
#line 172 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_standard_cluster); }}
- break;
- case 15:
+ {te = p;p = p - 1;{
+#line 172 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_standard_cluster); }
+ }}
+
+#line 987 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 15: {
+ {
#line 173 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
- break;
- case 13:
+ {te = p;p = p - 1;{
+#line 173 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_number_joiner_terminated_cluster); }
+ }}
+
+#line 999 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 13: {
+ {
+#line 174 "hb-ot-shaper-use-machine.rl"
+ {te = p;p = p - 1;{
#line 174 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_numeral_cluster); }}
- break;
- case 5:
+ found_syllable (use_numeral_cluster); }
+ }}
+
+#line 1011 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 5: {
+ {
+#line 175 "hb-ot-shaper-use-machine.rl"
+ {te = p;p = p - 1;{
#line 175 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_symbol_cluster); }}
- break;
- case 19:
+ found_syllable (use_symbol_cluster); }
+ }}
+
+#line 1023 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 19: {
+ {
+#line 176 "hb-ot-shaper-use-machine.rl"
+ {te = p;p = p - 1;{
#line 176 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
- break;
- case 17:
+ found_syllable (use_hieroglyph_cluster); }
+ }}
+
+#line 1035 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 17: {
+ {
+#line 177 "hb-ot-shaper-use-machine.rl"
+ {te = p;p = p - 1;{
#line 177 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 18:
+ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
+ }}
+
+#line 1047 "hb-ot-shaper-use-machine.hh"
+
+
+ break;
+ }
+ case 18: {
+ {
#line 178 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_non_cluster); }}
- break;
-#line 1014 "hb-ot-shaper-use-machine.hh"
- }
+ {te = p;p = p - 1;{
+#line 178 "hb-ot-shaper-use-machine.rl"
+ found_syllable (use_non_cluster); }
+ }}
+
+#line 1059 "hb-ot-shaper-use-machine.hh"
-_again:
- switch ( _use_syllable_machine_to_state_actions[cs] ) {
- case 1:
+
+ break;
+ }
+ }
+
+ }
+
+ if ( p == eof ) {
+ if ( cs >= 0 )
+ goto _out;
+ }
+ else {
+ switch ( _use_syllable_machine_to_state_actions[cs] ) {
+ case 1: {
+ {
#line 1 "NONE"
- {ts = 0;}
- break;
-#line 1021 "hb-ot-shaper-use-machine.hh"
- }
+ {ts = 0;}}
+
+#line 1078 "hb-ot-shaper-use-machine.hh"
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _use_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
+
+ break;
+ }
+ }
+
+ p += 1;
+ goto _resume;
+ }
+ _out: {}
}
-
- }
-
+
#line 287 "hb-ot-shaper-use-machine.rl"
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh
index 3449b30499..f3754aa6b8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh
@@ -72,6 +72,65 @@ struct AxisValueMap
return_trace (c->check_struct (this));
}
+ void set_mapping (float from_coord, float to_coord)
+ {
+ coords[0].set_float (from_coord);
+ coords[1].set_float (to_coord);
+ }
+
+ bool is_outside_axis_range (const Triple& axis_range) const
+ {
+ float from_coord = coords[0].to_float ();
+ return !axis_range.contains (from_coord);
+ }
+
+ bool must_include () const
+ {
+ float from_coord = coords[0].to_float ();
+ float to_coord = coords[1].to_float ();
+ return (from_coord == -1.f && to_coord == -1.f) ||
+ (from_coord == 0.f && to_coord == 0.f) ||
+ (from_coord == 1.f && to_coord == 1.f);
+ }
+
+ void instantiate (const Triple& axis_range,
+ const Triple& unmapped_range,
+ const TripleDistances& triple_distances)
+ {
+ float from_coord = coords[0].to_float ();
+ float to_coord = coords[1].to_float ();
+
+ from_coord = renormalizeValue (from_coord, unmapped_range, triple_distances);
+ to_coord = renormalizeValue (to_coord, axis_range, triple_distances);
+
+ coords[0].set_float (from_coord);
+ coords[1].set_float (to_coord);
+ }
+
+ HB_INTERNAL static int cmp (const void *pa, const void *pb)
+ {
+ const AxisValueMap *a = (const AxisValueMap *) pa;
+ const AxisValueMap *b = (const AxisValueMap *) pb;
+
+ int a_from = a->coords[0].to_int ();
+ int b_from = b->coords[0].to_int ();
+ if (a_from != b_from)
+ return a_from - b_from;
+
+ /* this should never be reached. according to the spec, all of the axis
+ * value map records for a given axis must have different fromCoord values
+ * */
+ int a_to = a->coords[1].to_int ();
+ int b_to = b->coords[1].to_int ();
+ return a_to - b_to;
+ }
+
+ bool serialize (hb_serialize_context_t *c) const
+ {
+ TRACE_SERIALIZE (this);
+ return_trace (c->embed (this));
+ }
+
public:
F2DOT14 coords[2];
// F2DOT14 fromCoord; /* A normalized coordinate value obtained using
@@ -122,6 +181,78 @@ struct SegmentMaps : Array16Of<AxisValueMap>
int unmap (int value) const { return map (value, 1, 0); }
+ Triple unmap_axis_range (const Triple& axis_range) const
+ {
+ F2DOT14 val, unmapped_val;
+
+ val.set_float (axis_range.minimum);
+ unmapped_val.set_int (unmap (val.to_int ()));
+ float unmapped_min = unmapped_val.to_float ();
+
+ val.set_float (axis_range.middle);
+ unmapped_val.set_int (unmap (val.to_int ()));
+ float unmapped_middle = unmapped_val.to_float ();
+
+ val.set_float (axis_range.maximum);
+ unmapped_val.set_int (unmap (val.to_int ()));
+ float unmapped_max = unmapped_val.to_float ();
+
+ return Triple{unmapped_min, unmapped_middle, unmapped_max};
+ }
+
+ bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const
+ {
+ TRACE_SUBSET (this);
+ /* avar mapped normalized axis range*/
+ Triple *axis_range;
+ if (!c->plan->axes_location.has (axis_tag, &axis_range))
+ return c->serializer->embed (*this);
+
+ TripleDistances *axis_triple_distances;
+ if (!c->plan->axes_triple_distances.has (axis_tag, &axis_triple_distances))
+ return_trace (false);
+
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ Triple unmapped_range = unmap_axis_range (*axis_range);
+
+ /* create a vector of retained mappings and sort */
+ hb_vector_t<AxisValueMap> value_mappings;
+ for (const auto& _ : as_array ())
+ {
+ if (_.is_outside_axis_range (unmapped_range))
+ continue;
+ AxisValueMap mapping;
+ mapping = _;
+ mapping.instantiate (*axis_range, unmapped_range, *axis_triple_distances);
+ /* (-1, -1), (0, 0), (1, 1) mappings will be added later, so avoid
+ * duplicates here */
+ if (mapping.must_include ())
+ continue;
+ value_mappings.push (std::move (mapping));
+ }
+
+ AxisValueMap m;
+ m.set_mapping (-1.f, -1.f);
+ value_mappings.push (m);
+
+ m.set_mapping (0.f, 0.f);
+ value_mappings.push (m);
+
+ m.set_mapping (1.f, 1.f);
+ value_mappings.push (m);
+
+ value_mappings.qsort ();
+
+ for (const auto& _ : value_mappings)
+ {
+ if (!_.serialize (c->serializer))
+ return_trace (false);
+ }
+ return_trace (c->serializer->check_assign (out->len, value_mappings.length, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+ }
+
public:
DEFINE_SIZE_ARRAY (2, *this);
};
@@ -225,6 +356,39 @@ struct avar
}
}
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ unsigned retained_axis_count = c->plan->axes_index_map.get_population ();
+ if (!retained_axis_count) //all axes are pinned/dropped
+ return_trace (false);
+
+ avar *out = c->serializer->allocate_min<avar> ();
+ if (unlikely (!out)) return_trace (false);
+
+ out->version.major = 1;
+ out->version.minor = 0;
+ if (!c->serializer->check_assign (out->axisCount, retained_axis_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+ return_trace (false);
+
+ const hb_map_t& axes_index_map = c->plan->axes_index_map;
+ const SegmentMaps *map = &firstAxisSegmentMaps;
+ unsigned count = axisCount;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (axes_index_map.has (i))
+ {
+ hb_tag_t *axis_tag;
+ if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag))
+ return_trace (false);
+ if (!map->subset (c, *axis_tag))
+ return_trace (false);
+ }
+ map = &StructAfter<SegmentMaps> (*map);
+ }
+ return_trace (true);
+ }
+
protected:
FixedVersion<>version; /* Version of the avar table
* initially set to 0x00010000u */
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh
index 44ec64bc03..9e813f6d2d 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh
@@ -60,18 +60,21 @@ struct DeltaSetIndexMapFormat01
entryFormat = ((width-1)<<4)|(inner_bit_count-1);
mapCount = output_map.length;
- HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length, false);
+ HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
if (unlikely (!p)) return_trace (false);
for (unsigned int i = 0; i < output_map.length; i++)
{
- unsigned int v = output_map[i];
- unsigned int outer = v >> 16;
- unsigned int inner = v & 0xFFFF;
- unsigned int u = (outer << inner_bit_count) | inner;
- for (unsigned int w = width; w > 0;)
+ unsigned int v = output_map.arrayZ[i];
+ if (v)
{
- p[--w] = u;
- u >>= 8;
+ unsigned int outer = v >> 16;
+ unsigned int inner = v & 0xFFFF;
+ unsigned int u = (outer << inner_bit_count) | inner;
+ for (unsigned int w = width; w > 0;)
+ {
+ p[--w] = u;
+ u >>= 8;
+ }
}
p += width;
}
@@ -421,25 +424,6 @@ struct TupleVariationHeader
DEFINE_SIZE_MIN (4);
};
-/* not using hb_bytes_t: avoid potential build issues with some compilers */
-struct byte_data_t
-{
- hb_bytes_t bytes;
-
- byte_data_t () = default;
- byte_data_t (const char *p_, unsigned len_) : bytes (hb_bytes_t (p_, len_)) {}
-
- void fini () { bytes.fini (); }
-
- bool operator == (const byte_data_t& o) const
- { return bytes.arrayZ == o.bytes.arrayZ && bytes.length == o.bytes.length; }
-
- explicit operator bool () const { return bytes.length; }
-
- void copy (hb_serialize_context_t *c) const
- { c->embed (bytes.arrayZ, bytes.length); }
-};
-
enum packed_delta_flag_t
{
DELTAS_ARE_ZERO = 0x80,
@@ -505,6 +489,7 @@ struct tuple_delta_t
else
{
if (!o.indices.arrayZ[i]) continue;
+ indices.arrayZ[i] = true;
deltas_x[i] = o.deltas_x[i];
if (deltas_y && o.deltas_y)
deltas_y[i] = o.deltas_y[i];
@@ -530,7 +515,8 @@ struct tuple_delta_t
return *this;
}
- hb_vector_t<tuple_delta_t> change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit) const
+ hb_vector_t<tuple_delta_t> change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit,
+ TripleDistances axis_triple_distances) const
{
hb_vector_t<tuple_delta_t> out;
Triple *tent;
@@ -550,7 +536,7 @@ struct tuple_delta_t
return out;
}
- result_t solutions = rebase_tent (*tent, axis_limit);
+ result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances);
for (auto t : solutions)
{
tuple_delta_t new_var = *this;
@@ -715,6 +701,8 @@ struct tuple_delta_t
}
if (j != rounded_deltas.length) return false;
+ /* reset i because we reuse rounded_deltas for deltas_y */
+ i = 0;
encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas);
}
return compiled_deltas.resize (encoded_len);
@@ -755,14 +743,14 @@ struct tuple_delta_t
while (run_length >= 64)
{
- *it++ = (DELTAS_ARE_ZERO | 63);
+ *it++ = char (DELTAS_ARE_ZERO | 63);
run_length -= 64;
encoded_len++;
}
if (run_length)
{
- *it++ = (DELTAS_ARE_ZERO | (run_length - 1));
+ *it++ = char (DELTAS_ARE_ZERO | (run_length - 1));
encoded_len++;
}
return encoded_len;
@@ -870,6 +858,7 @@ struct tuple_delta_t
if (run_length)
{
*it++ = (DELTAS_ARE_WORDS | (run_length - 1));
+ encoded_len++;
while (start < i)
{
int16_t delta_val = deltas[start++];
@@ -917,7 +906,7 @@ struct TupleVariationData
private:
/* referenced point set->compiled point data map */
- hb_hashmap_t<const hb_vector_t<bool>*, byte_data_t> point_data_map;
+ hb_hashmap_t<const hb_vector_t<bool>*, hb_bytes_t> point_data_map;
/* referenced point set-> count map, used in finding shared points */
hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map;
@@ -1003,16 +992,21 @@ struct TupleVariationData
return true;
}
- void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple> *normalized_axes_location)
+ void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+ const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
{
- for (auto _ : *normalized_axes_location)
+ for (auto _ : normalized_axes_location)
{
hb_tag_t axis_tag = _.first;
Triple axis_limit = _.second;
+ TripleDistances axis_triple_distances{1.f, 1.f};
+ if (axes_triple_distances.has (axis_tag))
+ axis_triple_distances = axes_triple_distances.get (axis_tag);
+
hb_vector_t<tuple_delta_t> new_vars;
for (const tuple_delta_t& var : tuple_vars)
{
- hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, axis_limit);
+ hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, axis_limit, axis_triple_distances);
if (!out) continue;
unsigned new_len = new_vars.length + out.length;
@@ -1054,7 +1048,7 @@ struct TupleVariationData
tuple_vars = std::move (new_vars);
}
- byte_data_t compile_point_set (const hb_vector_t<bool> &point_indices)
+ hb_bytes_t compile_point_set (const hb_vector_t<bool> &point_indices)
{
unsigned num_points = 0;
for (bool i : point_indices)
@@ -1066,15 +1060,15 @@ struct TupleVariationData
if (num_points == indices_length)
{
char *p = (char *) hb_calloc (1, sizeof (char));
- if (unlikely (!p)) return byte_data_t ();
+ if (unlikely (!p)) return hb_bytes_t ();
- return byte_data_t (p, 1);
+ return hb_bytes_t (p, 1);
}
/* allocate enough memories: 2 bytes for count + 3 bytes for each point */
unsigned num_bytes = 2 + 3 *num_points;
char *p = (char *) hb_calloc (num_bytes, sizeof (char));
- if (unlikely (!p)) return byte_data_t ();
+ if (unlikely (!p)) return hb_bytes_t ();
unsigned pos = 0;
/* binary data starts with the total number of reference points */
@@ -1137,10 +1131,10 @@ struct TupleVariationData
else
p[header_pos] = (run_length - 1) | 0x80;
}
- return byte_data_t (p, pos);
+ return hb_bytes_t (p, pos);
}
- /* compile all point set and store byte data in a point_set->byte_data_t hashmap,
+ /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap,
* also update point_set->count map, which will be used in finding shared
* point set*/
bool compile_all_point_sets ()
@@ -1157,8 +1151,8 @@ struct TupleVariationData
continue;
}
- byte_data_t compiled_data = compile_point_set (*points_set);
- if (unlikely (compiled_data == byte_data_t ()))
+ hb_bytes_t compiled_data = compile_point_set (*points_set);
+ if (unlikely (compiled_data == hb_bytes_t ()))
return false;
if (!point_data_map.set (points_set, compiled_data) ||
@@ -1169,19 +1163,19 @@ struct TupleVariationData
}
/* find shared points set which saves most bytes */
- byte_data_t find_shared_points ()
+ hb_bytes_t find_shared_points ()
{
unsigned max_saved_bytes = 0;
- byte_data_t res{};
+ hb_bytes_t res{};
for (const auto& _ : point_data_map.iter ())
{
const hb_vector_t<bool>* points_set = _.first;
- unsigned data_length = _.second.bytes.length;
+ unsigned data_length = _.second.length;
unsigned *count;
if (unlikely (!point_set_count_map.has (points_set, &count) ||
*count <= 1))
- return byte_data_t ();
+ return hb_bytes_t ();
unsigned saved_bytes = data_length * ((*count) -1);
if (saved_bytes > max_saved_bytes)
@@ -1193,9 +1187,10 @@ struct TupleVariationData
return res;
}
- void instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location)
+ void instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+ const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
{
- change_tuple_variations_axis_limits (&normalized_axes_location);
+ change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances);
merge_tuple_variations ();
}
@@ -1209,14 +1204,14 @@ struct TupleVariationData
for (auto& tuple: tuple_vars)
{
const hb_vector_t<bool>* points_set = &(tuple.indices);
- byte_data_t *points_data;
+ hb_bytes_t *points_data;
if (unlikely (!point_data_map.has (points_set, &points_data)))
return false;
if (!tuple.compile_deltas ())
return false;
- if (!tuple.compile_tuple_var_header (axes_index_map, points_data->bytes.length, axes_old_index_tag_map))
+ if (!tuple.compile_tuple_var_header (axes_index_map, points_data->length, axes_old_index_tag_map))
return false;
}
return true;
@@ -1227,8 +1222,7 @@ struct TupleVariationData
TRACE_SERIALIZE (this);
for (const auto& tuple: tuple_vars)
{
- byte_data_t compiled_bytes {tuple.compiled_tuple_header.arrayZ, tuple.compiled_tuple_header.length};
- compiled_bytes.copy (c);
+ tuple.compiled_tuple_header.as_array ().copy (c);
if (c->in_error ()) return_trace (false);
total_header_len += tuple.compiled_tuple_header.length;
}
@@ -1241,13 +1235,12 @@ struct TupleVariationData
for (const auto& tuple: tuple_vars)
{
const hb_vector_t<bool>* points_set = &(tuple.indices);
- byte_data_t *point_data;
+ hb_bytes_t *point_data;
if (!point_data_map.has (points_set, &point_data))
return_trace (false);
point_data->copy (c);
- byte_data_t compiled_bytes {tuple.compiled_deltas.arrayZ, tuple.compiled_deltas.length};
- compiled_bytes.copy (c);
+ tuple.compiled_deltas.as_array ().copy (c);
if (c->in_error ()) return_trace (false);
}
return_trace (true);
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh
index de54339301..fee39eff38 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh
@@ -161,13 +161,14 @@ struct cvar
const hb_tag_t cvt = HB_TAG('c','v','t',' ');
hb_blob_t *cvt_blob = hb_face_reference_table (c->plan->source, cvt);
unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size;
+ hb_blob_destroy (cvt_blob);
if (!decompile_tuple_variations (axis_count, point_count, false,
&(c->plan->axes_old_index_tag_map),
tuple_variations))
return_trace (false);
- tuple_variations.instantiate (c->plan->axes_location);
+ tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances);
if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map))
return_trace (false);
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
index d8e789cb44..4c4957bd71 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
@@ -99,16 +99,16 @@ struct InstanceRecord
for (unsigned i = 0 ; i < axis_count; i++)
{
uint32_t *axis_tag;
+ Triple *axis_limit;
// only keep instances whose coordinates == pinned axis location
- if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue;
- if (axes_location->has (*axis_tag))
+ if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) return_trace (false);
+ if (axes_location->has (*axis_tag, &axis_limit))
{
- Triple axis_limit = axes_location->get (*axis_tag);
- if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit))
+ if (!axis_coord_pinned_or_within_axis_range (coords, i, *axis_limit))
return_trace (false);
//skip pinned axis
- if (axis_limit.is_point ())
+ if (axis_limit->is_point ())
continue;
}
@@ -228,6 +228,30 @@ struct AxisRecord
return defaultValue.to_float ();
}
+ TripleDistances get_triple_distances () const
+ {
+ float min, default_, max;
+ get_coordinates (min, default_, max);
+ return TripleDistances (min, default_, max);
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ auto *out = c->serializer->embed (this);
+ if (unlikely (!out)) return_trace (false);
+
+ const hb_hashmap_t<hb_tag_t, Triple>& user_axes_location = c->plan->user_axes_location;
+ Triple *axis_limit;
+ if (user_axes_location.has (axisTag, &axis_limit))
+ {
+ out->minValue.set_float (axis_limit->minimum);
+ out->defaultValue.set_float (axis_limit->middle);
+ out->maxValue.set_float (axis_limit->maximum);
+ }
+ return_trace (true);
+ }
+
public:
Tag axisTag; /* Tag identifying the design variation for the axis. */
protected:
@@ -416,21 +440,25 @@ struct fvar
for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
{
if (!c->plan->axes_index_map.has (i)) continue;
- if (unlikely (!c->serializer->embed (axes_records[i])))
+ if (unlikely (!axes_records[i].subset (c)))
return_trace (false);
}
if (!c->serializer->check_assign (out->firstAxis, get_size (), HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
+ unsigned num_retained_instances = 0;
for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
{
const InstanceRecord *instance = get_instance (i);
auto snap = c->serializer->snapshot ();
if (!instance->subset (c, axisCount, has_postscript_nameid))
c->serializer->revert (snap);
+ else
+ num_retained_instances++;
}
- return_trace (true);
+
+ return_trace (c->serializer->check_assign (out->instanceCount, num_retained_instances, HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
public:
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
index 943d376bdf..490f883fcc 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
@@ -45,7 +45,8 @@ struct index_map_subset_plan_t
void init (const DeltaSetIndexMap &index_map,
hb_inc_bimap_t &outer_map,
hb_vector_t<hb_set_t *> &inner_sets,
- const hb_subset_plan_t *plan)
+ const hb_subset_plan_t *plan,
+ bool bypass_empty = true)
{
map_count = 0;
outer_bit_count = 0;
@@ -53,11 +54,10 @@ struct index_map_subset_plan_t
max_inners.init ();
output_map.init ();
- if (&index_map == &Null (DeltaSetIndexMap)) return;
+ if (bypass_empty && !index_map.get_map_count ()) return;
unsigned int last_val = (unsigned int)-1;
hb_codepoint_t last_gid = HB_CODEPOINT_INVALID;
- hb_codepoint_t num_gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
max_inners.resize (inner_sets.length);
@@ -68,24 +68,17 @@ struct index_map_subset_plan_t
unsigned count = new_to_old_gid_list.length;
for (unsigned j = count; j; j--)
{
- hb_codepoint_t gid = new_to_old_gid_list[j - 1].first;
- if (gid >= num_gid) continue;
-
- hb_codepoint_t old_gid = new_to_old_gid_list[j - 1].second;
+ hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first;
+ hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second;
unsigned int v = index_map.map (old_gid);
if (last_gid == HB_CODEPOINT_INVALID)
{
- if (gid + 1 != num_gid)
- {
- last_gid = gid + 1;
- break;
- }
last_val = v;
last_gid = gid;
continue;
}
- if (v != last_val || gid + 1 != last_gid)
+ if (v != last_val)
break;
last_gid = gid;
@@ -120,8 +113,6 @@ struct index_map_subset_plan_t
const hb_vector_t<hb_inc_bimap_t> &inner_maps,
const hb_subset_plan_t *plan)
{
- if (input_map == &Null (DeltaSetIndexMap)) return;
-
for (unsigned int i = 0; i < max_inners.length; i++)
{
if (inner_maps[i].get_population () == 0) continue;
@@ -129,18 +120,17 @@ struct index_map_subset_plan_t
if (bit_count > inner_bit_count) inner_bit_count = bit_count;
}
- output_map.resize (map_count);
- for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
+ if (unlikely (!output_map.resize (map_count))) return;
+ for (const auto &_ : plan->new_to_old_gid_list)
{
- hb_codepoint_t old_gid;
- if (plan->old_gid_for_new_gid (gid, &old_gid))
- {
- uint32_t v = input_map->map (old_gid);
- unsigned int outer = v >> 16;
- output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
- }
- else
- output_map[gid] = 0; /* Map unused glyph to outer/inner=0/0 */
+ hb_codepoint_t new_gid = _.first;
+ hb_codepoint_t old_gid = _.second;
+
+ if (unlikely (new_gid >= map_count)) break;
+
+ uint32_t v = input_map->map (old_gid);
+ unsigned int outer = v >> 16;
+ output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
}
}
@@ -184,7 +174,7 @@ struct hvarvvar_subset_plan_t
if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
bool retain_adv_map = false;
- index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
+ index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false);
if (index_maps[0] == &Null (DeltaSetIndexMap))
{
retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
@@ -201,13 +191,10 @@ struct hvarvvar_subset_plan_t
if (retain_adv_map)
{
- unsigned num_glyphs = plan->num_output_glyphs ();
- for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+ for (const auto &_ : plan->new_to_old_gid_list)
{
- if (inner_sets[0]->has (gid))
- inner_maps[0].add (gid);
- else
- inner_maps[0].skip ();
+ hb_codepoint_t old_gid = _.second;
+ inner_maps[0].add (old_gid);
}
}
else
diff --git a/thirdparty/harfbuzz/src/hb-priority-queue.hh b/thirdparty/harfbuzz/src/hb-priority-queue.hh
index bf1b282d3d..baac7e1e69 100644
--- a/thirdparty/harfbuzz/src/hb-priority-queue.hh
+++ b/thirdparty/harfbuzz/src/hb-priority-queue.hh
@@ -54,6 +54,9 @@ struct hb_priority_queue_t
bool in_error () const { return heap.in_error (); }
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
void insert (int64_t priority, unsigned value)
{
heap.push (item_t (priority, value));
@@ -61,6 +64,9 @@ struct hb_priority_queue_t
bubble_up (heap.length - 1);
}
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
item_t pop_minimum ()
{
assert (!is_empty ());
@@ -106,8 +112,10 @@ struct hb_priority_queue_t
return 2 * index + 2;
}
+ HB_ALWAYS_INLINE
void bubble_down (unsigned index)
{
+ repeat:
assert (index < heap.length);
unsigned left = left_child (index);
@@ -123,19 +131,21 @@ struct hb_priority_queue_t
&& (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
return;
+ unsigned child;
if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
- {
- swap (index, left);
- bubble_down (left);
- return;
- }
+ child = left;
+ else
+ child = right;
- swap (index, right);
- bubble_down (right);
+ swap (index, child);
+ index = child;
+ goto repeat;
}
+ HB_ALWAYS_INLINE
void bubble_up (unsigned index)
{
+ repeat:
assert (index < heap.length);
if (index == 0) return;
@@ -145,7 +155,8 @@ struct hb_priority_queue_t
return;
swap (index, parent_index);
- bubble_up (parent_index);
+ index = parent_index;
+ goto repeat;
}
void swap (unsigned a, unsigned b)
diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh
index 2d338c51c8..efb5adde5f 100644
--- a/thirdparty/harfbuzz/src/hb-sanitize.hh
+++ b/thirdparty/harfbuzz/src/hb-sanitize.hh
@@ -258,7 +258,8 @@ struct hb_sanitize_context_t :
this->max_ops = -1;
return false;
}
- return (this->max_ops -= (int) count) > 0;
+ this->max_ops -= (int) count;
+ return true;
}
#ifndef HB_OPTIMIZE_SIZE
@@ -381,6 +382,9 @@ struct hb_sanitize_context_t :
}
template <typename Type>
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
bool check_struct (const Type *obj) const
{
if (sizeof (uintptr_t) == sizeof (uint32_t))
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index f852f07ba6..15eccb6a09 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -266,7 +266,7 @@ struct hb_serialize_context_t
propagate_error (std::forward<Ts> (os)...); }
/* To be called around main operation. */
- template <typename Type>
+ template <typename Type=char>
__attribute__((returns_nonnull))
Type *start_serialize ()
{
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
index f54792648d..462e99cf8c 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
@@ -773,7 +773,7 @@ struct subr_subsetter_t
}
}
- /* Doing this here one by one instead of compacting all at the en
+ /* Doing this here one by one instead of compacting all at the end
* has massive peak-memory saving.
*
* The compacting both saves memory and makes further operations
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.cc b/thirdparty/harfbuzz/src/hb-subset-cff1.cc
index e80d18d097..872cba6672 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff1.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-cff1.cc
@@ -551,14 +551,12 @@ struct cff1_subset_plan
sid = sidmap.add (sid);
if (sid != last_sid + 1)
- {
subset_charset_ranges.push (code_pair_t {sid, glyph});
- if (glyph == old_glyph && skip)
- {
- glyph = hb_min (_.first - 1, glyph_to_sid_map->arrayZ[old_glyph].glyph);
- sid += glyph - old_glyph;
- }
+ if (glyph == old_glyph && skip)
+ {
+ glyph = hb_min (_.first - 1, glyph_to_sid_map->arrayZ[old_glyph].glyph);
+ sid += glyph - old_glyph;
}
last_sid = sid;
}
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.hh b/thirdparty/harfbuzz/src/hb-subset-cff1.hh
deleted file mode 100644
index aaf5def1ed..0000000000
--- a/thirdparty/harfbuzz/src/hb-subset-cff1.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF1_HH
-#define HB_SUBSET_CFF1_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff1 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF1_HH */
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff2.hh b/thirdparty/harfbuzz/src/hb-subset-cff2.hh
deleted file mode 100644
index f10556ddd7..0000000000
--- a/thirdparty/harfbuzz/src/hb-subset-cff2.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF2_HH
-#define HB_SUBSET_CFF2_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff2 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF2_HH */
diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc
index e6b23df704..93f961f2d8 100644
--- a/thirdparty/harfbuzz/src/hb-subset-input.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-input.cc
@@ -69,7 +69,6 @@ hb_subset_input_t::hb_subset_input_t ()
sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
hb_tag_t default_no_subset_tables[] = {
- HB_TAG ('a', 'v', 'a', 'r'),
HB_TAG ('g', 'a', 's', 'p'),
HB_TAG ('f', 'p', 'g', 'm'),
HB_TAG ('p', 'r', 'e', 'p'),
diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc
index c698d944ce..4cb3f8a485 100644
--- a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc
@@ -253,9 +253,8 @@ _solve (Triple tent, Triple axisLimit, bool negative = false)
* axisDef axisMax
*/
float newUpper = peak + (1 - gain) * (upper - peak);
- // I feel like the first condition is always true because
- // outGain >= gain.
- if (axisMax <= newUpper && newUpper <= axisDef + (axisMax - axisDef) * 2)
+ assert (axisMax <= newUpper); // Because outGain >= gain
+ if (newUpper <= axisDef + (axisMax - axisDef) * 2)
{
upper = newUpper;
if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper)
@@ -362,38 +361,47 @@ _solve (Triple tent, Triple axisLimit, bool negative = false)
return out;
}
-/* Normalizes value based on a min/default/max triple. */
-static inline float normalizeValue (float v, const Triple &triple, bool extrapolate = false)
+static inline TripleDistances _reverse_triple_distances (const TripleDistances &v)
+{ return TripleDistances (v.positive, v.negative); }
+
+float renormalizeValue (float v, const Triple &triple,
+ const TripleDistances &triple_distances, bool extrapolate)
{
- /*
- >>> normalizeValue(400, (100, 400, 900))
- 0.0
- >>> normalizeValue(100, (100, 400, 900))
- -1.0
- >>> normalizeValue(650, (100, 400, 900))
- 0.5
- */
float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
assert (lower <= def && def <= upper);
if (!extrapolate)
v = hb_max (hb_min (v, upper), lower);
- if ((v == def) || (lower == upper))
+ if (v == def)
return 0.f;
- if ((v < def && lower != def) || (v > def && upper == def))
+ if (def < 0.f)
+ return -renormalizeValue (-v, _reverse_negate (triple),
+ _reverse_triple_distances (triple_distances), extrapolate);
+
+ /* default >= 0 and v != default */
+ if (v > def)
+ return (v - def) / (upper - def);
+
+ /* v < def */
+ if (lower >= 0.f)
return (v - def) / (def - lower);
+
+ /* lower < 0 and v < default */
+ float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
+
+ float v_distance;
+ if (v >= 0.f)
+ v_distance = (def - v) * triple_distances.positive;
else
- {
- assert ((v > def && upper != def) ||
- (v < def && lower == def));
- return (v - def) / (upper - def);
- }
+ v_distance = (-v) * triple_distances.negative + triple_distances.positive * def;
+
+ return (-v_distance) /total_distance;
}
result_t
-rebase_tent (Triple tent, Triple axisLimit)
+rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances)
{
assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f);
assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f);
@@ -401,7 +409,7 @@ rebase_tent (Triple tent, Triple axisLimit)
result_t sols = _solve (tent, axisLimit);
- auto n = [&axisLimit] (float v) { return normalizeValue (v, axisLimit, true); };
+ auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
result_t out;
for (auto &p : sols)
diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh
index b1f8594937..563fccbb59 100644
--- a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh
@@ -27,6 +27,21 @@
#include "hb.hh"
+/* pre-normalized distances */
+struct TripleDistances
+{
+ TripleDistances (): negative (1.f), positive (1.f) {}
+ TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {}
+ TripleDistances (float min, float default_, float max)
+ {
+ negative = default_ - min;
+ positive = max - default_;
+ }
+
+ float negative;
+ float positive;
+};
+
struct Triple {
Triple () :
@@ -66,6 +81,7 @@ struct Triple {
return current;
}
+
float minimum;
float middle;
float maximum;
@@ -74,6 +90,12 @@ struct Triple {
using result_item_t = hb_pair_t<float, Triple>;
using result_t = hb_vector_t<result_item_t>;
+/* renormalize a normalized value v to the range of an axis,
+ * considering the prenormalized distances as well as the new axis limits.
+ * Ported from fonttools */
+HB_INTERNAL float renormalizeValue (float v, const Triple &triple,
+ const TripleDistances &triple_distances,
+ bool extrapolate = true);
/* Given a tuple (lower,peak,upper) "tent" and new axis limits
* (axisMin,axisDefault,axisMax), solves how to represent the tent
* under the new axis configuration. All values are in normalized
@@ -85,6 +107,6 @@ using result_t = hb_vector_t<result_item_t>;
* If tent value is Triple{}, that is a special deltaset that should
* be always-enabled (called "gain").
*/
-HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit);
+HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances);
#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh
index be29e67ecb..8e61055f4a 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh
@@ -105,6 +105,8 @@ HB_SUBSET_PLAN_MEMBER (hb_vector_t<int>, normalized_coords)
//user specified axes range map
HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), user_axes_location)
+//axis->TripleDistances map (distances in the pre-normalized space)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, TripleDistances>), axes_triple_distances)
//retained old axis index -> new axis index mapping in fvar axis array
HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map)
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index 9a00de3e60..a2090b727c 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -605,11 +605,14 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
/* Add gids which where requested, but not mapped in cmap */
unsigned num_glyphs = plan->source->get_num_glyphs ();
- for (hb_codepoint_t gid : *glyphs)
+ hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID;
+ for (; glyphs->next_range (&first, &last); )
{
- if (gid >= num_glyphs)
+ if (first >= num_glyphs)
break;
- plan->_glyphset_gsub.add (gid);
+ if (last >= num_glyphs)
+ last = num_glyphs - 1;
+ plan->_glyphset_gsub.add_range (first, last);
}
}
@@ -927,12 +930,14 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
new_axis_idx++;
}
- if (plan->user_axes_location.has (axis_tag))
+ Triple *axis_range;
+ if (plan->user_axes_location.has (axis_tag, &axis_range))
{
- Triple axis_range = plan->user_axes_location.get (axis_tag);
- int normalized_min = axis.normalize_axis_value (axis_range.minimum);
- int normalized_default = axis.normalize_axis_value (axis_range.middle);
- int normalized_max = axis.normalize_axis_value (axis_range.maximum);
+ plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ());
+
+ int normalized_min = axis.normalize_axis_value (axis_range->minimum);
+ int normalized_default = axis.normalize_axis_value (axis_range->middle);
+ int normalized_max = axis.normalize_axis_value (axis_range->maximum);
if (has_avar && old_axis_idx < avar_axis_count)
{
@@ -940,9 +945,9 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
normalized_default = seg_maps->map (normalized_default);
normalized_max = seg_maps->map (normalized_max);
}
- plan->axes_location.set (axis_tag, Triple (static_cast<float> (normalized_min),
- static_cast<float> (normalized_default),
- static_cast<float> (normalized_max)));
+ plan->axes_location.set (axis_tag, Triple (static_cast<float> (normalized_min / 16384.f),
+ static_cast<float> (normalized_default / 16384.f),
+ static_cast<float> (normalized_max / 16384.f)));
if (normalized_default != 0)
plan->pinned_at_default = false;
diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc
index 8e8a5eb0bd..1f97dbed29 100644
--- a/thirdparty/harfbuzz/src/hb-subset.cc
+++ b/thirdparty/harfbuzz/src/hb-subset.cc
@@ -50,6 +50,7 @@
#include "hb-ot-name-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-var-avar-table.hh"
#include "hb-ot-var-cvar-table.hh"
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-var-gvar-table.hh"
@@ -273,7 +274,7 @@ _try_subset (const TableType *table,
hb_vector_t<char>* buf,
hb_subset_context_t* c /* OUT */)
{
- c->serializer->start_serialize<TableType> ();
+ c->serializer->start_serialize ();
if (c->serializer->in_error ()) return false;
bool needed = table->subset (c);
@@ -516,10 +517,11 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_fvar:
if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
return _subset<const OT::fvar> (plan, buf);
+ case HB_OT_TAG_avar:
+ if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+ return _subset<const OT::avar> (plan, buf);
case HB_OT_TAG_STAT:
- /*TODO(qxliu): change the condition as we support more complex
- * instancing operation*/
- if (plan->all_axes_pinned) return _subset<const OT::STAT> (plan, buf);
+ if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf);
else return _passthrough (plan, tag);
case HB_TAG ('c', 'v', 't', ' '):
diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc
index 9648e02663..1b8ac367e1 100644
--- a/thirdparty/harfbuzz/src/hb-uniscribe.cc
+++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc
@@ -699,7 +699,7 @@ retry:
script_tags,
&item_count);
if (unlikely (FAILED (hr)))
- FAIL ("ScriptItemizeOpenType() failed: 0x%08lx", hr);
+ FAIL ("ScriptItemizeOpenType() failed: 0x%08lx", (unsigned long) hr);
#undef MAX_ITEMS
@@ -785,7 +785,7 @@ retry:
}
if (unlikely (FAILED (hr)))
{
- FAIL ("ScriptShapeOpenType() failed: 0x%08lx", hr);
+ FAIL ("ScriptShapeOpenType() failed: 0x%08lx", (unsigned long) hr);
}
for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++)
@@ -811,7 +811,7 @@ retry:
offsets + glyphs_offset,
nullptr);
if (unlikely (FAILED (hr)))
- FAIL ("ScriptPlaceOpenType() failed: 0x%08lx", hr);
+ FAIL ("ScriptPlaceOpenType() failed: 0x%08lx", (unsigned long) hr);
if (DEBUG_ENABLED (UNISCRIBE))
fprintf (stderr, "Item %d RTL %d LayoutRTL %d LogicalOrder %d ScriptTag %c%c%c%c\n",
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index 9b27acf598..773395fb25 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 0
+#define HB_VERSION_MINOR 1
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MICRO 1
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "8.0.0"
+#define HB_VERSION_STRING "8.1.1"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh
index 49119b8f82..972608d6a3 100644
--- a/thirdparty/harfbuzz/src/hb.hh
+++ b/thirdparty/harfbuzz/src/hb.hh
@@ -64,6 +64,7 @@
#pragma GCC diagnostic error "-Wbitwise-instead-of-logical"
#pragma GCC diagnostic error "-Wcast-align"
#pragma GCC diagnostic error "-Wcast-function-type"
+#pragma GCC diagnostic error "-Wconstant-conversion"
#pragma GCC diagnostic error "-Wcomma"
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"
#pragma GCC diagnostic error "-Wembedded-directive"
diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h
index 6741dead05..6c545bd4a3 100644
--- a/thirdparty/mbedtls/include/mbedtls/aesni.h
+++ b/thirdparty/mbedtls/include/mbedtls/aesni.h
@@ -54,9 +54,10 @@
* macros that may change in future releases.
*/
#undef MBEDTLS_AESNI_HAVE_INTRINSICS
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
- * VS 2013 and up for other reasons anyway, so no need to check the version. */
+ * VS 2013 and up for other reasons anyway, so no need to check the version.
+ * Only supported on x64 and x86. */
#define MBEDTLS_AESNI_HAVE_INTRINSICS
#endif
/* GCC-like compilers: currently, we only support intrinsics if the requisite
diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c
index 57fddd4d62..3420616a06 100644
--- a/thirdparty/mbedtls/library/entropy_poll.c
+++ b/thirdparty/mbedtls/library/entropy_poll.c
@@ -55,41 +55,26 @@
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h>
-#include <bcrypt.h>
-#if defined(_MSC_VER) && _MSC_VER <= 1600
-/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and
- * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants.
- * These constants are guaranteed to be the same, though, so we suppress the
- * warning when including intsafe.h.
- */
-#pragma warning( push )
-#pragma warning( disable : 4005 )
-#endif
-#include <intsafe.h>
-#if defined(_MSC_VER) && _MSC_VER <= 1600
-#pragma warning( pop )
-#endif
+#include <wincrypt.h>
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
size_t *olen)
{
- ULONG len_as_ulong = 0;
+ HCRYPTPROV provider;
((void) data);
*olen = 0;
- /*
- * BCryptGenRandom takes ULONG for size, which is smaller than size_t on
- * 64-bit Windows platforms. Ensure len's value can be safely converted into
- * a ULONG.
- */
- if (FAILED(SizeTToULong(len, &len_as_ulong))) {
+ if (CryptAcquireContext(&provider, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
}
- if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, len_as_ulong, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
+ if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) {
+ CryptReleaseContext(provider, 0);
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
}
+ CryptReleaseContext(provider, 0);
*olen = len;
return 0;
diff --git a/thirdparty/mbedtls/patches/1453.diff b/thirdparty/mbedtls/patches/1453.diff
deleted file mode 100644
index a29a928dd3..0000000000
--- a/thirdparty/mbedtls/patches/1453.diff
+++ /dev/null
@@ -1,53 +0,0 @@
-diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c
-index 3420616a06..57fddd4d62 100644
---- a/thirdparty/mbedtls/library/entropy_poll.c
-+++ b/thirdparty/mbedtls/library/entropy_poll.c
-@@ -55,26 +55,41 @@
- #define _WIN32_WINNT 0x0400
- #endif
- #include <windows.h>
--#include <wincrypt.h>
-+#include <bcrypt.h>
-+#if defined(_MSC_VER) && _MSC_VER <= 1600
-+/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and
-+ * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants.
-+ * These constants are guaranteed to be the same, though, so we suppress the
-+ * warning when including intsafe.h.
-+ */
-+#pragma warning( push )
-+#pragma warning( disable : 4005 )
-+#endif
-+#include <intsafe.h>
-+#if defined(_MSC_VER) && _MSC_VER <= 1600
-+#pragma warning( pop )
-+#endif
-
- int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
- size_t *olen)
- {
-- HCRYPTPROV provider;
-+ ULONG len_as_ulong = 0;
- ((void) data);
- *olen = 0;
-
-- if (CryptAcquireContext(&provider, NULL, NULL,
-- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
-+ /*
-+ * BCryptGenRandom takes ULONG for size, which is smaller than size_t on
-+ * 64-bit Windows platforms. Ensure len's value can be safely converted into
-+ * a ULONG.
-+ */
-+ if (FAILED(SizeTToULong(len, &len_as_ulong))) {
- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
- }
-
-- if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) {
-- CryptReleaseContext(provider, 0);
-+ if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, len_as_ulong, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
- }
-
-- CryptReleaseContext(provider, 0);
- *olen = len;
-
- return 0;
diff --git a/thirdparty/mbedtls/patches/aesni-no-arm-intrinsics.patch b/thirdparty/mbedtls/patches/aesni-no-arm-intrinsics.patch
new file mode 100644
index 0000000000..7edfa072d8
--- /dev/null
+++ b/thirdparty/mbedtls/patches/aesni-no-arm-intrinsics.patch
@@ -0,0 +1,17 @@
+diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h
+index 6741dead05..6c545bd4a3 100644
+--- a/thirdparty/mbedtls/include/mbedtls/aesni.h
++++ b/thirdparty/mbedtls/include/mbedtls/aesni.h
+@@ -54,9 +54,10 @@
+ * macros that may change in future releases.
+ */
+ #undef MBEDTLS_AESNI_HAVE_INTRINSICS
+-#if defined(_MSC_VER)
++#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
+ /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
+- * VS 2013 and up for other reasons anyway, so no need to check the version. */
++ * VS 2013 and up for other reasons anyway, so no need to check the version.
++ * Only supported on x64 and x86. */
+ #define MBEDTLS_AESNI_HAVE_INTRINSICS
+ #endif
+ /* GCC-like compilers: currently, we only support intrinsics if the requisite