summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/linux_builds.yml8
-rw-r--r--CHANGELOG.md422
-rw-r--r--DONORS.md2
-rw-r--r--SConstruct7
-rw-r--r--core/config/project_settings.cpp77
-rw-r--r--core/config/project_settings.h1
-rw-r--r--core/core_bind.cpp13
-rw-r--r--core/core_bind.h1
-rw-r--r--core/core_constants.cpp43
-rw-r--r--core/debugger/local_debugger.cpp2
-rw-r--r--core/doc_data.cpp4
-rw-r--r--core/doc_data.h38
-rw-r--r--core/error/error_macros.cpp2
-rw-r--r--core/extension/extension_api_dump.cpp4
-rw-r--r--core/extension/gdnative_interface.cpp30
-rw-r--r--core/extension/gdnative_interface.h10
-rw-r--r--core/extension/native_extension.cpp3
-rw-r--r--core/extension/native_extension_manager.cpp2
-rw-r--r--core/input/input.cpp9
-rw-r--r--core/input/input_event.cpp10
-rw-r--r--core/input/input_map.cpp6
-rw-r--r--core/io/config_file.cpp6
-rw-r--r--core/io/dir_access.cpp8
-rw-r--r--core/io/file_access.cpp4
-rw-r--r--core/io/file_access_pack.cpp2
-rw-r--r--core/io/http_client.cpp11
-rw-r--r--core/io/http_client.h4
-rw-r--r--core/io/http_client_tcp.cpp93
-rw-r--r--core/io/http_client_tcp.h11
-rw-r--r--core/io/logger.cpp6
-rw-r--r--core/io/marshalls.cpp2
-rw-r--r--core/io/resource.cpp8
-rw-r--r--core/io/resource_format_binary.cpp12
-rw-r--r--core/io/resource_importer.cpp14
-rw-r--r--core/io/resource_loader.cpp16
-rw-r--r--core/io/translation_loader_po.cpp16
-rw-r--r--core/math/a_star.cpp10
-rw-r--r--core/math/a_star.h4
-rw-r--r--core/math/aabb.cpp20
-rw-r--r--core/math/aabb.h30
-rw-r--r--core/math/audio_frame.h3
-rw-r--r--core/math/bvh_split.inc4
-rw-r--r--core/math/convex_hull.cpp14
-rw-r--r--core/math/expression.cpp8
-rw-r--r--core/math/math_defs.h45
-rw-r--r--core/math/quaternion.h3
-rw-r--r--core/math/rect2.cpp10
-rw-r--r--core/math/rect2.h82
-rw-r--r--core/math/vector2.h16
-rw-r--r--core/math/vector3.cpp8
-rw-r--r--core/math/vector3.h26
-rw-r--r--core/math/vector3i.cpp8
-rw-r--r--core/math/vector3i.h4
-rw-r--r--core/multiplayer/multiplayer_replicator.cpp2
-rw-r--r--core/object/class_db.cpp50
-rw-r--r--core/object/class_db.h3
-rw-r--r--core/object/make_virtuals.py11
-rw-r--r--core/object/object.cpp8
-rw-r--r--core/object/object.h3
-rw-r--r--core/object/script_language.cpp2
-rw-r--r--core/os/os.cpp6
-rw-r--r--core/string/node_path.cpp2
-rw-r--r--core/string/string_builder.cpp2
-rw-r--r--core/string/string_name.cpp4
-rw-r--r--core/string/translation.cpp2
-rw-r--r--core/string/ustring.cpp12
-rw-r--r--core/string/ustring.h20
-rw-r--r--core/templates/local_vector.h6
-rw-r--r--core/templates/oa_hash_map.h3
-rw-r--r--core/templates/ordered_hash_map.h6
-rw-r--r--core/templates/vector.h36
-rw-r--r--core/templates/vmap.h3
-rw-r--r--core/variant/array.cpp57
-rw-r--r--core/variant/array.h2
-rw-r--r--core/variant/binder_common.h9
-rw-r--r--core/variant/variant_call.cpp38
-rw-r--r--core/variant/variant_internal.h10
-rw-r--r--core/variant/variant_parser.cpp4
-rw-r--r--doc/classes/@GlobalScope.xml61
-rw-r--r--doc/classes/AABB.xml6
-rw-r--r--doc/classes/AStar.xml12
-rw-r--r--doc/classes/AStar2D.xml12
-rw-r--r--doc/classes/AcceptDialog.xml10
-rw-r--r--doc/classes/AnimationNodeStateMachinePlayback.xml2
-rw-r--r--doc/classes/Array.xml5
-rw-r--r--doc/classes/AspectRatioContainer.xml10
-rw-r--r--doc/classes/BaseButton.xml2
-rw-r--r--doc/classes/BaseMaterial3D.xml3
-rw-r--r--doc/classes/BoxContainer.xml13
-rw-r--r--doc/classes/Button.xml59
-rw-r--r--doc/classes/ButtonGroup.xml2
-rw-r--r--doc/classes/Camera2D.xml10
-rw-r--r--doc/classes/Camera3D.xml4
-rw-r--r--doc/classes/CanvasItem.xml8
-rw-r--r--doc/classes/CheckBox.xml66
-rw-r--r--doc/classes/CheckButton.xml52
-rw-r--r--doc/classes/CodeEdit.xml108
-rw-r--r--doc/classes/ColorPicker.xml28
-rw-r--r--doc/classes/ColorPickerButton.xml38
-rw-r--r--doc/classes/ConfirmationDialog.xml6
-rw-r--r--doc/classes/Container.xml2
-rw-r--r--doc/classes/Control.xml12
-rw-r--r--doc/classes/DirectionalLight3D.xml2
-rw-r--r--doc/classes/EditorCommandPalette.xml2
-rw-r--r--doc/classes/EditorFileDialog.xml4
-rw-r--r--doc/classes/EditorInspector.xml2
-rw-r--r--doc/classes/EditorInterface.xml12
-rw-r--r--doc/classes/EditorNode3DGizmo.xml2
-rw-r--r--doc/classes/EditorSpinSlider.xml2
-rw-r--r--doc/classes/Engine.xml5
-rw-r--r--doc/classes/File.xml1
-rw-r--r--doc/classes/FileDialog.xml22
-rw-r--r--doc/classes/Font.xml6
-rw-r--r--doc/classes/GPUParticlesAttractorBox3D.xml (renamed from doc/classes/GPUParticlesAttractorBox.xml)2
-rw-r--r--doc/classes/GPUParticlesAttractorSphere3D.xml (renamed from doc/classes/GPUParticlesAttractorSphere.xml)2
-rw-r--r--doc/classes/GPUParticlesAttractorVectorField3D.xml (renamed from doc/classes/GPUParticlesAttractorVectorField.xml)2
-rw-r--r--doc/classes/GPUParticlesCollisionBox3D.xml (renamed from doc/classes/GPUParticlesCollisionBox.xml)2
-rw-r--r--doc/classes/GPUParticlesCollisionHeightField3D.xml (renamed from doc/classes/GPUParticlesCollisionHeightField.xml)6
-rw-r--r--doc/classes/GPUParticlesCollisionSDF3D.xml (renamed from doc/classes/GPUParticlesCollisionSDF.xml)4
-rw-r--r--doc/classes/GPUParticlesCollisionSphere3D.xml (renamed from doc/classes/GPUParticlesCollisionSphere.xml)2
-rw-r--r--doc/classes/GraphEdit.xml42
-rw-r--r--doc/classes/GraphNode.xml62
-rw-r--r--doc/classes/HScrollBar.xml18
-rw-r--r--doc/classes/HSlider.xml16
-rw-r--r--doc/classes/HSplitContainer.xml6
-rw-r--r--doc/classes/HTTPClient.xml18
-rw-r--r--doc/classes/Image.xml2
-rw-r--r--doc/classes/Input.xml11
-rw-r--r--doc/classes/InputEventScreenTouch.xml2
-rw-r--r--doc/classes/ItemList.xml48
-rw-r--r--doc/classes/Label.xml56
-rw-r--r--doc/classes/Line2D.xml2
-rw-r--r--doc/classes/LineEdit.xml56
-rw-r--r--doc/classes/LinkButton.xml22
-rw-r--r--doc/classes/MenuButton.xml40
-rw-r--r--doc/classes/NinePatchRect.xml2
-rw-r--r--doc/classes/Node.xml10
-rw-r--r--doc/classes/OS.xml9
-rw-r--r--doc/classes/OptionButton.xml54
-rw-r--r--doc/classes/PackedByteArray.xml17
-rw-r--r--doc/classes/PackedColorArray.xml14
-rw-r--r--doc/classes/PackedFloat32Array.xml14
-rw-r--r--doc/classes/PackedFloat64Array.xml14
-rw-r--r--doc/classes/PackedInt32Array.xml14
-rw-r--r--doc/classes/PackedInt64Array.xml14
-rw-r--r--doc/classes/PackedStringArray.xml14
-rw-r--r--doc/classes/PackedVector2Array.xml14
-rw-r--r--doc/classes/PackedVector3Array.xml14
-rw-r--r--doc/classes/PanelContainer.xml2
-rw-r--r--doc/classes/ParallaxBackground.xml2
-rw-r--r--doc/classes/ParticlesMaterial.xml7
-rw-r--r--doc/classes/PhysicsBody2D.xml2
-rw-r--r--doc/classes/PhysicsServer2D.xml23
-rw-r--r--doc/classes/PhysicsServer3D.xml34
-rw-r--r--doc/classes/Popup.xml10
-rw-r--r--doc/classes/PopupMenu.xml190
-rw-r--r--doc/classes/ProgressBar.xml26
-rw-r--r--doc/classes/ProjectSettings.xml8
-rw-r--r--doc/classes/ProximityGroup3D.xml42
-rw-r--r--doc/classes/Rect2.xml1
-rw-r--r--doc/classes/Rect2i.xml1
-rw-r--r--doc/classes/RichTextLabel.xml112
-rw-r--r--doc/classes/SceneTreeTimer.xml3
-rw-r--r--doc/classes/ScriptCreateDialog.xml4
-rw-r--r--doc/classes/ScrollBar.xml4
-rw-r--r--doc/classes/ScrollContainer.xml36
-rw-r--r--doc/classes/SkeletonModification3DTwoBoneIK.xml2
-rw-r--r--doc/classes/Slider.xml4
-rw-r--r--doc/classes/SpinBox.xml7
-rw-r--r--doc/classes/SpotLight3D.xml2
-rw-r--r--doc/classes/Sprite3D.xml5
-rw-r--r--doc/classes/SpriteBase3D.xml3
-rw-r--r--doc/classes/TabBar.xml61
-rw-r--r--doc/classes/TabContainer.xml51
-rw-r--r--doc/classes/TextEdit.xml57
-rw-r--r--doc/classes/TextLine.xml7
-rw-r--r--doc/classes/TextParagraph.xml6
-rw-r--r--doc/classes/TextServer.xml4
-rw-r--r--doc/classes/TextServerExtension.xml4
-rw-r--r--doc/classes/TextureProgressBar.xml2
-rw-r--r--doc/classes/TextureRect.xml2
-rw-r--r--doc/classes/Transform2D.xml12
-rw-r--r--doc/classes/Transform3D.xml14
-rw-r--r--doc/classes/TranslationServer.xml2
-rw-r--r--doc/classes/Tree.xml176
-rw-r--r--doc/classes/TreeItem.xml19
-rw-r--r--doc/classes/VScrollBar.xml22
-rw-r--r--doc/classes/VSlider.xml20
-rw-r--r--doc/classes/VSplitContainer.xml6
-rw-r--r--doc/classes/Vector2.xml38
-rw-r--r--doc/classes/Vector2i.xml16
-rw-r--r--doc/classes/Vector3.xml54
-rw-r--r--doc/classes/Vector3i.xml14
-rw-r--r--doc/classes/VehicleBody3D.xml2
-rw-r--r--doc/classes/VideoStream.xml2
-rw-r--r--doc/classes/VideoStreamPlayer.xml (renamed from doc/classes/VideoPlayer.xml)4
-rw-r--r--doc/classes/Viewport.xml4
-rw-r--r--doc/classes/ViewportTexture.xml2
-rw-r--r--doc/classes/VisualShaderNodeIntFunc.xml5
-rw-r--r--doc/classes/VisualShaderNodeIntOp.xml17
-rw-r--r--doc/classes/VoxelGIData.xml12
-rw-r--r--doc/classes/Window.xml22
-rw-r--r--doc/classes/float.xml18
-rw-r--r--doc/classes/int.xml28
-rwxr-xr-xdoc/tools/make_rst.py19
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp12
-rw-r--r--drivers/gles3/shader_gles3.cpp58
-rw-r--r--drivers/unix/dir_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.cpp5
-rw-r--r--drivers/unix/os_unix.cpp6
-rw-r--r--drivers/unix/os_unix.h2
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp4
-rw-r--r--drivers/windows/dir_access_windows.cpp6
-rw-r--r--drivers/windows/file_access_windows.cpp7
-rw-r--r--editor/action_map_editor.cpp8
-rw-r--r--editor/animation_bezier_editor.cpp8
-rw-r--r--editor/animation_track_editor.cpp114
-rw-r--r--editor/animation_track_editor.h2
-rw-r--r--editor/animation_track_editor_plugins.cpp4
-rw-r--r--editor/audio_stream_preview.h3
-rw-r--r--editor/code_editor.cpp14
-rw-r--r--editor/connections_dialog.cpp16
-rw-r--r--editor/create_dialog.cpp12
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.cpp41
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp11
-rw-r--r--editor/debugger/editor_debugger_node.cpp7
-rw-r--r--editor/debugger/editor_debugger_node.h3
-rw-r--r--editor/debugger/editor_debugger_server.cpp48
-rw-r--r--editor/debugger/editor_debugger_server.h4
-rw-r--r--editor/debugger/editor_debugger_tree.cpp2
-rw-r--r--editor/debugger/editor_network_profiler.cpp6
-rw-r--r--editor/debugger/editor_performance_profiler.cpp14
-rw-r--r--editor/debugger/editor_profiler.cpp2
-rw-r--r--editor/debugger/editor_visual_profiler.cpp8
-rw-r--r--editor/debugger/script_editor_debugger.cpp24
-rw-r--r--editor/dependency_editor.cpp7
-rw-r--r--editor/doc_tools.cpp64
-rw-r--r--editor/editor_about.cpp2
-rw-r--r--editor/editor_asset_installer.cpp6
-rw-r--r--editor/editor_audio_buses.cpp15
-rw-r--r--editor/editor_audio_buses.h3
-rw-r--r--editor/editor_autoload_settings.cpp10
-rw-r--r--editor/editor_command_palette.cpp4
-rw-r--r--editor/editor_data.cpp25
-rw-r--r--editor/editor_dir_dialog.cpp2
-rw-r--r--editor/editor_export.cpp27
-rw-r--r--editor/editor_feature_profile.cpp36
-rw-r--r--editor/editor_file_dialog.cpp14
-rw-r--r--editor/editor_file_system.cpp52
-rw-r--r--editor/editor_folding.cpp12
-rw-r--r--editor/editor_fonts.cpp6
-rw-r--r--editor/editor_help.cpp202
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/editor_help_search.cpp10
-rw-r--r--editor/editor_inspector.cpp54
-rw-r--r--editor/editor_layouts_dialog.cpp2
-rw-r--r--editor/editor_log.cpp6
-rw-r--r--editor/editor_node.cpp94
-rw-r--r--editor/editor_path.cpp6
-rw-r--r--editor/editor_paths.cpp2
-rw-r--r--editor/editor_plugin.cpp7
-rw-r--r--editor/editor_plugin.h1
-rw-r--r--editor/editor_plugin_settings.cpp2
-rw-r--r--editor/editor_properties.cpp27
-rw-r--r--editor/editor_properties_array_dict.cpp2
-rw-r--r--editor/editor_resource_picker.cpp10
-rw-r--r--editor/editor_resource_preview.cpp2
-rw-r--r--editor/editor_run.cpp34
-rw-r--r--editor/editor_run.h2
-rw-r--r--editor/editor_sectioned_inspector.cpp6
-rw-r--r--editor/editor_settings.cpp16
-rw-r--r--editor/editor_spin_slider.cpp10
-rw-r--r--editor/editor_themes.cpp2
-rw-r--r--editor/editor_zoom_widget.cpp2
-rw-r--r--editor/export_template_manager.cpp10
-rw-r--r--editor/fileserver/editor_file_server.cpp2
-rw-r--r--editor/filesystem_dock.cpp51
-rw-r--r--editor/filesystem_dock.h2
-rw-r--r--editor/find_in_files.cpp4
-rw-r--r--editor/groups_editor.cpp6
-rw-r--r--editor/icons/GPUParticlesAttractorBox3D.svg (renamed from editor/icons/GPUParticlesAttractorBox.svg)0
-rw-r--r--editor/icons/GPUParticlesAttractorSphere3D.svg (renamed from editor/icons/GPUParticlesAttractorSphere.svg)0
-rw-r--r--editor/icons/GPUParticlesAttractorVectorField3D.svg (renamed from editor/icons/GPUParticlesAttractorVectorField.svg)0
-rw-r--r--editor/icons/GPUParticlesCollisionBox3D.svg (renamed from editor/icons/GPUParticlesCollisionBox.svg)0
-rw-r--r--editor/icons/GPUParticlesCollisionHeightField3D.svg (renamed from editor/icons/GPUParticlesCollisionHeightField.svg)0
-rw-r--r--editor/icons/GPUParticlesCollisionSDF3D.svg (renamed from editor/icons/GPUParticlesCollisionSDF.svg)0
-rw-r--r--editor/icons/GPUParticlesCollisionSphere3D.svg (renamed from editor/icons/GPUParticlesCollisionSphere.svg)0
-rw-r--r--editor/icons/ProximityGroup3D.svg1
-rw-r--r--editor/import/collada.cpp26
-rw-r--r--editor/import/dynamicfont_import_settings.cpp26
-rw-r--r--editor/import/editor_import_collada.cpp50
-rw-r--r--editor/import/resource_importer_csv_translation.cpp2
-rw-r--r--editor/import/resource_importer_obj.cpp8
-rw-r--r--editor/import/resource_importer_scene.cpp14
-rw-r--r--editor/import/scene_import_settings.cpp6
-rw-r--r--editor/import_dock.cpp2
-rw-r--r--editor/inspector_dock.cpp4
-rw-r--r--editor/localization_editor.cpp8
-rw-r--r--editor/multi_node_edit.cpp2
-rw-r--r--editor/node_dock.cpp4
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp2
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp7
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp9
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp29
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp29
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp17
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp27
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp69
-rw-r--r--editor/plugins/curve_editor_plugin.cpp24
-rw-r--r--editor/plugins/editor_preview_plugins.cpp4
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.h2
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp88
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.h13
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp4
-rw-r--r--editor/plugins/material_editor_plugin.cpp51
-rw-r--r--editor/plugins/material_editor_plugin.h28
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp31
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h4
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp57
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/ot_features_plugin.cpp1
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp2
-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.cpp26
-rw-r--r--editor/plugins/script_text_editor.cpp28
-rw-r--r--editor/plugins/shader_editor_plugin.cpp18
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp10
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/text_editor.cpp4
-rw-r--r--editor/plugins/theme_editor_plugin.cpp24
-rw-r--r--editor/plugins/theme_editor_preview.cpp14
-rw-r--r--editor/plugins/theme_editor_preview.h1
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp4
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp4
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp8
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp19
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp12
-rw-r--r--editor/plugins/tiles/tile_set_editor.cpp6
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp6
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp14
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp60
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp47
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.h1
-rw-r--r--editor/project_export.cpp16
-rw-r--r--editor/project_manager.cpp136
-rw-r--r--editor/project_settings_editor.cpp16
-rw-r--r--editor/property_editor.cpp16
-rw-r--r--editor/property_selector.cpp20
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/rename_dialog.cpp2
-rw-r--r--editor/scene_tree_dock.cpp34
-rw-r--r--editor/scene_tree_editor.cpp16
-rw-r--r--editor/script_create_dialog.cpp18
-rw-r--r--editor/settings_config_dialog.cpp6
-rw-r--r--editor/shader_create_dialog.cpp21
-rw-r--r--editor/shader_create_dialog.h2
-rw-r--r--editor/shader_globals_editor.cpp2
-rw-r--r--gles3_builders.py70
-rw-r--r--main/SCsub13
-rw-r--r--main/main.cpp58
-rw-r--r--main/splash_editor.pngbin37471 -> 0 bytes
-rw-r--r--modules/bullet/godot_result_callbacks.cpp48
-rw-r--r--modules/bullet/godot_result_callbacks.h6
-rw-r--r--modules/fbx/data/fbx_material.cpp8
-rw-r--r--modules/fbx/fbx_parser/FBXMeshGeometry.cpp2
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp4
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp2
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp7
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp6
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml4
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp6
-rw-r--r--modules/gdscript/gdscript.cpp22
-rw-r--r--modules/gdscript/gdscript_cache.cpp16
-rw-r--r--modules/gdscript/gdscript_compiler.cpp8
-rw-r--r--modules/gdscript/gdscript_editor.cpp4
-rw-r--r--modules/gdscript/gdscript_function.h3
-rw-r--r--modules/gdscript/gdscript_parser.cpp12
-rw-r--r--modules/gdscript/gdscript_parser.h3
-rw-r--r--modules/gdscript/gdscript_vm.cpp20
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.h2
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp3
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp6
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp2
-rw-r--r--modules/glslang/register_types.cpp2
-rw-r--r--modules/gltf/gltf_animation.h4
-rw-r--r--modules/gltf/gltf_document.cpp24
-rw-r--r--modules/gltf/gltf_document.h2
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp10
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp2
-rw-r--r--modules/minimp3/audio_stream_mp3.cpp32
-rw-r--r--modules/minimp3/audio_stream_mp3.h2
-rw-r--r--modules/mobile_vr/doc_classes/MobileVRInterface.xml2
-rw-r--r--modules/mono/SdkPackageVersions.props5
-rw-r--r--modules/mono/csharp_script.cpp6
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs16
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs19
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs8
-rw-r--r--modules/mono/editor/bindings_generator.h2
-rw-r--r--modules/mono/editor/code_completion.cpp2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs164
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs13
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs32
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs46
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs72
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs38
-rw-r--r--modules/mono/godotsharp_dirs.cpp3
-rw-r--r--modules/mono/mono_gc_handle.h3
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp11
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp11
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h2
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp62
-rw-r--r--modules/navigation/navigation_mesh_generator.h8
-rw-r--r--modules/text_server_adv/text_server_adv.cpp126
-rw-r--r--modules/text_server_adv/text_server_adv.h4
-rw-r--r--modules/text_server_fb/text_server_fb.cpp112
-rw-r--r--modules/text_server_fb/text_server_fb.h4
-rw-r--r--modules/visual_script/editor/visual_script_editor.cpp42
-rw-r--r--modules/visual_script/editor/visual_script_property_selector.cpp16
-rw-r--r--modules/visual_script/visual_script.cpp8
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp8
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp26
-rw-r--r--modules/visual_script/visual_script_nodes.cpp16
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp2
-rw-r--r--modules/websocket/editor_debugger_server_websocket.cpp34
-rw-r--r--modules/websocket/editor_debugger_server_websocket.h14
-rw-r--r--modules/websocket/wsl_server.cpp6
-rw-r--r--platform/android/dir_access_jandroid.cpp8
-rw-r--r--platform/android/export/export_plugin.cpp89
-rw-r--r--platform/android/export/gradle_export_util.cpp19
-rw-r--r--platform/android/export/gradle_export_util.h4
-rw-r--r--platform/android/java/app/AndroidManifest.xml8
-rw-r--r--platform/android/java/app/build.gradle4
-rw-r--r--platform/android/java/app/config.gradle28
-rw-r--r--platform/android/os_android.cpp14
-rw-r--r--platform/iphone/export/export_plugin.cpp11
-rw-r--r--platform/javascript/SCsub6
-rw-r--r--platform/javascript/export/export_plugin.cpp6
-rw-r--r--platform/javascript/js/libs/library_godot_input.js16
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp8
-rw-r--r--platform/osx/export/export_plugin.cpp14
-rw-r--r--platform/osx/os_osx.mm2
-rw-r--r--platform/uwp/export/export_plugin.cpp8
-rw-r--r--platform/windows/display_server_windows.cpp2
-rw-r--r--platform/windows/export/export_plugin.cpp30
-rw-r--r--platform/windows/os_windows.cpp20
-rw-r--r--platform/windows/windows_terminal_logger.cpp2
-rw-r--r--platform/windows/windows_terminal_logger.h4
-rw-r--r--scene/2d/animated_sprite_2d.cpp4
-rw-r--r--scene/2d/camera_2d.cpp2
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/gpu_particles_2d.cpp12
-rw-r--r--scene/2d/gpu_particles_2d.h9
-rw-r--r--scene/2d/path_2d.cpp14
-rw-r--r--scene/2d/path_2d.h1
-rw-r--r--scene/3d/audio_stream_player_3d.cpp6
-rw-r--r--scene/3d/cpu_particles_3d.cpp26
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp200
-rw-r--r--scene/3d/gpu_particles_collision_3d.h62
-rw-r--r--scene/3d/lightmap_gi.cpp2
-rw-r--r--scene/3d/occluder_instance_3d.cpp2
-rw-r--r--scene/3d/proximity_group_3d.cpp182
-rw-r--r--scene/3d/proximity_group_3d.h85
-rw-r--r--scene/3d/skeleton_3d.cpp2
-rw-r--r--scene/3d/soft_dynamic_body_3d.cpp3
-rw-r--r--scene/3d/soft_dynamic_body_3d.h2
-rw-r--r--scene/3d/sprite_3d.cpp6
-rw-r--r--scene/3d/world_environment.cpp4
-rw-r--r--scene/animation/animation_blend_tree.cpp2
-rw-r--r--scene/animation/animation_node_state_machine.cpp2
-rw-r--r--scene/animation/animation_player.cpp12
-rw-r--r--scene/animation/animation_player.h2
-rw-r--r--scene/animation/animation_tree.cpp5
-rw-r--r--scene/debugger/scene_debugger.cpp4
-rw-r--r--scene/gui/aspect_ratio_container.cpp22
-rw-r--r--scene/gui/aspect_ratio_container.h22
-rw-r--r--scene/gui/base_button.cpp2
-rw-r--r--scene/gui/box_container.cpp32
-rw-r--r--scene/gui/box_container.h16
-rw-r--r--scene/gui/button.cpp101
-rw-r--r--scene/gui/button.h21
-rw-r--r--scene/gui/center_container.cpp2
-rw-r--r--scene/gui/check_box.cpp2
-rw-r--r--scene/gui/check_button.cpp2
-rw-r--r--scene/gui/code_edit.cpp43
-rw-r--r--scene/gui/color_picker.cpp2
-rw-r--r--scene/gui/container.cpp8
-rw-r--r--scene/gui/control.cpp16
-rw-r--r--scene/gui/control.h4
-rw-r--r--scene/gui/dialogs.cpp4
-rw-r--r--scene/gui/file_dialog.cpp24
-rw-r--r--scene/gui/graph_edit.cpp4
-rw-r--r--scene/gui/graph_node.cpp6
-rw-r--r--scene/gui/grid_container.cpp4
-rw-r--r--scene/gui/item_list.cpp26
-rw-r--r--scene/gui/label.cpp83
-rw-r--r--scene/gui/label.h28
-rw-r--r--scene/gui/line_edit.cpp109
-rw-r--r--scene/gui/line_edit.h14
-rw-r--r--scene/gui/link_button.cpp8
-rw-r--r--scene/gui/margin_container.cpp2
-rw-r--r--scene/gui/menu_button.cpp2
-rw-r--r--scene/gui/nine_patch_rect.cpp4
-rw-r--r--scene/gui/option_button.cpp2
-rw-r--r--scene/gui/popup_menu.cpp116
-rw-r--r--scene/gui/rich_text_label.cpp145
-rw-r--r--scene/gui/rich_text_label.h24
-rw-r--r--scene/gui/scroll_container.cpp101
-rw-r--r--scene/gui/scroll_container.h35
-rw-r--r--scene/gui/slider.cpp2
-rw-r--r--scene/gui/spin_box.cpp24
-rw-r--r--scene/gui/spin_box.h4
-rw-r--r--scene/gui/split_container.cpp2
-rw-r--r--scene/gui/tab_bar.cpp66
-rw-r--r--scene/gui/tab_bar.h18
-rw-r--r--scene/gui/tab_container.cpp40
-rw-r--r--scene/gui/tab_container.h16
-rw-r--r--scene/gui/text_edit.cpp289
-rw-r--r--scene/gui/text_edit.h13
-rw-r--r--scene/gui/texture_button.cpp10
-rw-r--r--scene/gui/texture_progress_bar.cpp28
-rw-r--r--scene/gui/texture_rect.cpp6
-rw-r--r--scene/gui/tree.cpp58
-rw-r--r--scene/gui/tree.h13
-rw-r--r--scene/gui/video_stream_player.cpp (renamed from scene/gui/video_player.cpp)134
-rw-r--r--scene/gui/video_stream_player.h (renamed from scene/gui/video_player.h)16
-rw-r--r--scene/main/canvas_item.cpp19
-rw-r--r--scene/main/canvas_item.h4
-rw-r--r--scene/main/http_request.cpp4
-rw-r--r--scene/main/node.cpp14
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/main/scene_tree.cpp8
-rw-r--r--scene/main/viewport.cpp28
-rw-r--r--scene/property_utils.cpp2
-rw-r--r--scene/register_scene_types.cpp49
-rw-r--r--scene/register_scene_types.h2
-rw-r--r--scene/resources/animation.cpp5
-rw-r--r--scene/resources/curve.cpp484
-rw-r--r--scene/resources/curve.h120
-rw-r--r--scene/resources/font.cpp24
-rw-r--r--scene/resources/font.h8
-rw-r--r--scene/resources/immediate_mesh.cpp3
-rw-r--r--scene/resources/immediate_mesh.h2
-rw-r--r--scene/resources/importer_mesh.cpp10
-rw-r--r--scene/resources/material.cpp17
-rw-r--r--scene/resources/mesh.cpp6
-rw-r--r--scene/resources/packed_scene.cpp8
-rw-r--r--scene/resources/particles_material.cpp2
-rw-r--r--scene/resources/resource_format_text.cpp28
-rw-r--r--scene/resources/syntax_highlighter.cpp4
-rw-r--r--scene/resources/text_file.cpp2
-rw-r--r--scene/resources/text_line.cpp54
-rw-r--r--scene/resources/text_line.h10
-rw-r--r--scene/resources/text_paragraph.cpp52
-rw-r--r--scene/resources/text_paragraph.h10
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--scene/resources/visual_shader.cpp28
-rw-r--r--scene/resources/visual_shader_nodes.cpp102
-rw-r--r--scene/resources/visual_shader_nodes.h6
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp157
-rw-r--r--scene/resources/visual_shader_particle_nodes.h1
-rw-r--r--scene/resources/visual_shader_sdf_nodes.cpp12
-rw-r--r--scene/scene_string_names.cpp1
-rw-r--r--scene/scene_string_names.h1
-rw-r--r--servers/audio/audio_rb_resampler.cpp2
-rw-r--r--servers/display_server_headless.h16
-rw-r--r--servers/physics_2d/godot_body_2d.cpp3
-rw-r--r--servers/physics_2d/godot_body_2d.h16
-rw-r--r--servers/physics_2d/godot_body_pair_2d.cpp132
-rw-r--r--servers/physics_2d/godot_body_pair_2d.h3
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp21
-rw-r--r--servers/physics_2d/godot_physics_server_2d.h3
-rw-r--r--servers/physics_2d/godot_space_2d.cpp14
-rw-r--r--servers/physics_2d/godot_space_2d.h5
-rw-r--r--servers/physics_2d/godot_step_2d.cpp4
-rw-r--r--servers/physics_2d/godot_step_2d.h2
-rw-r--r--servers/physics_3d/godot_body_3d.cpp3
-rw-r--r--servers/physics_3d/godot_body_3d.h6
-rw-r--r--servers/physics_3d/godot_body_pair_3d.cpp149
-rw-r--r--servers/physics_3d/godot_body_pair_3d.h1
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp21
-rw-r--r--servers/physics_3d/godot_physics_server_3d.h3
-rw-r--r--servers/physics_3d/godot_space_3d.cpp14
-rw-r--r--servers/physics_3d/godot_space_3d.h5
-rw-r--r--servers/physics_3d/godot_step_3d.cpp4
-rw-r--r--servers/physics_3d/godot_step_3d.h2
-rw-r--r--servers/physics_server_2d.cpp6
-rw-r--r--servers/physics_server_2d.h9
-rw-r--r--servers/physics_server_2d_wrap_mt.h1
-rw-r--r--servers/physics_server_3d.cpp6
-rw-r--r--servers/physics_server_3d.h9
-rw-r--r--servers/physics_server_3d_wrap_mt.h1
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp2
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp8
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp2
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp23
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp15
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl25
-rw-r--r--servers/rendering/renderer_viewport.cpp6
-rw-r--r--servers/rendering/rendering_device.cpp14
-rw-r--r--servers/rendering/rendering_device_binds.cpp16
-rw-r--r--servers/rendering/rendering_device_binds.h4
-rw-r--r--servers/rendering/shader_language.cpp262
-rw-r--r--servers/rendering/shader_language.h20
-rw-r--r--servers/rendering/shader_types.cpp32
-rw-r--r--servers/rendering/shader_warnings.cpp4
-rw-r--r--servers/rendering/shader_warnings.h2
-rw-r--r--servers/rendering_server.cpp64
-rw-r--r--servers/rendering_server.h57
-rw-r--r--servers/text/text_server_extension.cpp4
-rw-r--r--servers/text/text_server_extension.h8
-rw-r--r--servers/text_server.cpp18
-rw-r--r--servers/text_server.h6
-rw-r--r--tests/core/io/test_file_access.h2
-rw-r--r--tests/core/math/test_aabb.h21
-rw-r--r--tests/core/math/test_math.cpp2
-rw-r--r--tests/core/string/test_string.h26
-rw-r--r--tests/core/templates/test_oa_hash_map.cpp5
-rw-r--r--tests/core/templates/test_vector.h44
-rw-r--r--tests/core/variant/test_array.h31
-rw-r--r--tests/scene/test_code_edit.h78
-rw-r--r--tests/scene/test_curve.h26
-rw-r--r--tests/scene/test_gui.cpp2
-rw-r--r--tests/servers/test_shader_lang.cpp9
-rw-r--r--thirdparty/README.md15
-rw-r--r--thirdparty/harfbuzz/src/hb-array.hh24
-rw-r--r--thirdparty/harfbuzz/src/hb-map.hh22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh21
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh31
-rw-r--r--thirdparty/harfbuzz/src/hb-sanitize.hh15
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-set.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc20
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h4
-rw-r--r--thirdparty/minimp3/minimp3.h24
-rw-r--r--thirdparty/minimp3/minimp3_ex.h7
672 files changed, 7595 insertions, 6023 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index 44d0cb041f..c848860bd7 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -29,15 +29,15 @@ jobs:
build-mono: true
artifact: true
- - name: Editor and sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes)
- cache-name: linux-editor-sanitizers
+ - name: Editor with doubles and sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes)
+ cache-name: linux-editor-double-sanitizers
target: debug
tools: true
tests: true
- sconsflags: use_asan=yes use_ubsan=yes
+ sconsflags: float=64 use_asan=yes use_ubsan=yes
proj-test: true
godot-cpp-test: true
- bin: "./bin/godot.linuxbsd.tools.64s"
+ bin: "./bin/godot.linuxbsd.double.tools.64s"
build-mono: false
# Skip 2GiB artifact speeding up action.
artifact: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe5631cefd..d1e622edb4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,428 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+## [4.0] - TBD
+
+### Added
+
+#### Animation
+
+- [Revamped 3D animation storage.](https://godotengine.org/article/animation-data-redesign-40)
+ - [New blend shape track to adjust blend shapes in animations more efficiently.](https://github.com/godotengine/godot/pull/53865)
+ - [New expression-based transitions in AnimationTree state machines.](https://github.com/godotengine/godot/pull/54327)
+ - [Support for animation compression to improve performance with long animations such as cutscenes.](https://github.com/godotengine/godot/pull/54050)
+ - [Replaced transform tracks by position, rotation and scale tracks.](https://github.com/godotengine/godot/pull/53689)
+ - [Removed the animation dependency on bone rests.](https://github.com/godotengine/godot/pull/53765)
+ - Better compatibility with models that use non-uniform scaling in animations.
+ - Better compatibility with models exported from Maya and 3DS Max.
+ - Easier animation reuse across different models.
+ - Easier procedural generation of animations.
+
+#### Core
+
+- New TileMap and TileSet resources.
+- New Vector2i, Vector3i and Rect2i types.
+ - These are integer variants of Vector2, Vector3 and Rect2.
+- Callable type for first-class functions (can be created with lambdas in GDScript).
+- The Euler rotation order can now be adjusted in Node3D.
+- [New `Array.map()`, `Array.filter()` and `Array.reduce()` methods that can be used with Callables.](https://github.com/godotengine/godot/pull/38645)
+- [Rewritten Tween with more functionality](https://github.com/godotengine/godot/pull/41794).
+ - Tween is no longer a node.
+ - Easier chaining of tweens.
+ - Low-level tweening option to get an interpolated value directly.
+ - *Existing projects will have to be modified to account for this, as automatic conversion isn't feasible.*
+- [New and improved IK in Skeleton2D](https://github.com/godotengine/godot/pull/40347).
+ - New classes: SkeletonModifier2D, SkeletonModifierStack2D, SkeletonModification2DLookAt, SkeletonModification2DCCDIK, SkeletonModification2DFABRIK, SkeletonModification2DJiggle, SkeletonModification2DTwoBoneIK, PhysicalBone2D, SkeletonModification2DPhysicalBones, SkeletonModification2DStackHolder.
+ - New `Transform2D.looking_at()` function.
+- [New and improved IK in Skeleton3D](https://github.com/godotengine/godot/pull/39353).
+ - New classes: SkeletonModifier3D, SkeletonModifierStack3D, SkeletonModifier3DLookAt, SkeletonModification3DCCDIK, SkeletonModification3DFABRIK, SkeletonModification3DJiggle, SkeletonModification3DTwoBoneIK, SkeletonModification3DStackHolder.
+ - The Bone struct now includes a local_pose_override.
+ - The Bone struct now keeps track of its children bones, if it has any.
+ - Added functions to Skeleton3D for getting the forward vector using the information stored in the rest pose for the bones.
+ - New `Basis.rotate_to_align()` function.
+ - Refactored the BoneAttachment3D node.
+ - Removed the `process_list` functions.
+- [New GradientTexture2D resource (useful for 2D lights, particles, …)](https://github.com/godotengine/godot/pull/53234).
+- [Support for gettext PO template generation from scene and script files.](https://github.com/godotengine/godot/pull/39415)
+ - Translation parser plugins can be written to allow extracting strings from custom file types.
+- [New Time singleton to replace date/time handling methods in the OS singleton.](https://github.com/godotengine/godot/pull/49123)
+ - Includes new methods to handle ISO 8601 timestamp conversion.
+- [Support for custom performance monitors](https://github.com/godotengine/godot/pull/39302).
+- New `randi_range()` global scope function to return a random *integer* number within a range.
+- New `randfn()` global scope function to return a floating-point number along a normal gaussian distribution.
+- [New `pingpong()` global scope function to return a floating-point number that increments then decrements in a "sawtooth" fashion.](https://github.com/godotengine/godot/pull/46346)
+- Vectors and Colors can now be clamped between two values their respective `clamp()` methods.
+- New `Vector3.limit_length()` method as a Vector3 counterpart to `Vector2.limit_length()` (formerly `Vector2.clamped()`).
+- New PackedArrays to replace PoolArrays.
+ - 64-bit integer and float arrays are now available in addition to the existing 32-bit ones.
+- New `ConfigFile.parse(data: String)` method to load a string as if it was a ConfigFile on disk.
+- New `Image.save_png_to_buffer()` method to save a PNG image to memory as a PackedByteArray (instead of saving to disk).
+- [New File API to check, read and write symbolic links on macOS and Linux.](https://github.com/godotengine/godot/pull/46866)
+- [Replaced GDNative with GDExtension](https://godotengine.org/article/introducing-gd-extensions).
+ - Easier setup and compilation for various platforms.
+ - Code structure is more similar to [statically compiled C++ modules](https://docs.godotengine.org/en/stable/development/cpp/custom_modules_in_cpp.html).
+ - Lower performance overhead compared to GDNative.
+
+#### Editor
+
+- New TileMap and TileSet editors with better usability.
+- Support for multiple windows.
+ - Docks can be moved out of the main window into separate windows.
+ - Single-window mode can be enabled in the Editor Settings to revert to the old behavior.
+- Movement and scaling handles in the 2D editor (similar to the 3D editor).
+- New Replace in Files dialog in the script editor to complement Find in Files.
+- **macOS:** More built-in mouse cursors are now exposed (such as diagonal resize cursors).
+- **macOS:** Support for building Godot with Clang sanitizers.
+- **HTML5:** [Support for profiling projects exported to HTML5.](https://godotengine.org/article/html5-export-profiling)
+
+#### Export
+
+- **macOS:** Projects can now optionally be exported to a application bundle contained within a ZIP archive.
+ - Previously, a DMG image was always used when exporting from macOS.
+- **macOS:** DMG images can now be codesigned after exporting.
+
+#### GDScript
+
+- GDScript was rewritten from scratch with a cleaner approach.
+ - Annotations to replace keywords in certain cases (`@export`, `@onready`, `@rpc()`, `@tool`, `@warning_ignore()`, …).
+ - Typed arrays (`var array_of_nodes: Array[Node]`). Any type can be used, including custom classes.
+ - See individual progress reports for more information:
+ [#1](https://godotengine.org/article/gdscript-progress-report-writing-tokenizer),
+ [#2](https://godotengine.org/article/gdscript-progress-report-writing-new-parser),
+ [#3](https://godotengine.org/article/gdscript-progress-report-type-checking-back).
+- [New documentation generation system](https://github.com/godotengine/godot/pull/41095).
+ - Comments starting with `##` are considered documentation comments.
+ - Documentation comments be placed before any member variable, constant, enum or function declaration, or at the top of a file.
+ - Documentation comments appear in the editor help and when hovering exported properties in the inspector.
+
+#### GUI
+
+- Support for multiple windows on desktop platforms. Projects can spawn additional windows, each with their own viewport.
+ - Added `NOTIFICATION_APPLICATION_FOCUS_IN` and `NOTIFICATION_APPLICATION_FOCUS_OUT` notifications for "global" project focus changes (separate from `NOTIFICATION_WM_FOCUS_IN` and `NOTIFICATION_WM_FOCUS_OUT`).
+- RichTextLabel property `fit_content_height` to make the label's height fit its content automatically (not always reliable).
+- RichTextLabel's `img` tag now supports an optional `color` attribute to modulate the image.
+- `get_char_size()` is now exposed in Font, making it usable in DynamicFont rather than being limited to BitmapFont.
+- [Tree can now highlight relationship lines for the currently selected item, its parents and direct children.](https://github.com/godotengine/godot/pull/48546)
+ - This is used in the scene tree dock in the editor.
+
+#### Import
+
+- Support for importing lights from glTF scenes.
+
+#### Input
+
+- Support for physical (keyboard layout-independent) key codes.
+ - This can be used to provide <kbd>W</kbd>/<kbd>A</kbd>/<kbd>S</kbd>/<kbd>D</kbd> controls that work on any keyboard layout.
+- `DisplayServer.keyboard_get_current_layout()` and `DisplayServer.keyboard_get_layout_*()` methods to get information about keyboard layouts.
+- New `Input.MOUSE_MODE_CONFINED_HIDDEN` mouse mode to combine the confined and hidden mouse modes.
+
+#### Mono/C#
+
+- Support for exporting C# projects to iOS and HTML5.
+- [C# events can now be used to implement Godot signals](https://godotengine.org/article/csharp-ios-signals-events).
+- [New Visual Studio and Visual Studio Code add-ons.](https://godotengine.org/article/csharp-vs-and-vscode)
+
+#### Navigation
+
+- [New NavigationServer.](https://godotengine.org/article/navigation-server-godot-4-0)
+ - Support for dynamic obstacle avoidance.
+
+#### Networking
+
+- [Support for DTLS encryption in UDP and ENet.](https://godotengine.org/article/enet-dtls-encryption)
+
+#### Porting
+
+- New DisplayServer abstraction, allowing for the creation of multiple windows.
+ - This is used in the editor for detachable docks, but can also be used in projects.
+- **Android:** [Allow basic user data backup. This can be disabled in the export preset if needed.](https://github.com/godotengine/godot/pull/49069)
+- **Android:** [Support for changing the mouse cursor shape (no custom images)](https://github.com/godotengine/godot/pull/44201).
+- **iOS:** [The targeted device family (iPhone, iPad, iPhone and iPad) can now be specified in the export preset.](https://github.com/godotengine/godot/pull/49137)
+
+#### Physics
+
+- New CharacterBody node to supersede KinematicBody.
+ - Some KinematicBody features were moved to PhysicsBody.
+
+#### Porting
+
+- **Android:** Clients of the Godot library can now add their own command line arguments.
+
+#### Rendering
+
+- New Vulkan renderer.
+- [New OpenGL renderer, using OpenGL 3.3/OpenGL ES 3.0/WebGL 2.0 as a baseline.](https://github.com/godotengine/godot/pull/53150)
+ - Designed to target mobile/web platforms first, but also usable on desktop platforms.
+ - Uses a low-end-friendly approach to maximize performance in simple scenes.
+ - Currently supports 2D rendering only.
+ - OpenGL 3D rendering is planned for a future 4.x release.
+- Support for specular mapping when using 2D lighting.
+- [New DirectionalLight2D node for 2D lighting.](https://github.com/godotengine/godot/pull/43297)
+- CanvasGroup node to modulate several 2D nodes as a group (or apply shaders to them).
+- Support for clipping in CanvasItem, replacing the use of Light2D as masks in a more convenient manner.
+- [Support for light projectors/"cookies" in OmniLight3D and SpotLight3D.](https://github.com/godotengine/godot/pull/37887)
+ - Only supported for lights with shadows enabled.
+- 3D lights now have a Size property which can be set to simulate area lights.
+ - This property also affects how fast shadow penumbras will grow over distance.
+ - A shadow blur property is also available to set a constant blurring factor on a per-light basis.
+- Shadow mapping with improved filtering and PCSS-like penumbra simulation.
+ - Shadow normal offset bias is now implemented to avoid issues with shadow acne or peter-panning.
+- [New Decal node to project textures onto 3D surfaces.](https://github.com/godotengine/godot/pull/37861)
+- New fully real-time VoxelGI (formerly GIProbe).
+ - Dynamic lights and emissive can emit GI that's updated every frame (instead of only updating sporadically).
+ - Dynamic objects can receive GI and contribute to it.
+- [New signed distance field-based global illumination](https://godotengine.org/article/godot-40-gets-sdf-based-real-time-global-illumination) (SDFGI) for open world lighting.
+ - Enabled in the WorldEnvironment. No node required, no baking.
+ - Semi-realtime: dynamic objects can receive GI, but not contribute to it.
+- [Volumetric fog](https://github.com/godotengine/godot/pull/41213) with optional GI contribution.
+- [Fog volumes to locally apply volumetric fog (or subtract to global fog using negative density).](https://github.com/godotengine/godot/pull/53353)
+- More physically accurate exponential fog to replace the old distance-based fog.
+- New Aerial Scattering property in distance-based fog to fade out to the background sky instead of a fixed color.
+ - Also available in volumetric fog with the Ambient Inject property.
+- [New GPU-based lightmapper.](https://godotengine.org/article/godot-40-will-get-new-modernized-lightmapper)
+ - When using a dedicated GPU, this results in much faster bake speeds compared to the CPU lightmapper.
+ - Optional support for storing directional lighting information and rough reflections using spherical harmonics.
+ - Improved support for lighting dynamic objects with better performance and quality.
+ - In addition to automatic generation, LightmapProbe nodes can now be placed manually to provide better lighting information for dynamic objects where needed.
+- [Physical sky material and custom sky shaders](https://godotengine.org/article/custom-sky-shaders-godot-4-0), both supporting real-time updates.
+- [Global and per-instance shader uniforms.](https://godotengine.org/article/godot-40-gets-global-and-instance-shader-uniforms)
+ - This can be used to better reuse shaders, leading to improved performance.
+- Support for automatically generating and using mesh LODs to improve performance.
+ - Several LOD levels are generated for imported 3D scenes by default.
+ - LODs are automatically used for mesh rendering using a pixel coverage-based selection algorithm.
+ - Uses the [meshoptimizer](https://github.com/zeux/meshoptimizer) library.
+- Support for LOD visibility ranges in GeometryInstance3D.
+ - Manually authored LODs can be configured using distance and hysteresis cutoffs.
+ - Can be used for <abbr title="Hierarchical Level of Detail">HLOD</abbr> setups to reduce draw calls while preserving culling opportunities when up close.
+- [Support for GeometryInstance3D distance fade to make distant meshes disappear smoothly without having to modify their material.](https://github.com/godotengine/godot/pull/54222)
+- Support for automatically generating and using shadow meshes to improve performance.
+ - The generated shadow meshes are welded aggressively to improve performance with no difference in visual quality.
+ - To further improve performance, hand-made shadow meshes can be specified in the inspector in MeshInstance nodes.
+- [Support for rendering a viewport's 3D contents at a lower resolution to improve performance](https://github.com/godotengine/godot/pull/51870).
+ - 2D elements remain at full resolution to improve perceived sharpness.
+ - A scaling factor above 1.0 can be used for supersampling, which is useful to maximize quality for offline rendering.
+- See individual progress reports for more information:
+ [#1](https://godotengine.org/article/vulkan-progress-report-1),
+ [#2](https://godotengine.org/article/vulkan-progress-report-2),
+ [#3](https://godotengine.org/article/vulkan-progress-report-3),
+ [#4](https://godotengine.org/article/vulkan-progress-report-4),
+ [#5](https://godotengine.org/article/vulkan-progress-report-5),
+ [#6](https://godotengine.org/article/vulkan-progress-report-6),
+ [#7](https://godotengine.org/article/vulkan-progress-report-7).
+
+#### Shaders
+
+- New shader compiler rewritten from scratch.
+ - [Support for uniform arrays (including sampler arrays).](https://github.com/godotengine/godot/pull/49485)
+ - [Arrays can now be passed as function parameters (including arrays of structs).](https://github.com/godotengine/godot/pull/48933)
+ - [The return type of a function can now be an array (including arrays of structs).](https://github.com/godotengine/godot/pull/48933)
+ - [Array size can now be optionally written before the identifier (`int[2] array;` instead of `int array[2]`).](https://github.com/godotengine/godot/pull/53527)
+ - This eases porting shaders from GLSL.
+ - [Array constructors can now be called at any time after initialization.](https://github.com/godotengine/godot/pull/44705)
+ - For example, `int array[3]; array = {1, 2, 3}` is now valid.
+ - [New `fma()` (fused multiply-add) built-in function to optimize shaders in a low-level way.](https://github.com/godotengine/godot/pull/36225)
+ - [New built-in data (un)packing functions to optimize shaders in a low-level way.](https://github.com/godotengine/godot/pull/53066)
+ - Warning system for common issues such as floating-point comparison and unused variables.
+ - Argument names now appear in code completion tooltips.
+ - More information in the [progress report](https://godotengine.org/article/improvements-shaders-visual-shaders-godot-4).
+- [Add Billboard mode to visual shaders.](https://github.com/godotengine/godot/pull/49157)
+- [The constants `PI`, `TAU` and `E` are now available in the shader language.](https://github.com/godotengine/godot/pull/48837)
+
+#### Miscellaneous
+
+- The engine is now unit-tested using [doctest](https://github.com/onqtam/doctest).
+ - [GDScript also now has integration tests.](https://docs.godotengine.org/en/latest/development/cpp/unit_testing.html#integration-tests-for-gdscript)
+- Switched from Travis CI and AppVeyor to GitHub Actions.
+- A Fish shell completion file is now available for the Godot editor's command line interface.
+
+### Changed
+
+#### Audio
+
+- [Increased the default AudioStreamPlayer3D unit size to (1 → 10) to make sounds more audible while setting up the node.](https://github.com/godotengine/godot/pull/38224)
+- Renamed the audio-related `FFT_Size` enum to `FFTSize` for consistency.
+
+#### Core
+
+- Tweaked the output strings to be more human-readable when printing various built-in Variant and Object types.
+- Renamed File's `endian_swap` property to `big_endian` for consistency with ResourceSaver and StreamPeer.
+- [Renamed File's `get_len()` method to `get_length()`.](https://github.com/godotengine/godot/pull/49061)
+- [Renamed Object's `PROPERTY_USAGE_NOEDITOR` to `PROPERTY_USAGE_NO_EDITOR`.](https://github.com/godotengine/godot/pull/54571)
+- Renamed `Vector2.clamped()` to `Vector2.limit_length()` to differentiate it from the new `Vector2.clamp()`.
+- Renamed `rand_range()` to `randf_range()` to avoid ambiguity with the new `randi_range()` and make its return type more obvious.
+- Replaced `Node.add_child_below_node()` with `Node.add_sibling()`.
+- Replaced `Directory.list_dir_begin()`'s `skip_navigational` and `skip_hidden` arguments with `show_navigational` and `show_hidden`.
+ - Both arguments are `false` by default, which means the default behavior is now to exclude both navigational and hidden files from the returned list.
+- Renamed the built-in Quat type to Quaternion.
+- Renamed the built-in Transform type to Transform3D.
+- Renamed Node3D's `translation` property to `position` for consistency with Node2D.
+- Moved YSort functionality to a Node2D property.
+- Viewports now use a size of 512×512 by default to make them visible out of the box.
+- [Screen orientation is now represented as an enum in the Project Settings.](https://github.com/godotengine/godot/pull/48939)
+- [Renamed 3D nodes to contain an explicit "3D" prefix for clarity and consistency](https://github.com/godotengine/godot/pull/37340).
+- Renamed various nodes:
+ - Spatial → Node3D
+ - GIProbe → VoxelGI
+ - BakedLightmap → LightmapGI
+ - Light2D -> PointLight2D
+ - VisibilityNotifier2D -> VisibleOnScreenNotifier2D
+ - VisibilityNotifier3D -> VisibleOnScreenNotifier3D
+ - VisibilityEnabler2D -> VisibleOnScreenEnabler2D
+ - VisibilityEnabler3D -> VisibleOnScreenEnabler3D
+- Renamed various resources:
+ - GradientTexture -> GradientTexture1D
+- Old node and resource names are automatically converted when loading scenes from Godot 3.x.
+
+#### Editor
+
+- Renewed the editor theme for a more modern design.
+ - [Increased icon saturation by 30% when using a dark theme.](https://github.com/godotengine/godot/pull/48644)
+ - Icon saturation can now be adjusted in the Editor Settings.
+- [Improved the audio bus editor appearance.](https://github.com/godotengine/godot/pull/49130)
+- Improved layout and texts of the Manage Editor Features dialog.
+- Improved the Video RAM debugger usability.
+ - The Video RAM tab is now refreshed automatically when switching to it.
+- Hovering layer checkboxes in the inspector now results in visual feedback.
+ - Clicking between two checkboxes will now enable the checkbox that was last highlighted instead of doing nothing.
+- CSV profiler measures can now be saved anywhere on the filesystem, not just in the project folder.
+- Improved the 2D zooming algorithm to always visit powers of two (50%, 100%, 200%, …) and avoid floating-point precision issues.
+- Times are now displayed as milliseconds in the profiler and performance monitors (instead of seconds).
+- Improved the batch rename dialog usability and design consistency.
+ - Clarified error messages when there are regular expression errors.
+- Optimized editor icon generation to speed up editor startup.
+- Script editor autocompletion now displays previews next to color constant suggestions.
+- The number of replaced results now appears in place of the matches counter when replacing text in the script editor.
+- Pressing <kbd>Enter</kbd> (or <kbd>Shift + Enter</kbd>) in the script editor replacement dialog now performs a forwards (or backwards) replacement operation.
+- Pressing <kbd>Ctrl + F</kbd> now focuses the search field in the AssetLib tab.
+- Pressing <kbd>G</kbd> now switches to the Pan mode in the 2D editor.
+ - The TileMap editor's Bucket Fill shortcut was moved to <kbd>B</kbd> to cater for this change.
+- Mouse wheel behavior for zooming in the animation behavior is now inverted.
+- The Sync Scene Changes and Sync Script Changes settings' values now persist on a per-project basis instead of being always enabled by default.
+- Various tooltips have been added or modified to clarify the editor operation.
+- Various visual and formatting changes to the editor help to improve readability and be closer to the online class reference.
+- Tweaked Camera2D editor line colors for better visibility.
+- Light theme presets now use a negative contrast rate by default for a more logical preview of UI elevation.
+- Increased the use of bold fonts throughout the editor.
+- Revised icons for the Gradient and GradientTexture resources.
+- Renamed "Identifier" to "Bundle Identifier" in the macOS and iOS export presets for clarity.
+- Renamed the script editor's "Adaptive" syntax theme to "Default" and "Default" to "Godot 2", for consistency with the editor theme presets.
+- Flipped the 2D editor icon to match Godot's coordinate handedness.
+
+#### GUI
+
+- Improved drive letter handling in EditorFileDialog and FileDialog.
+- Container nodes (except PanelContainer) now use the Pass mouse mode by default.
+- Pressing the left/right arrows while having selected text will now move the cursor to the beginning/end of the selection in LineEdit (while unselecting the text as usual).
+- TextEdit's `search()` method now returns a Dictionary instead of a PackedIntArray.
+- **macOS:** The <kbd>Ctrl + A</kbd> and <kbd>Ctrl + E</kbd> navigation shortcuts now work in LineEdit.
+
+#### Input
+
+- Renamed InputEventKey's `scancode` to `keycode`.
+- Renamed InputMap's `get_action_list()` to `get_action_events()`.
+
+#### Networking
+
+- Optimized bandwidth usage in the high-level multiplayer API.
+
+#### Physics
+
+- Split KinematicBody into the new CharacterBody node and PhysicsBody.
+- RayCast nodes are now enabled by default.
+ - The `disabled` property was renamed to `enabled` with its behavior inverted.
+- Renamed PlaneShape to WorldBoundaryShape.
+
+#### Rendering
+
+- Some Environment settings such as depth of field have been moved to a CameraEffects resource which is assigned to individual Camera nodes.
+- [The ACES Fitted tonemapping algoirthm is now used in place of the old ACES algorithm.](https://github.com/godotengine/godot/pull/52476)
+ - The old non-fitted ACES tonemapping algorithm was removed.
+- Quality settings have been moved from individual nodes and resources to the Project Settings for better centralization.
+- Quality settings now have performance hints in their values' names, such as "Fast" or "Slow".
+
+#### Shaders
+
+- Renamed the `.shader` file extension to `.gdshader`.
+ - Existing text-based shader files will have to be renamed before loading the project in a new engine version.
+
+#### Miscellaneous
+
+- Renamed the `x11` platform to `linuxbsd` to prepare for Wayland support.
+- The engine is now written in C++17.
+- Python 3.6 and SCons 3.1 are now required to build Godot from source.
+
+### Removed
+
+#### Buildsystem
+
+- Removed the `server` platform in favor of disabling specific DisplayServers at build-time (e.g. `vulkan=no`).
+
+#### Core
+
+- Removed the YSort node in favor of the Node2D YSort property.
+- Removed the deprecated `Color.gray()` method.
+ - Use `Color.v()` for a better grayscale approximation instead.
+- Removed built-in HQ2X implementation (used for crude hiDPI support in the default project theme).
+ - This helps with binary size as HQ2X is made of particularly large functions.
+
+#### Editor
+
+- Removed the **Dim Dialog on Editor Popup** editor setting since it was made obsolete by the multi-window paradigm.
+
+#### GUI
+
+- [Removed the ToolButton node in favor of Button.](https://github.com/godotengine/godot/pull/39690)
+ - Existing ToolButton nodes from Godot 3.x projects will be converted to Button nodes.
+
+#### Input
+
+- Removed the `DisplayServer.get_latin_keyboard_variant()` method (replaced by the more flexible `DisplayServer.keyboard_get_current_layout()`).
+
+#### Networking
+
+- Removed the deprecated `allow_object_decoding` property from PacketPeer.
+- Removed the deprecated `sync` and `slave` high-level multiplayer keywords.
+
+#### Export
+
+- **iOS:** [Remove redundant orientation export setting in favor of the orientation project setting.](https://github.com/godotengine/godot/pull/48939)
+
+#### Physics
+
+- Removed the deprecated PhysicsBody `friction` and `bounce` properties (replaced by PhysicsMaterial).
+
+#### Rendering
+
+- Removed OpenGL ES 2.0 renderer (replaced by the new mobile-oriented OpenGL 3 renderer).
+ - Vulkan, OpenGL 3.3, OpenGL ES 3.0 or WebGL 2.0 support is now required to run Godot.
+- [Removed support for 16× MSAA due to driver bugs and low performance.](https://github.com/godotengine/godot/pull/49063)
+ - For high-quality offline rendering, using supersampling together with 8× MSAA is a better option anyway.
+
+### Fixed
+
+#### Core
+
+- The positional command line argument now considers `.res` and `.tres` files as runnable scene formats.
+ - This fixes Godot not running the main scene or a custom scene if they were saved with a `.res` or `.tres` extension.
+- **macOS/Linux:** Fix the result of `Directory.get_space_left()`.
+- **Windows:** Godot can now kill its own PID using `OS.kill()`.
+
+#### Editor
+
+- The Android exporter no longer reports progress on each file, greatly speeding up the exporting process.
+- Searching with the Whole Words option enabled in the script editor is no longer exceedingly slow.
+
+#### GUI
+
+- Fixed OptionButton minimum size.
+- TabContainer is no longer too large when tabs are hidden.
+- ScrollBar now allows using `scroll_to_line()` when Scroll Active is disabled.
+- DynamicFont outlines now have antialiasing disabled if it was disabled on the font itself.
+
+#### Porting
+
+- **Windows:** `OS.execute()` now only quotes command line arguments if they contain special characters.
+
## [3.2] - 2020-01-29
### Added
diff --git a/DONORS.md b/DONORS.md
index 33a68650d9..f7026d9470 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -13,8 +13,6 @@ generous deed immortalized in the next stable release of Godot Engine.
## Platinum sponsors
Gamblify <https://www.gamblify.com>
- Heroic Labs <https://heroiclabs.com>
- Spiffcode <http://www.spiffcode.com>
## Gold sponsors
diff --git a/SConstruct b/SConstruct
index 83bd1560ff..9dcc6c554f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -127,7 +127,7 @@ opts.Add(BoolVariable("production", "Set defaults to build Godot for use in prod
opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
# Components
-opts.Add(BoolVariable("deprecated", "Enable deprecated features", True))
+opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True))
opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
@@ -149,7 +149,7 @@ opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable",
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
opts.Add("disable_classes", "Disable given classes (comma separated)", "")
opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True))
-opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", False))
+opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "")
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
@@ -329,6 +329,9 @@ if env_base["target"] == "debug":
if env_base["use_precise_math_checks"]:
env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"])
+if not env_base.File("#main/splash_editor.png").exists():
+ # Force disabling editor splash if missing.
+ env_base["no_editor_splash"] = True
if env_base["no_editor_splash"]:
env_base.Append(CPPDEFINES=["NO_EDITOR_SPLASH"])
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 21a802cb78..c85b0866cb 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -65,6 +65,14 @@ String ProjectSettings::get_resource_path() const {
return resource_path;
}
+String ProjectSettings::get_safe_project_name() const {
+ String safe_name = OS::get_singleton()->get_safe_dir_name(get("application/config/name"));
+ if (safe_name.is_empty()) {
+ safe_name = "UnnamedProject";
+ }
+ return safe_name;
+}
+
String ProjectSettings::get_imported_files_path() const {
return get_project_data_path().plus_file("imported");
}
@@ -176,7 +184,7 @@ String ProjectSettings::localize_path(const String &p_path) const {
String parent = path.substr(0, sep);
String plocal = localize_path(parent);
- if (plocal == "") {
+ if (plocal.is_empty()) {
return "";
}
// Only strip the starting '/' from 'path' if its parent ('plocal') ends with '/'
@@ -220,13 +228,13 @@ bool ProjectSettings::get_ignore_value_in_docs(const String &p_name) const {
String ProjectSettings::globalize_path(const String &p_path) const {
if (p_path.begins_with("res://")) {
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return p_path.replace("res:/", resource_path);
}
return p_path.replace("res://", "");
} else if (p_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return p_path.replace("user:/", data_dir);
}
return p_path.replace("user://", "");
@@ -448,7 +456,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Attempt with a user-defined main pack first
- if (p_main_pack != "") {
+ if (!p_main_pack.is_empty()) {
bool ok = _load_resource_pack(p_main_pack);
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, "Cannot open resource pack '" + p_main_pack + "'.");
@@ -463,7 +471,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
String exec_path = OS::get_singleton()->get_executable_path();
- if (exec_path != "") {
+ if (!exec_path.is_empty()) {
// We do several tests sequentially until one succeeds to find a PCK,
// and if so, we attempt loading it at the end.
@@ -515,11 +523,11 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Try to use the filesystem for files, according to OS.
// (Only Android -when reading from pck- and iOS use this.)
- if (OS::get_singleton()->get_resource_dir() != "") {
+ if (!OS::get_singleton()->get_resource_dir().is_empty()) {
// OS will call ProjectSettings->get_resource_path which will be empty if not overridden!
// If the OS would rather use a specific location, then it will not be empty.
resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/");
- if (resource_path != "" && resource_path[resource_path.length() - 1] == '/') {
+ if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') {
resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end.
}
@@ -583,7 +591,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
Error err = _setup(p_path, p_main_pack, p_upwards, p_ignore_override);
if (err == OK) {
String custom_settings = GLOBAL_DEF("application/config/project_settings_override", "");
- if (custom_settings != "") {
+ if (!custom_settings.is_empty()) {
_load_settings_text(custom_settings);
}
}
@@ -691,26 +699,21 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
return err;
}
- if (assign != String()) {
- if (section == String() && assign == "config_version") {
+ if (!assign.is_empty()) {
+ if (section.is_empty() && assign == "config_version") {
config_version = value;
if (config_version > CONFIG_VERSION) {
memdelete(f);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
}
} else {
- if (section == String()) {
+ if (section.is_empty()) {
set(assign, value);
- } else if (section == "application" && assign == "config/features") {
- const PackedStringArray project_features_untrimmed = value;
- const PackedStringArray project_features = _trim_to_supported_features(project_features_untrimmed);
- set("application/config/features", project_features);
- save();
} else {
set(section + "/" + assign, value);
}
}
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
section = next_tag.name;
}
}
@@ -794,7 +797,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
count += E.value.size();
}
- if (p_custom_features != String()) {
+ if (!p_custom_features.is_empty()) {
file->store_32(count + 1);
//store how many properties are saved, add one for custom featuers, which must always go first
String key = CoreStringNames::get_singleton()->_custom_features;
@@ -824,7 +827,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
for (String &key : E->get()) {
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
key = E->key() + "/" + key;
}
Variant value;
@@ -878,7 +881,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_line("");
file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
- if (p_custom_features != String()) {
+ if (!p_custom_features.is_empty()) {
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
}
file->store_string("\n");
@@ -888,12 +891,12 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_string("\n");
}
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
file->store_string("[" + E->key() + "]\n\n");
}
for (const String &F : E->get()) {
String key = F;
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
key = E->key() + "/" + key;
}
Variant value;
@@ -921,7 +924,35 @@ Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other par
}
Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) {
- ERR_FAIL_COND_V_MSG(p_path == "", ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
+ ERR_FAIL_COND_V_MSG(p_path.is_empty(), ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
+
+ PackedStringArray project_features = has_setting("application/config/features") ? (PackedStringArray)get_setting("application/config/features") : PackedStringArray();
+ // If there is no feature list currently present, force one to generate.
+ if (project_features.is_empty()) {
+ project_features = ProjectSettings::get_required_features();
+ }
+ // Check the rendering API.
+ const String rendering_api = has_setting("rendering/quality/driver/driver_name") ? (String)get_setting("rendering/quality/driver/driver_name") : String();
+ if (!rendering_api.is_empty()) {
+ // Add the rendering API as a project feature if it doesn't already exist.
+ if (!project_features.has(rendering_api)) {
+ project_features.append(rendering_api);
+ }
+ }
+ // Check for the existence of a csproj file.
+ if (FileAccess::exists(get_resource_path().plus_file(get_safe_project_name() + ".csproj"))) {
+ // If there is a csproj file, add the C# feature if it doesn't already exist.
+ if (!project_features.has("C#")) {
+ project_features.append("C#");
+ }
+ } else {
+ // If there isn't a csproj file, remove the C# feature if it exists.
+ if (project_features.has("C#")) {
+ project_features.remove_at(project_features.find("C#"));
+ }
+ }
+ project_features = _trim_to_supported_features(project_features);
+ set_setting("application/config/features", project_features);
Set<_VCSort> vclist;
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index 2d8ec76b7a..5b74356337 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -151,6 +151,7 @@ public:
String get_project_data_dir_name() const;
String get_project_data_path() const;
String get_resource_path() const;
+ String get_safe_project_name() const;
String get_imported_files_path() const;
static ProjectSettings *get_singleton();
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 0bf6efc96d..161008fd35 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -207,6 +207,10 @@ void OS::alert(const String &p_alert, const String &p_title) {
::OS::get_singleton()->alert(p_alert, p_title);
}
+void OS::crash(const String &p_message) {
+ CRASH_NOW_MSG(p_message);
+}
+
String OS::get_executable_path() const {
return ::OS::get_singleton()->get_executable_path();
}
@@ -542,6 +546,7 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("close_midi_inputs"), &OS::close_midi_inputs);
ClassDB::bind_method(D_METHOD("alert", "text", "title"), &OS::alert, DEFVAL("Alert!"));
+ ClassDB::bind_method(D_METHOD("crash", "message"), &OS::crash);
ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &OS::set_low_processor_usage_mode);
ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &OS::is_in_low_processor_usage_mode);
@@ -1478,7 +1483,7 @@ String Directory::get_next() {
ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use.");
String next = d->get_next();
- while (next != "" && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) {
+ while (!next.is_empty() && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) {
next = d->get_next();
}
return next;
@@ -1660,7 +1665,7 @@ String Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) {
ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant.");
String ret = CryptoCore::b64_encode_str(&w[0], len);
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
@@ -1685,7 +1690,7 @@ Variant Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
String Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) {
String ret = CryptoCore::b64_encode_str(p_arr.ptr(), p_arr.size());
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
@@ -1709,7 +1714,7 @@ Vector<uint8_t> Marshalls::base64_to_raw(const String &p_str) {
String Marshalls::utf8_to_base64(const String &p_str) {
CharString cstr = p_str.utf8();
String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length());
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
diff --git a/core/core_bind.h b/core/core_bind.h
index 4bacfa720c..920f2b539b 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -161,6 +161,7 @@ public:
int get_low_processor_usage_mode_sleep_usec() const;
void alert(const String &p_alert, const String &p_title = "ALERT!");
+ void crash(const String &p_message);
String get_executable_path() const;
int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false);
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index dd1754f010..51fcfd5305 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -142,27 +142,28 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(CLOCKWISE);
BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE);
- BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT);
- BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT);
- BIND_CORE_ENUM_CONSTANT(HALIGN_FILL);
-
- BIND_CORE_ENUM_CONSTANT(VALIGN_TOP);
- BIND_CORE_ENUM_CONSTANT(VALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(VALIGN_BOTTOM);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP_TO);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER_TO);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM_TO);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_TOP);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_CENTER);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BASELINE);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BOTTOM);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_LEFT);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_RIGHT);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_FILL);
+
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_TOP);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_BOTTOM);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_FILL);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP_TO);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER_TO);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM_TO);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_TOP);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_CENTER);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BASELINE);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BOTTOM);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPECIAL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ESCAPE);
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index 60aa3e6be7..7b397e88a3 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -139,7 +139,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
// Cache options
String variable_prefix = options["variable_prefix"];
- if (line == "") {
+ if (line.is_empty()) {
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
print_line("Enter \"help\" for assistance.");
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 4b284a30aa..7334db5cb0 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -33,7 +33,7 @@
void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
if (p_retinfo.type == Variant::INT && p_retinfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
p_method.return_type = p_retinfo.hint_string;
- if (p_method.return_type == "") {
+ if (p_method.return_type.is_empty()) {
p_method.return_type = "void*";
} else {
p_method.return_type += "*";
@@ -64,7 +64,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
if (p_arginfo.type == Variant::INT && p_arginfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
p_argument.type = p_arginfo.hint_string;
- if (p_argument.type == "") {
+ if (p_argument.type.is_empty()) {
p_argument.type = "void*";
} else {
p_argument.type += "*";
diff --git a/core/doc_data.h b/core/doc_data.h
index c75cdfcde5..db83dda8aa 100644
--- a/core/doc_data.h
+++ b/core/doc_data.h
@@ -70,18 +70,29 @@ public:
Vector<int> errors_returned;
bool operator<(const MethodDoc &p_method) const {
if (name == p_method.name) {
- // Must be a constructor since there is no overloading.
- // We want this arbitrary order for a class "Foo":
- // - 1. Default constructor: Foo()
- // - 2. Copy constructor: Foo(Foo)
- // - 3+. Other constructors Foo(Bar, ...) based on first argument's name
- if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
+ // Must be an operator or a constructor since there is no other overloading
+ if (name.left(8) == "operator") {
+ if (arguments.size() == p_method.arguments.size()) {
+ if (arguments.size() == 0) {
+ return false;
+ }
+ return arguments[0].type < p_method.arguments[0].type;
+ }
return arguments.size() < p_method.arguments.size();
+ } else {
+ // Must be a constructor
+ // We want this arbitrary order for a class "Foo":
+ // - 1. Default constructor: Foo()
+ // - 2. Copy constructor: Foo(Foo)
+ // - 3+. Other constructors Foo(Bar, ...) based on first argument's name
+ if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
+ return arguments.size() < p_method.arguments.size();
+ }
+ if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
+ return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type);
+ }
+ return arguments[0] < p_method.arguments[0];
}
- if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
- return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type);
- }
- return arguments[0] < p_method.arguments[0];
}
return name < p_method.name;
}
@@ -112,6 +123,7 @@ public:
String setter, getter;
String default_value;
bool overridden = false;
+ String overrides;
bool operator<(const PropertyDoc &p_prop) const {
return name < p_prop.name;
}
@@ -124,7 +136,11 @@ public:
String description;
String default_value;
bool operator<(const ThemeItemDoc &p_theme_item) const {
- return name < p_theme_item.name;
+ // First sort by the data type, then by name.
+ if (data_type == p_theme_item.data_type) {
+ return name < p_theme_item.name;
+ }
+ return data_type < p_theme_item.data_type;
}
};
diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp
index 719ea8afb5..61bb949ed4 100644
--- a/core/error/error_macros.cpp
+++ b/core/error/error_macros.cpp
@@ -76,7 +76,7 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
// Main error printing function.
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
- OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
+ OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, p_editor_notify, (Logger::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 03b2426370..fc74293d0d 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -40,7 +40,7 @@
static String get_type_name(const PropertyInfo &p_info) {
if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
- if (p_info.hint_string == "") {
+ if (p_info.hint_string.is_empty()) {
return "void*";
} else {
return p_info.hint_string + "*";
@@ -340,7 +340,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
int value = CoreConstants::get_global_constant_value(i);
String enum_name = CoreConstants::get_global_constant_enum(i);
String name = CoreConstants::get_global_constant_name(i);
- if (enum_name != String()) {
+ if (!enum_name.is_empty()) {
enum_list[enum_name].push_back(Pair<String, int>(name, value));
} else {
Dictionary d;
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index 19988a26cb..0c9b344a37 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -827,16 +827,21 @@ static GDNativeObjectPtr gdnative_global_get_singleton(const char *p_name) {
return (GDNativeObjectPtr)Engine::get_singleton()->get_singleton_object(String(p_name));
}
-static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
- Object *o = (Object *)p_instance;
+static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_object, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_object;
return o->get_instance_binding(p_token, p_callbacks);
}
-static void gdnative_object_set_instance_binding(GDNativeObjectPtr p_instance, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) {
- Object *o = (Object *)p_instance;
+static void gdnative_object_set_instance_binding(GDNativeObjectPtr p_object, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_object;
o->set_instance_binding(p_token, p_binding, p_callbacks);
}
+static void gdnative_object_set_instance(GDNativeObjectPtr p_object, const char *p_classname, GDExtensionClassInstancePtr p_instance) {
+ Object *o = (Object *)p_object;
+ ClassDB::set_object_extension_instance(o, p_classname, p_instance);
+}
+
static GDNativeObjectPtr gdnative_object_get_instance_from_id(GDObjectInstanceID p_instance_id) {
return (GDNativeObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id));
}
@@ -866,19 +871,8 @@ static GDNativeMethodBindPtr gdnative_classdb_get_method_bind(const char *p_clas
return (GDNativeMethodBindPtr)mb;
}
-static GDNativeClassConstructor gdnative_classdb_get_constructor(const char *p_classname, GDNativeExtensionPtr *r_extension) {
- ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname));
- if (class_info) {
- if (r_extension) {
- *r_extension = class_info->native_extension;
- }
- return (GDNativeClassConstructor)class_info->creation_func;
- }
- return nullptr;
-}
-
-static GDNativeObjectPtr gdnative_classdb_construct_object(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension) {
- return (GDNativeObjectPtr)ClassDB::construct_object((Object * (*)()) p_constructor, (ObjectNativeExtension *)p_extension);
+static GDNativeObjectPtr gdnative_classdb_construct_object(const char *p_classname) {
+ return (GDNativeObjectPtr)ClassDB::instantiate(p_classname);
}
static void *gdnative_classdb_get_class_tag(const char *p_classname) {
@@ -1026,6 +1020,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.global_get_singleton = gdnative_global_get_singleton;
gdni.object_get_instance_binding = gdnative_object_get_instance_binding;
gdni.object_set_instance_binding = gdnative_object_set_instance_binding;
+ gdni.object_set_instance = gdnative_object_set_instance;
gdni.object_cast_to = gdnative_object_cast_to;
gdni.object_get_instance_from_id = gdnative_object_get_instance_from_id;
@@ -1033,7 +1028,6 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
/* CLASSDB */
- gdni.classdb_get_constructor = gdnative_classdb_get_constructor;
gdni.classdb_construct_object = gdnative_classdb_construct_object;
gdni.classdb_get_method_bind = gdnative_classdb_get_method_bind;
gdni.classdb_get_class_tag = gdnative_classdb_get_class_tag;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index e411a9d85b..2191d99dea 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -211,7 +211,7 @@ typedef const char *(*GDNativeExtensionClassToString)(GDExtensionClassInstancePt
typedef void (*GDNativeExtensionClassReference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
-typedef GDExtensionClassInstancePtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
+typedef GDNativeObjectPtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassObjectInstance)(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance);
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
@@ -227,7 +227,6 @@ typedef struct {
GDNativeExtensionClassUnreference unreference_func;
GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
- GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */
GDNativeExtensionClassGetVirtual get_virtual_func;
void *class_userdata;
} GDNativeExtensionClassCreationInfo;
@@ -428,17 +427,18 @@ typedef struct {
void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
void (*object_destroy)(GDNativeObjectPtr p_o);
GDNativeObjectPtr (*global_get_singleton)(const char *p_name);
+
void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
+ void (*object_set_instance)(GDNativeObjectPtr p_o, const char *p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
+
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
GDObjectInstanceID (*object_get_instance_id)(const GDNativeObjectPtr p_object);
/* CLASSDB */
-
- GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname, GDNativeExtensionPtr *r_extension);
- GDNativeObjectPtr (*classdb_construct_object)(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension);
+ GDNativeObjectPtr (*classdb_construct_object)(const char *p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */
GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash);
void *(*classdb_get_class_tag)(const char *p_classname);
diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp
index a6b0a708c3..cfd3ac8099 100644
--- a/core/extension/native_extension.cpp
+++ b/core/extension/native_extension.cpp
@@ -156,7 +156,6 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
extension->native_extension.unreference = p_extension_funcs->unreference_func;
extension->native_extension.class_userdata = p_extension_funcs->class_userdata;
extension->native_extension.create_instance = p_extension_funcs->create_instance_func;
- extension->native_extension.set_object_instance = p_extension_funcs->object_instance_func;
extension->native_extension.free_instance = p_extension_funcs->free_instance_func;
extension->native_extension.get_virtual = p_extension_funcs->get_virtual_func;
@@ -398,7 +397,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or
}
}
- if (library_path == String()) {
+ if (library_path.is_empty()) {
if (r_error) {
*r_error = ERR_FILE_NOT_FOUND;
}
diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp
index c8755250d5..043843ea31 100644
--- a/core/extension/native_extension_manager.cpp
+++ b/core/extension/native_extension_manager.cpp
@@ -115,7 +115,7 @@ void NativeExtensionManager::load_extensions() {
FileAccessRef f = FileAccess::open(NativeExtension::get_extension_list_config_file(), FileAccess::READ);
while (f && !f->eof_reached()) {
String s = f->get_line().strip_edges();
- if (s != String()) {
+ if (!s.is_empty()) {
LoadStatus err = load_extension(s);
ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, "Error loading extension: " + s);
}
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 342ab3b704..3dfe73ab8e 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -103,7 +103,6 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f));
ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false));
ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping);
- ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed);
ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
@@ -404,7 +403,7 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
if (p_connected) {
String uidname = p_guid;
- if (p_guid == "") {
+ if (p_guid.is_empty()) {
int uidlen = MIN(p_name.length(), 16);
for (int i = 0; i < uidlen; i++) {
uidname = uidname + _hex_str(p_name[i]);
@@ -1250,7 +1249,7 @@ void Input::parse_mapping(String p_mapping) {
int idx = 1;
while (++idx < entry.size()) {
- if (entry[idx] == "") {
+ if (entry[idx].is_empty()) {
continue;
}
@@ -1421,10 +1420,10 @@ Input::Input() {
// If defined, parse SDL_GAMECONTROLLERCONFIG for possible new mappings/overrides.
String env_mapping = OS::get_singleton()->get_environment("SDL_GAMECONTROLLERCONFIG");
- if (env_mapping != "") {
+ if (!env_mapping.is_empty()) {
Vector<String> entries = env_mapping.split("\n");
for (int i = 0; i < entries.size(); i++) {
- if (entries[i] == "") {
+ if (entries[i].is_empty()) {
continue;
}
parse_mapping(entries[i]);
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index ccde8838e1..7c98fa9540 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -360,12 +360,12 @@ String InputEventKey::as_text() const {
kc = keycode_get_string(keycode);
}
- if (kc == String()) {
+ if (kc.is_empty()) {
return kc;
}
String mods_text = InputEventWithModifiers::as_text();
- return mods_text == "" ? kc : mods_text + "+" + kc;
+ return mods_text.is_empty() ? kc : mods_text + "+" + kc;
}
String InputEventKey::to_string() {
@@ -382,7 +382,7 @@ String InputEventKey::to_string() {
}
String mods = InputEventWithModifiers::as_text();
- mods = mods == "" ? TTR("none") : mods;
+ mods = mods.is_empty() ? TTR("none") : mods;
return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e);
}
@@ -634,7 +634,7 @@ static const char *_mouse_button_descriptions[9] = {
String InputEventMouseButton::as_text() const {
// Modifiers
String mods_text = InputEventWithModifiers::as_text();
- String full_string = mods_text == "" ? "" : mods_text + "+";
+ String full_string = mods_text.is_empty() ? "" : mods_text + "+";
// Button
MouseButton idx = get_button_index();
@@ -687,7 +687,7 @@ String InputEventMouseButton::to_string() {
}
String mods = InputEventWithModifiers::as_text();
- mods = mods == "" ? TTR("none") : mods;
+ mods = mods.is_empty() ? TTR("none") : mods;
// Work around the fact vformat can only take 5 substitutions but 6 need to be passed.
String index_and_mods = vformat("button_index=%s, mods=%s", button_index, mods);
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 84e1313756..183a2c3e68 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -718,7 +718,7 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
String name = split[0];
String override_for = split.size() > 1 ? split[1] : String();
- if (override_for != String() && OS::get_singleton()->has_feature(override_for)) {
+ if (!override_for.is_empty() && OS::get_singleton()->has_feature(override_for)) {
builtins_with_overrides[name].push_back(override_for);
}
}
@@ -730,12 +730,12 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
String name = split[0];
String override_for = split.size() > 1 ? split[1] : String();
- if (builtins_with_overrides.has(name) && override_for == String()) {
+ if (builtins_with_overrides.has(name) && override_for.is_empty()) {
// Builtin has an override but this particular one is not an override, so skip.
continue;
}
- if (override_for != String() && !OS::get_singleton()->has_feature(override_for)) {
+ if (!override_for.is_empty() && !OS::get_singleton()->has_feature(override_for)) {
// OS does not support this override - skip.
continue;
}
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 33f992e153..b2300574f8 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -183,7 +183,7 @@ Error ConfigFile::_internal_save(FileAccess *file) {
if (E != values.front()) {
file->store_string("\n");
}
- if (E.key() != "") {
+ if (!E.key().is_empty()) {
file->store_string("[" + E.key() + "]\n\n");
}
@@ -287,9 +287,9 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
return err;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
set_value(section, assign, value);
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
section = next_tag.name;
}
}
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 3bff0a3fd5..d804e67493 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -79,7 +79,7 @@ static Error _erase_recursive(DirAccess *da) {
da->list_dir_begin();
String n = da->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n != "." && n != "..") {
if (da->current_is_dir()) {
dirs.push_back(n);
@@ -183,7 +183,7 @@ String DirAccess::fix_path(String p_path) const {
if (ProjectSettings::get_singleton()) {
if (p_path.begins_with("res://")) {
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return p_path.replace_first("res:/", resource_path);
}
return p_path.replace_first("res://", "");
@@ -194,7 +194,7 @@ String DirAccess::fix_path(String p_path) const {
case ACCESS_USERDATA: {
if (p_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return p_path.replace_first("user:/", data_dir);
}
return p_path.replace_first("user://", "");
@@ -337,7 +337,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag
String curdir = get_current_dir();
list_dir_begin();
String n = get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n != "." && n != "..") {
if (p_copy_links && is_link(get_current_dir().plus_file(n))) {
create_link(read_link(get_current_dir().plus_file(n)), p_to + n);
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index e6e79dff8a..1b9c43b155 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -127,7 +127,7 @@ String FileAccess::fix_path(const String &p_path) const {
if (ProjectSettings::get_singleton()) {
if (r_path.begins_with("res://")) {
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return r_path.replace("res:/", resource_path);
}
return r_path.replace("res://", "");
@@ -138,7 +138,7 @@ String FileAccess::fix_path(const String &p_path) const {
case ACCESS_USERDATA: {
if (r_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return r_path.replace("user:/", data_dir);
}
return r_path.replace("user://", "");
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index b2832b2a75..e343706e66 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -459,7 +459,7 @@ PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
nd = nd.simplify_path();
- if (nd == "") {
+ if (nd.is_empty()) {
nd = ".";
}
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 800ac779e5..5c67bc4c48 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -49,6 +49,14 @@ HTTPClient *HTTPClient::create() {
return nullptr;
}
+void HTTPClient::set_http_proxy(const String &p_host, int p_port) {
+ WARN_PRINT("HTTP proxy feature is not available");
+}
+
+void HTTPClient::set_https_proxy(const String &p_host, int p_port) {
+ WARN_PRINT("HTTPS proxy feature is not available");
+}
+
Error HTTPClient::_request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
int size = p_body.size();
return request(p_method, p_url, p_headers, size > 0 ? p_body.ptr() : nullptr, size);
@@ -142,6 +150,9 @@ void HTTPClient::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_status"), &HTTPClient::get_status);
ClassDB::bind_method(D_METHOD("poll"), &HTTPClient::poll);
+ ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPClient::set_http_proxy);
+ ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPClient::set_https_proxy);
+
ClassDB::bind_method(D_METHOD("query_string_from_dict", "fields"), &HTTPClient::query_string_from_dict);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_mode_enabled"), "set_blocking_mode", "is_blocking_mode_enabled");
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 718c3a905e..9bc0134a6a 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -192,6 +192,10 @@ public:
virtual Error poll() = 0;
+ // Use empty string or -1 to unset
+ virtual void set_http_proxy(const String &p_host, int p_port);
+ virtual void set_https_proxy(const String &p_host, int p_port);
+
HTTPClient() {}
virtual ~HTTPClient() {}
};
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index b3d35b3603..f2ddeddbb8 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -70,9 +70,21 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
connection = tcp_connection;
- if (conn_host.is_valid_ip_address()) {
+ if (ssl && https_proxy_port != -1) {
+ proxy_client.instantiate(); // Needs proxy negotiation
+ server_host = https_proxy_host;
+ server_port = https_proxy_port;
+ } else if (!ssl && http_proxy_port != -1) {
+ server_host = http_proxy_host;
+ server_port = http_proxy_port;
+ } else {
+ server_host = conn_host;
+ server_port = conn_port;
+ }
+
+ if (server_host.is_valid_ip_address()) {
// Host contains valid IP
- Error err = tcp_connection->connect_to_host(IPAddress(conn_host), p_port);
+ Error err = tcp_connection->connect_to_host(IPAddress(server_host), server_port);
if (err) {
status = STATUS_CANT_CONNECT;
return err;
@@ -81,7 +93,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
status = STATUS_CONNECTING;
} else {
// Host contains hostname and needs to be resolved to IP
- resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host);
+ resolving = IP::get_singleton()->resolve_hostname_queue_item(server_host);
status = STATUS_RESOLVING;
}
@@ -134,7 +146,12 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA);
- String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n";
+ String uri = p_url;
+ if (!ssl && http_proxy_port != -1) {
+ uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url);
+ }
+
+ String request = String(_methods[p_method]) + " " + uri + " HTTP/1.1\r\n";
bool add_host = true;
bool add_clen = p_body_size > 0;
bool add_uagent = true;
@@ -229,6 +246,7 @@ void HTTPClientTCP::close() {
}
connection.unref();
+ proxy_client.unref();
status = STATUS_DISCONNECTED;
head_request = false;
if (resolving != IP::RESOLVER_INVALID_ID) {
@@ -265,7 +283,7 @@ Error HTTPClientTCP::poll() {
Error err = ERR_BUG; // Should be at least one entry.
while (ip_candidates.size() > 0) {
- err = tcp_connection->connect_to_host(ip_candidates.front(), conn_port);
+ err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port);
if (err == OK) {
break;
}
@@ -294,7 +312,48 @@ Error HTTPClientTCP::poll() {
return OK;
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
- if (ssl) {
+ if (ssl && proxy_client.is_valid()) {
+ Error err = proxy_client->poll();
+ if (err == ERR_UNCONFIGURED) {
+ proxy_client->set_connection(tcp_connection);
+ const Vector<String> headers;
+ err = proxy_client->request(METHOD_CONNECT, vformat("%s:%d", conn_host, conn_port), headers, nullptr, 0);
+ if (err != OK) {
+ status = STATUS_CANT_CONNECT;
+ return err;
+ }
+ } else if (err != OK) {
+ status = STATUS_CANT_CONNECT;
+ return err;
+ }
+ switch (proxy_client->get_status()) {
+ case STATUS_REQUESTING: {
+ return OK;
+ } break;
+ case STATUS_BODY: {
+ proxy_client->read_response_body_chunk();
+ return OK;
+ } break;
+ case STATUS_CONNECTED: {
+ if (proxy_client->get_response_code() != RESPONSE_OK) {
+ status = STATUS_CANT_CONNECT;
+ return ERR_CANT_CONNECT;
+ }
+ proxy_client.unref();
+ return OK;
+ }
+ case STATUS_DISCONNECTED:
+ case STATUS_RESOLVING:
+ case STATUS_CONNECTING: {
+ status = STATUS_CANT_CONNECT;
+ ERR_FAIL_V(ERR_BUG);
+ } break;
+ default: {
+ status = STATUS_CANT_CONNECT;
+ return ERR_CANT_CONNECT;
+ } break;
+ }
+ } else if (ssl) {
Ref<StreamPeerSSL> ssl;
if (!handshaking) {
// Connect the StreamPeerSSL and start handshaking
@@ -344,7 +403,7 @@ Error HTTPClientTCP::poll() {
Error err = ERR_CANT_CONNECT;
while (ip_candidates.size() > 0) {
tcp_connection->disconnect_from_host();
- err = tcp_connection->connect_to_host(ip_candidates.pop_front(), conn_port);
+ err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port);
if (err == OK) {
return OK;
}
@@ -678,6 +737,26 @@ int HTTPClientTCP::get_read_chunk_size() const {
return read_chunk_size;
}
+void HTTPClientTCP::set_http_proxy(const String &p_host, int p_port) {
+ if (p_host.is_empty() || p_port == -1) {
+ http_proxy_host = "";
+ http_proxy_port = -1;
+ } else {
+ http_proxy_host = p_host;
+ http_proxy_port = p_port;
+ }
+}
+
+void HTTPClientTCP::set_https_proxy(const String &p_host, int p_port) {
+ if (p_host.is_empty() || p_port == -1) {
+ https_proxy_host = "";
+ https_proxy_port = -1;
+ } else {
+ https_proxy_host = p_host;
+ https_proxy_port = p_port;
+ }
+}
+
HTTPClientTCP::HTTPClientTCP() {
tcp_connection.instantiate();
}
diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h
index 170afb551c..40a962925e 100644
--- a/core/io/http_client_tcp.h
+++ b/core/io/http_client_tcp.h
@@ -38,8 +38,14 @@ private:
Status status = STATUS_DISCONNECTED;
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
Array ip_candidates;
- int conn_port = -1;
+ int conn_port = -1; // Server to make requests to
String conn_host;
+ int server_port = -1; // Server to connect to (might be a proxy server)
+ String server_host;
+ int http_proxy_port = -1; // Proxy server for http requests
+ String http_proxy_host;
+ int https_proxy_port = -1; // Proxy server for https requests
+ String https_proxy_host;
bool ssl = false;
bool ssl_verify_host = false;
bool blocking = false;
@@ -58,6 +64,7 @@ private:
Ref<StreamPeerTCP> tcp_connection;
Ref<StreamPeer> connection;
+ Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server
int response_num = 0;
Vector<String> response_headers;
@@ -87,6 +94,8 @@ public:
void set_read_chunk_size(int p_size) override;
int get_read_chunk_size() const override;
Error poll() override;
+ void set_http_proxy(const String &p_host, int p_port) override;
+ void set_https_proxy(const String &p_host, int p_port) override;
HTTPClientTCP();
};
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index b68a8b20a5..3330bb8149 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -136,7 +136,7 @@ void RotatedFileLogger::clear_old_backups() {
da->list_dir_begin();
String f = da->get_next();
Set<String> backups;
- while (f != String()) {
+ while (!f.is_empty()) {
if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) {
backups.insert(f);
}
@@ -163,7 +163,7 @@ void RotatedFileLogger::rotate_file() {
if (max_files > 1) {
String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", ".");
String backup_name = base_path.get_basename() + timestamp;
- if (base_path.get_extension() != String()) {
+ if (!base_path.get_extension().is_empty()) {
backup_name += "." + base_path.get_extension();
}
@@ -266,7 +266,7 @@ void CompositeLogger::log_error(const char *p_function, const char *p_file, int
}
for (int i = 0; i < loggers.size(); ++i) {
- loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+ loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type);
}
}
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index e7d5b78d14..7c06a354d1 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -562,7 +562,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
return err;
}
- if (str == String()) {
+ if (str.is_empty()) {
r_variant = (Object *)nullptr;
} else {
Object *obj = ClassDB::instantiate(str);
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 972076e397..8da4e936e3 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -52,7 +52,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
return;
}
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
ResourceCache::lock.write_unlock();
@@ -82,7 +82,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
}
path_cache = p_path;
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources[path_cache] = this;
ResourceCache::lock.write_unlock();
@@ -383,7 +383,7 @@ bool Resource::is_translation_remapped() const {
#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void Resource::set_id_for_path(const String &p_path, const String &p_id) {
- if (p_id == "") {
+ if (p_id.is_empty()) {
ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
ResourceCache::path_cache_lock.write_unlock();
@@ -434,7 +434,7 @@ Resource::Resource() :
remapped_list(this) {}
Resource::~Resource() {
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
ResourceCache::lock.write_unlock();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index a5a195f859..bd040f303d 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -727,7 +727,7 @@ Error ResourceLoaderBinary::load() {
}
res = RES(r);
- if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ if (!path.is_empty() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it
}
r->set_scene_unique_id(id);
@@ -829,7 +829,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep
dep = external_resources[i].path;
}
- if (p_add_types && external_resources[i].type != String()) {
+ if (p_add_types && !external_resources[i].type.is_empty()) {
dep += "::" + external_resources[i].type;
}
@@ -1026,7 +1026,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
loader.cache_mode = p_cache_mode;
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
- String path = p_original_path != "" ? p_original_path : p_path;
+ String path = !p_original_path.is_empty() ? p_original_path : p_path;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.res_path = loader.local_path;
//loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
@@ -1045,7 +1045,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "") {
+ if (p_type.is_empty()) {
get_recognized_extensions(p_extensions);
return;
}
@@ -1979,7 +1979,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
for (RES &r : saved_resources) {
if (r->is_built_in()) {
- if (r->get_scene_unique_id() != "") {
+ if (!r->get_scene_unique_id().is_empty()) {
if (used_unique_ids.has(r->get_scene_unique_id())) {
r->set_scene_unique_id("");
} else {
@@ -1993,7 +1993,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
int res_index = 0;
for (RES &r : saved_resources) {
if (r->is_built_in()) {
- if (r->get_scene_unique_id() == "") {
+ if (r->get_scene_unique_id().is_empty()) {
String new_id;
while (true) {
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index cd44c537a8..fc5c434e37 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -78,8 +78,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return err;
}
- if (assign != String()) {
- if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) {
+ if (!assign.is_empty()) {
+ if (!path_found && assign.begins_with("path.") && r_path_and_type.path.is_empty()) {
String feature = assign.get_slicec('.', 1);
if (OS::get_singleton()->has_feature(feature)) {
r_path_and_type.path = value;
@@ -112,7 +112,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
memdelete(f);
- if (r_path_and_type.path == String() || r_path_and_type.type == String()) {
+ if (r_path_and_type.path.is_empty() || r_path_and_type.type.is_empty()) {
return ERR_FILE_CORRUPT;
}
return OK;
@@ -158,7 +158,7 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
}
void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "") {
+ if (p_type.is_empty()) {
get_recognized_extensions(p_extensions);
return;
}
@@ -167,7 +167,7 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type();
- if (res_type == String()) {
+ if (res_type.is_empty()) {
continue;
}
@@ -246,7 +246,7 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
bool ResourceFormatImporter::handles_type(const String &p_type) const {
for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type();
- if (res_type == String()) {
+ if (res_type.is_empty()) {
continue;
}
if (ClassDB::is_parent_class(res_type, p_type)) {
@@ -300,7 +300,7 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
return;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
if (assign.begins_with("path.")) {
r_paths->push_back(value);
} else if (assign == "path") {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 2198761c2a..f65570bd60 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -52,7 +52,7 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
String extension = p_path.get_extension();
List<String> extensions;
- if (p_for_type == String()) {
+ if (p_for_type.is_empty()) {
get_recognized_extensions(&extensions);
} else {
get_recognized_extensions_for_type(p_for_type, &extensions);
@@ -96,7 +96,7 @@ ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) con
}
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "" || handles_type(p_type)) {
+ if (p_type.is_empty() || handles_type(p_type)) {
get_recognized_extensions(p_extensions);
}
}
@@ -194,7 +194,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
+ RES res = loader[i]->load(p_path, !p_original_path.is_empty() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
if (res.is_null()) {
continue;
}
@@ -289,7 +289,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
thread_load_mutex->lock();
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
//must be loading from this resource
if (!thread_load_tasks.has(p_source_resource)) {
thread_load_mutex->unlock();
@@ -310,7 +310,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
if (thread_load_tasks.has(local_path)) {
thread_load_tasks[local_path].requests++;
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
}
thread_load_mutex->unlock();
@@ -354,7 +354,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
ResourceCache::lock.read_unlock();
}
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
}
@@ -574,7 +574,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour
bool xl_remapped = false;
String path = _path_remap(local_path, &xl_remapped);
- if (path == "") {
+ if (path.is_empty()) {
ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
}
@@ -776,7 +776,7 @@ String ResourceLoader::get_resource_type(const String &p_path) {
for (int i = 0; i < loader_count; i++) {
String result = loader[i]->get_resource_type(local_path);
- if (result != "") {
+ if (!result.is_empty()) {
return result;
}
}
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 83d575cee8..cb7d67a726 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -87,7 +87,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
// In PO file, "msgctxt" appears before "msgid". If we encounter a "msgctxt", we add what we have read
// and set "entered_context" to true to prevent adding twice.
- if (!skip_this && msg_id != "") {
+ if (!skip_this && !msg_id.is_empty()) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
} else if (status == STATUS_READING_PLURAL) {
@@ -125,7 +125,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
}
- if (msg_id != "") {
+ if (!msg_id.is_empty()) {
if (!skip_this && !entered_context) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
@@ -137,7 +137,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
translation->add_plural_message(msg_id, msgs_plural, msg_context);
}
}
- } else if (config == "") {
+ } else if (config.is_empty()) {
config = msg_str;
// Record plural rule.
int p_start = config.find("Plural-Forms");
@@ -178,7 +178,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
status = STATUS_READING_STRING;
}
- if (l == "" || l.begins_with("#")) {
+ if (l.is_empty() || l.begins_with("#")) {
if (l.find("fuzzy") != -1) {
skip_next = true;
}
@@ -236,15 +236,15 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
// Add the last set of data from last iteration.
if (status == STATUS_READING_STRING) {
- if (msg_id != "") {
+ if (!msg_id.is_empty()) {
if (!skip_this) {
translation->add_message(msg_id, msg_str, msg_context);
}
- } else if (config == "") {
+ } else if (config.is_empty()) {
config = msg_str;
}
} else if (status == STATUS_READING_PLURAL) {
- if (!skip_this && msg_id != "") {
+ if (!skip_this && !msg_id.is_empty()) {
if (plural_index != plural_forms - 1) {
memdelete(f);
ERR_FAIL_V_MSG(RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line));
@@ -253,7 +253,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
}
- ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + path + ".");
+ ERR_FAIL_COND_V_MSG(config.is_empty(), RES(), "No config found in file: " + path + ".");
Vector<String> configs = config.split("\n");
for (int i = 0; i < configs.size(); i++) {
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 8a44646ef9..bdceae4374 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -210,7 +210,7 @@ bool AStar::has_point(int p_id) const {
return points.has(p_id);
}
-Array AStar::get_points() {
+Array AStar::get_point_ids() {
Array point_list;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
@@ -539,7 +539,7 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled);
@@ -606,8 +606,8 @@ Vector<int> AStar2D::get_point_connections(int p_id) {
return astar.get_point_connections(p_id);
}
-Array AStar2D::get_points() {
- return astar.get_points();
+Array AStar2D::get_point_ids() {
+ return astar.get_point_ids();
}
void AStar2D::set_point_disabled(int p_id, bool p_disabled) {
@@ -859,7 +859,7 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar2D::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar2D::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar2D::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar2D::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 64fa32a325..ef6f22d228 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -138,7 +138,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
@@ -188,7 +188,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index f3e78c0080..83726f46b5 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -46,6 +46,11 @@ bool AABB::operator!=(const AABB &p_rval) const {
}
void AABB::merge_with(const AABB &p_aabb) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 beg_1, beg_2;
Vector3 end_1, end_2;
Vector3 min, max;
@@ -72,6 +77,11 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const {
}
AABB AABB::intersection(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -104,6 +114,11 @@ AABB AABB::intersection(const AABB &p_aabb) const {
}
bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 c1, c2;
Vector3 end = position + size;
real_t near = -1e20;
@@ -147,6 +162,11 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
}
bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 02ce2501a0..81124002e2 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -132,6 +132,11 @@ public:
};
inline bool AABB::intersects(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x >= (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -155,6 +160,11 @@ inline bool AABB::intersects(const AABB &p_aabb) const {
}
inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x > (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -178,6 +188,11 @@ inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
}
inline bool AABB::encloses(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -288,6 +303,11 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
}
bool AABB::has_point(const Vector3 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -311,6 +331,11 @@ bool AABB::has_point(const Vector3 &p_point) const {
}
inline void AABB::expand_to(const Vector3 &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 begin = position;
Vector3 end = position + size;
@@ -377,6 +402,11 @@ inline real_t AABB::get_shortest_axis_size() const {
}
bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t divx = 1.0 / p_dir.x;
real_t divy = 1.0 / p_dir.y;
real_t divz = 1.0 / p_dir.z;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index a5616b8d79..4a11b99fe8 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -124,10 +124,9 @@ struct AudioFrame {
r = p_frame.r;
}
- _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) {
+ _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) {
l = p_frame.l;
r = p_frame.r;
- return *this;
}
_ALWAYS_INLINE_ operator Vector2() const {
diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc
index 6f54d06ce7..f19ee8a7da 100644
--- a/core/math/bvh_split.inc
+++ b/core/math/bvh_split.inc
@@ -30,8 +30,8 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
int order[Point::AXIS_COUNT];
- order[0] = size.min_axis();
- order[Point::AXIS_COUNT - 1] = size.max_axis();
+ order[0] = size.min_axis_index();
+ order[Point::AXIS_COUNT - 1] = size.max_axis_index();
static_assert(Point::AXIS_COUNT <= 3);
if (Point::AXIS_COUNT == 3) {
diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp
index 2956e0cf09..6f551319df 100644
--- a/core/math/convex_hull.cpp
+++ b/core/math/convex_hull.cpp
@@ -606,9 +606,9 @@ private:
PagedAllocator<Face> face_pool;
LocalVector<Vertex *> original_vertices;
int32_t merge_stamp = 0;
- int32_t min_axis = 0;
- int32_t med_axis = 0;
- int32_t max_axis = 0;
+ Vector3::Axis min_axis = Vector3::Axis::AXIS_X;
+ Vector3::Axis med_axis = Vector3::Axis::AXIS_X;
+ Vector3::Axis max_axis = Vector3::Axis::AXIS_X;
int32_t used_edge_pairs = 0;
int32_t max_used_edge_pairs = 0;
@@ -1585,12 +1585,12 @@ void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) {
}
Vector3 s = aabb.size;
- max_axis = s.max_axis();
- min_axis = s.min_axis();
+ max_axis = s.max_axis_index();
+ min_axis = s.min_axis_index();
if (min_axis == max_axis) {
- min_axis = (max_axis + 1) % 3;
+ min_axis = Vector3::Axis((max_axis + 1) % 3);
}
- med_axis = 3 - max_axis - min_axis;
+ med_axis = Vector3::Axis(3 - max_axis - min_axis);
s /= real_t(10216);
if (((med_axis + 1) % 3) != max_axis) {
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index f366fd0499..fe277cff96 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -410,6 +410,14 @@ Error Expression::_get_token(Token &r_token) {
} else if (id == "self") {
r_token.type = TK_SELF;
} else {
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ if (id == Variant::get_type_name(Variant::Type(i))) {
+ r_token.type = TK_BASIC_TYPE;
+ r_token.value = i;
+ return OK;
+ }
+ }
+
if (Variant::has_utility_function(id)) {
r_token.type = TK_BUILTIN_FUNC;
r_token.value = id;
diff --git a/core/math/math_defs.h b/core/math/math_defs.h
index 900e90a598..1c6139688b 100644
--- a/core/math/math_defs.h
+++ b/core/math/math_defs.h
@@ -68,37 +68,38 @@ enum Orientation {
VERTICAL
};
-enum HAlign {
- HALIGN_LEFT,
- HALIGN_CENTER,
- HALIGN_RIGHT,
- HALIGN_FILL,
+enum HorizontalAlignment {
+ HORIZONTAL_ALIGNMENT_LEFT,
+ HORIZONTAL_ALIGNMENT_CENTER,
+ HORIZONTAL_ALIGNMENT_RIGHT,
+ HORIZONTAL_ALIGNMENT_FILL,
};
-enum VAlign {
- VALIGN_TOP,
- VALIGN_CENTER,
- VALIGN_BOTTOM
+enum VerticalAlignment {
+ VERTICAL_ALIGNMENT_TOP,
+ VERTICAL_ALIGNMENT_CENTER,
+ VERTICAL_ALIGNMENT_BOTTOM,
+ VERTICAL_ALIGNMENT_FILL,
};
-enum InlineAlign {
+enum InlineAlignment {
// Image alignment points.
- INLINE_ALIGN_TOP_TO = 0b0000,
- INLINE_ALIGN_CENTER_TO = 0b0001,
- INLINE_ALIGN_BOTTOM_TO = 0b0010,
- INLINE_ALIGN_IMAGE_MASK = 0b0011,
+ INLINE_ALIGNMENT_TOP_TO = 0b0000,
+ INLINE_ALIGNMENT_CENTER_TO = 0b0001,
+ INLINE_ALIGNMENT_BOTTOM_TO = 0b0010,
+ INLINE_ALIGNMENT_IMAGE_MASK = 0b0011,
// Text alignment points.
- INLINE_ALIGN_TO_TOP = 0b0000,
- INLINE_ALIGN_TO_CENTER = 0b0100,
- INLINE_ALIGN_TO_BASELINE = 0b1000,
- INLINE_ALIGN_TO_BOTTOM = 0b1100,
- INLINE_ALIGN_TEXT_MASK = 0b1100,
+ INLINE_ALIGNMENT_TO_TOP = 0b0000,
+ INLINE_ALIGNMENT_TO_CENTER = 0b0100,
+ INLINE_ALIGNMENT_TO_BASELINE = 0b1000,
+ INLINE_ALIGNMENT_TO_BOTTOM = 0b1100,
+ INLINE_ALIGNMENT_TEXT_MASK = 0b1100,
// Presets.
- INLINE_ALIGN_TOP = INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP,
- INLINE_ALIGN_CENTER = INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER,
- INLINE_ALIGN_BOTTOM = INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM
+ INLINE_ALIGNMENT_TOP = INLINE_ALIGNMENT_TOP_TO | INLINE_ALIGNMENT_TO_TOP,
+ INLINE_ALIGNMENT_CENTER = INLINE_ALIGNMENT_CENTER_TO | INLINE_ALIGNMENT_TO_CENTER,
+ INLINE_ALIGNMENT_BOTTOM = INLINE_ALIGNMENT_BOTTOM_TO | INLINE_ALIGNMENT_TO_BOTTOM
};
enum Side {
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index d8d0c06672..457d167516 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -134,12 +134,11 @@ public:
w(p_q.w) {
}
- Quaternion &operator=(const Quaternion &p_q) {
+ void operator=(const Quaternion &p_q) {
x = p_q.x;
y = p_q.y;
z = p_q.z;
w = p_q.w;
- return *this;
}
Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index f64bf560c8..0e6127b017 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -35,6 +35,11 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
}
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
@@ -95,6 +100,11 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
}
bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
//SAT intersection between local and transformed rect2
Vector2 xf_points[4] = {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 26e202589d..7029204cf1 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -49,6 +49,11 @@ struct Rect2 {
_FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); }
inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_include_borders) {
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
@@ -81,6 +86,11 @@ struct Rect2 {
}
inline real_t distance_to(const Vector2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t dist = 0.0;
bool inside = true;
@@ -117,6 +127,11 @@ struct Rect2 {
bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const;
inline bool encloses(const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
@@ -147,7 +162,11 @@ struct Rect2 {
}
inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -161,6 +180,11 @@ struct Rect2 {
return new_rect;
}
inline bool has_point(const Point2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -183,6 +207,11 @@ struct Rect2 {
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.grow_by(p_amount);
return g;
@@ -209,6 +238,11 @@ struct Rect2 {
}
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -225,7 +259,11 @@ struct Rect2 {
}
inline void expand_to(const Vector2 &p_vector) { //in place function for speed
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Vector2 begin = position;
Vector2 end = position + size;
@@ -349,6 +387,11 @@ struct Rect2i {
_FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); }
inline bool intersects(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
}
@@ -366,6 +409,11 @@ struct Rect2i {
}
inline bool encloses(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
@@ -389,14 +437,18 @@ struct Rect2i {
Point2i p_rect_end = p_rect.position + p_rect.size;
Point2i end = position + size;
- new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
- new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
+ new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
+ new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
return new_rect;
}
inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -410,6 +462,11 @@ struct Rect2i {
return new_rect;
}
bool has_point(const Point2i &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -431,6 +488,11 @@ struct Rect2i {
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_amount;
g.position.y -= p_amount;
@@ -453,6 +515,11 @@ struct Rect2i {
}
inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -469,6 +536,11 @@ struct Rect2i {
}
inline void expand_to(const Point2i &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Point2i begin = position;
Point2i end = position + size;
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 0a7b9d3faf..c0a189e040 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -70,12 +70,12 @@ struct Vector2 {
x = y = p_value;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? 0 : 1;
+ _FORCE_INLINE_ Vector2::Axis min_axis_index() const {
+ return x < y ? Vector2::AXIS_X : Vector2::AXIS_Y;
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? 1 : 0;
+ _FORCE_INLINE_ Vector2::Axis max_axis_index() const {
+ return x < y ? Vector2::AXIS_Y : Vector2::AXIS_X;
}
void normalize();
@@ -301,12 +301,12 @@ struct Vector2i {
return p_idx ? y : x;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? 0 : 1;
+ _FORCE_INLINE_ Vector2i::Axis min_axis_index() const {
+ return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y;
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? 1 : 0;
+ _FORCE_INLINE_ Vector2i::Axis max_axis_index() const {
+ return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X;
}
Vector2i min(const Vector2i &p_vector2i) const {
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 42e3da0b27..b9bd04b8c1 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -108,10 +108,10 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
}
-Basis Vector3::outer(const Vector3 &p_b) const {
- Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z);
- Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z);
- Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z);
+Basis Vector3::outer(const Vector3 &p_with) const {
+ Vector3 row0(x * p_with.x, x * p_with.y, x * p_with.z);
+ Vector3 row1(y * p_with.x, y * p_with.y, y * p_with.z);
+ Vector3 row2(z * p_with.x, z * p_with.y, z * p_with.z);
return Basis(row0, row1, row2);
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 02a56f684e..c0f80e8f11 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -71,12 +71,12 @@ struct Vector3 {
x = y = z = p_value;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
+ _FORCE_INLINE_ Vector3::Axis min_axis_index() const {
+ return x < y ? (x < z ? Vector3::AXIS_X : Vector3::AXIS_Z) : (y < z ? Vector3::AXIS_Y : Vector3::AXIS_Z);
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
+ _FORCE_INLINE_ Vector3::Axis max_axis_index() const {
+ return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X);
}
_FORCE_INLINE_ real_t length() const;
@@ -128,9 +128,9 @@ struct Vector3 {
return n.normalized();
}
- _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const;
- _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const;
- Basis outer(const Vector3 &p_b) const;
+ _FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
+ _FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
+ Basis outer(const Vector3 &p_with) const;
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
@@ -199,17 +199,17 @@ struct Vector3 {
}
};
-Vector3 Vector3::cross(const Vector3 &p_b) const {
+Vector3 Vector3::cross(const Vector3 &p_with) const {
Vector3 ret(
- (y * p_b.z) - (z * p_b.y),
- (z * p_b.x) - (x * p_b.z),
- (x * p_b.y) - (y * p_b.x));
+ (y * p_with.z) - (z * p_with.y),
+ (z * p_with.x) - (x * p_with.z),
+ (x * p_with.y) - (y * p_with.x));
return ret;
}
-real_t Vector3::dot(const Vector3 &p_b) const {
- return x * p_b.x + y * p_b.y + z * p_b.z;
+real_t Vector3::dot(const Vector3 &p_with) const {
+ return x * p_with.x + y * p_with.y + z * p_with.z;
}
Vector3 Vector3::abs() const {
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
index d3a57af77c..7812a0b41c 100644
--- a/core/math/vector3i.cpp
+++ b/core/math/vector3i.cpp
@@ -40,12 +40,12 @@ int32_t Vector3i::get_axis(const int p_axis) const {
return operator[](p_axis);
}
-int Vector3i::min_axis() const {
- return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
+Vector3i::Axis Vector3i::min_axis_index() const {
+ return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
}
-int Vector3i::max_axis() const {
- return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
+Vector3i::Axis Vector3i::max_axis_index() const {
+ return x < y ? (y < z ? Vector3i::AXIS_Z : Vector3i::AXIS_Y) : (x < z ? Vector3i::AXIS_Z : Vector3i::AXIS_X);
}
Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 10c28a5bb9..fba29a1f8d 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -62,8 +62,8 @@ struct Vector3i {
void set_axis(const int p_axis, const int32_t p_value);
int32_t get_axis(const int p_axis) const;
- int min_axis() const;
- int max_axis() const;
+ Vector3i::Axis min_axis_index() const;
+ Vector3i::Axis max_axis_index() const;
_FORCE_INLINE_ void zero();
diff --git a/core/multiplayer/multiplayer_replicator.cpp b/core/multiplayer/multiplayer_replicator.cpp
index 6604510394..c57562552a 100644
--- a/core/multiplayer/multiplayer_replicator.cpp
+++ b/core/multiplayer/multiplayer_replicator.cpp
@@ -207,7 +207,7 @@ Error MultiplayerReplicator::_send_default_spawn_despawn(int p_peer_id, const Re
const Vector<StringName> names = rel_path.get_names();
ERR_FAIL_COND_V(names.size() < 2, ERR_INVALID_PARAMETER);
- NodePath parent = NodePath(names.subarray(0, names.size() - 2), false);
+ NodePath parent = NodePath(names.slice(0, names.size() - 1), false);
ERR_FAIL_COND_V_MSG(!root_node->has_node(parent), ERR_INVALID_PARAMETER, "Path not found: " + parent);
int path_id = 0;
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 4b3c8b123f..bbd3b7b8de 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -497,22 +497,6 @@ void ClassDB::add_compatibility_class(const StringName &p_class, const StringNam
compat_classes[p_class] = p_fallback;
}
-thread_local bool initializing_with_extension = false;
-thread_local ObjectNativeExtension *initializing_extension = nullptr;
-thread_local GDExtensionClassInstancePtr initializing_extension_instance = nullptr;
-
-void ClassDB::instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base) {
- if (initializing_with_extension) {
- *r_extension = initializing_extension;
- *r_extension_instance = initializing_extension_instance;
- initializing_with_extension = false;
- initializing_extension->set_object_instance(*r_extension_instance, p_base);
- } else {
- *r_extension = nullptr;
- *r_extension_instance = nullptr;
- }
-}
-
Object *ClassDB::instantiate(const StringName &p_class) {
ClassInfo *ti;
{
@@ -533,21 +517,31 @@ Object *ClassDB::instantiate(const StringName &p_class) {
return nullptr;
}
#endif
- if (ti->native_extension) {
- initializing_with_extension = true;
- initializing_extension = ti->native_extension;
- initializing_extension_instance = ti->native_extension->create_instance(ti->native_extension->class_userdata);
+ if (ti->native_extension && ti->native_extension->create_instance) {
+ return (Object *)ti->native_extension->create_instance(ti->native_extension->class_userdata);
+ } else {
+ return ti->creation_func();
}
- return ti->creation_func();
}
-Object *ClassDB::construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension) {
- if (p_extension) {
- initializing_with_extension = true;
- initializing_extension = p_extension;
- initializing_extension_instance = p_extension->create_instance(p_extension->class_userdata);
+void ClassDB::set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance) {
+ ERR_FAIL_COND(!p_object);
+ ClassInfo *ti;
+ {
+ OBJTYPE_RLOCK;
+ ti = classes.getptr(p_class);
+ if (!ti || ti->disabled || !ti->creation_func || (ti->native_extension && !ti->native_extension->create_instance)) {
+ if (compat_classes.has(p_class)) {
+ ti = classes.getptr(compat_classes[p_class]);
+ }
+ }
+ ERR_FAIL_COND_MSG(!ti, "Cannot get class '" + String(p_class) + "'.");
+ ERR_FAIL_COND_MSG(ti->disabled, "Class '" + String(p_class) + "' is disabled.");
+ ERR_FAIL_COND_MSG(!ti->native_extension, "Class '" + String(p_class) + "' has no native extension.");
}
- return p_create_func();
+
+ p_object->_extension = ti->native_extension;
+ p_object->_extension_instance = p_instance;
}
bool ClassDB::can_instantiate(const StringName &p_class) {
@@ -737,7 +731,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
type->constant_map[p_name] = p_constant;
String enum_name = p_enum;
- if (enum_name != String()) {
+ if (!enum_name.is_empty()) {
if (enum_name.find(".") != -1) {
enum_name = enum_name.get_slicec('.', 1);
}
diff --git a/core/object/class_db.h b/core/object/class_db.h
index dae75ba564..ca9c1def29 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -211,8 +211,7 @@ public:
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
static bool can_instantiate(const StringName &p_class);
static Object *instantiate(const StringName &p_class);
- static Object *construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension);
- static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base);
+ static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
static APIType get_api_type(const StringName &p_class);
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 86c2891e5d..e961745d96 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -1,7 +1,8 @@
proto = """
#define GDVIRTUAL$VER($RET m_name $ARG) \\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
-GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+mutable bool _gdvirtual_##m_name##_initialized = false;\\
+mutable GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
if (script_instance) {\\
@@ -13,6 +14,10 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
return true;\\
} \\
}\\
+ if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
+ _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+ _gdvirtual_##m_name##_initialized = true;\\
+ }\\
if (_gdvirtual_##m_name) {\\
$CALLPTRARGS\\
$CALLPTRRETDEF\\
@@ -28,6 +33,10 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\
if (script_instance) {\\
return script_instance->has_method(_gdvirtual_##m_name##_sn);\\
}\\
+ if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
+ _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+ _gdvirtual_##m_name##_initialized = true;\\
+ }\\
if (_gdvirtual_##m_name) {\\
return true;\\
}\\
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 90bd697d37..14d4e0bee6 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -990,7 +990,7 @@ void Object::get_meta_list(List<StringName> *p_list) const {
}
void Object::add_user_signal(const MethodInfo &p_signal) {
- ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
+ ERR_FAIL_COND_MSG(p_signal.name.is_empty(), "Signal name cannot be empty.");
ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
SignalData s;
@@ -1253,7 +1253,7 @@ void Object::get_signal_list(List<MethodInfo> *p_signals) const {
const StringName *S = nullptr;
while ((S = signal_map.next(S))) {
- if (signal_map[*S].user.name != "") {
+ if (!signal_map[*S].user.name.is_empty()) {
//user signal
p_signals->push_back(signal_map[*S].user);
}
@@ -1680,7 +1680,7 @@ void Object::get_translatable_strings(List<String> *p_strings) const {
String text = get(E.name);
- if (text == "") {
+ if (text.is_empty()) {
continue;
}
@@ -1838,8 +1838,6 @@ void Object::_construct_object(bool p_reference) {
type_is_reference = p_reference;
_instance_id = ObjectDB::add_instance(this);
- ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance, this);
-
#ifdef DEBUG_ENABLED
_lock_index.init(1);
#endif
diff --git a/core/object/object.h b/core/object/object.h
index 218bc26dec..fc6e6a3660 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -284,7 +284,6 @@ struct ObjectNativeExtension {
GDNativeExtensionClassCreateInstance create_instance;
GDNativeExtensionClassFreeInstance free_instance;
- GDNativeExtensionClassObjectInstance set_object_instance;
GDNativeExtensionClassGetVirtual get_virtual;
};
@@ -353,7 +352,7 @@ public:
static String get_category_static() { \
String category = m_inherits::get_category_static(); \
if (_get_category != m_inherits::_get_category) { \
- if (category != "") { \
+ if (!category.is_empty()) { \
category += "/"; \
} \
category += _get_category(); \
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index c2449e3ddc..8ec1a973e7 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -511,7 +511,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
Variant defval;
if (script->get_property_default_value(E->key(), defval)) {
//remove because it's the same as the default value
- if (defval == E) {
+ if (defval == E->get()) {
to_remove.push_back(E->key());
}
}
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 03e251880f..c8b8931919 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -190,8 +190,8 @@ static void _OS_printres(Object *p_obj) {
}
void OS::print_all_resources(String p_to_file) {
- ERR_FAIL_COND(p_to_file != "" && _OSPRF);
- if (p_to_file != "") {
+ ERR_FAIL_COND(!p_to_file.is_empty() && _OSPRF);
+ if (!p_to_file.is_empty()) {
Error err;
_OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err);
if (err != OK) {
@@ -202,7 +202,7 @@ void OS::print_all_resources(String p_to_file) {
ObjectDB::debug_objects(_OS_printres);
- if (p_to_file != "") {
+ if (!p_to_file.is_empty()) {
if (_OSPRF) {
memdelete(_OSPRF);
}
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index 7ab85ac9d0..bb9a44ccaf 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -368,7 +368,7 @@ NodePath::NodePath(const String &p_path) {
for (int i = from; i <= path.length(); i++) {
if (path[i] == ':' || path[i] == 0) {
String str = path.substr(from, i - from);
- if (str == "") {
+ if (str.is_empty()) {
if (path[i] == 0) {
continue; // Allow end-of-path :
}
diff --git a/core/string/string_builder.cpp b/core/string/string_builder.cpp
index 834c87c845..45cc2f3280 100644
--- a/core/string/string_builder.cpp
+++ b/core/string/string_builder.cpp
@@ -33,7 +33,7 @@
#include <string.h>
StringBuilder &StringBuilder::append(const String &p_string) {
- if (p_string == String()) {
+ if (p_string.is_empty()) {
return *this;
}
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 9024f60dae..0e3482e873 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -310,7 +310,7 @@ StringName::StringName(const String &p_name, bool p_static) {
ERR_FAIL_COND(!configured);
- if (p_name == String()) {
+ if (p_name.is_empty()) {
return;
}
@@ -434,7 +434,7 @@ StringName StringName::search(const char32_t *p_name) {
}
StringName StringName::search(const String &p_name) {
- ERR_FAIL_COND_V(p_name == "", StringName());
+ ERR_FAIL_COND_V(p_name.is_empty(), StringName());
MutexLock lock(mutex);
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index b98aad9b58..73f789b041 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -1287,7 +1287,7 @@ bool TranslationServer::_load_translations(const String &p_from) {
void TranslationServer::setup() {
String test = GLOBAL_DEF("internationalization/locale/test", "");
test = test.strip_edges();
- if (test != "") {
+ if (!test.is_empty()) {
set_locale(test);
} else {
set_locale(OS::get_singleton()->get_locale());
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 320aae2ba4..ac8e2ece12 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -130,9 +130,8 @@ Char16String &Char16String::operator+=(char16_t p_char) {
return *this;
}
-Char16String &Char16String::operator=(const char16_t *p_cstr) {
+void Char16String::operator=(const char16_t *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char16_t *Char16String::get_data() const {
@@ -186,9 +185,8 @@ CharString &CharString::operator+=(char p_char) {
return *this;
}
-CharString &CharString::operator=(const char *p_cstr) {
+void CharString::operator=(const char *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char *CharString::get_data() const {
@@ -4285,7 +4283,7 @@ bool String::is_valid_filename() const {
return false;
}
- if (stripped == String()) {
+ if (stripped.is_empty()) {
return false;
}
@@ -4904,7 +4902,7 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String RTR(const String &p_text, const String &p_context) {
if (TranslationServer::get_singleton()) {
String rtr = TranslationServer::get_singleton()->tool_translate(p_text, p_context);
- if (rtr == String() || rtr == p_text) {
+ if (rtr.is_empty() || rtr == p_text) {
return TranslationServer::get_singleton()->translate(p_text, p_context);
} else {
return rtr;
@@ -4917,7 +4915,7 @@ String RTR(const String &p_text, const String &p_context) {
String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context) {
if (TranslationServer::get_singleton()) {
String rtr = TranslationServer::get_singleton()->tool_translate_plural(p_text, p_text_plural, p_n, p_context);
- if (rtr == String() || rtr == p_text || rtr == p_text_plural) {
+ if (rtr.is_empty() || rtr == p_text || rtr == p_text_plural) {
return TranslationServer::get_singleton()->translate_plural(p_text, p_text_plural, p_n, p_context);
} else {
return rtr;
diff --git a/core/string/ustring.h b/core/string/ustring.h
index f25c36f66c..396c996050 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -108,13 +108,10 @@ public:
_FORCE_INLINE_ Char16String() {}
_FORCE_INLINE_ Char16String(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ Char16String &operator=(const Char16String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ Char16String(const char16_t *p_cstr) { copy_from(p_cstr); }
- Char16String &operator=(const char16_t *p_cstr);
+ void operator=(const char16_t *p_cstr);
bool operator<(const Char16String &p_right) const;
Char16String &operator+=(char16_t p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -152,13 +149,10 @@ public:
_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ CharString &operator=(const CharString &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
- CharString &operator=(const char *p_cstr);
+ void operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -442,11 +436,7 @@ public:
_FORCE_INLINE_ String() {}
_FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
-
- String &operator=(const String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const String &p_str) { _cowdata._ref(p_str._cowdata); }
Vector<uint8_t> to_ascii_buffer() const;
Vector<uint8_t> to_utf8_buffer() const;
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index 3854e1e94c..4ec08821f8 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -234,19 +234,17 @@ public:
data[i] = p_from.data[i];
}
}
- inline LocalVector &operator=(const LocalVector &p_from) {
+ inline void operator=(const LocalVector &p_from) {
resize(p_from.size());
for (U i = 0; i < p_from.count; i++) {
data[i] = p_from.data[i];
}
- return *this;
}
- inline LocalVector &operator=(const Vector<T> &p_from) {
+ inline void operator=(const Vector<T> &p_from) {
resize(p_from.size());
for (U i = 0; i < count; i++) {
data[i] = p_from[i];
}
- return *this;
}
_FORCE_INLINE_ ~LocalVector() {
diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h
index 025cc30db4..9dab36e343 100644
--- a/core/templates/oa_hash_map.h
+++ b/core/templates/oa_hash_map.h
@@ -353,7 +353,7 @@ public:
(*this) = p_other;
}
- OAHashMap &operator=(const OAHashMap &p_other) {
+ void operator=(const OAHashMap &p_other) {
if (capacity != 0) {
clear();
}
@@ -363,7 +363,6 @@ public:
for (Iterator it = p_other.iter(); it.valid; it = p_other.next_iter(it)) {
set(*it.key, *it.value);
}
- return *this;
}
OAHashMap(uint32_t p_initial_capacity = 64) {
diff --git a/core/templates/ordered_hash_map.h b/core/templates/ordered_hash_map.h
index 4996b88190..928072bb18 100644
--- a/core/templates/ordered_hash_map.h
+++ b/core/templates/ordered_hash_map.h
@@ -85,11 +85,10 @@ public:
next_element(other.next_element) {
}
- Element &operator=(const Element &other) {
+ void operator=(const Element &other) {
list_element = other.list_element;
next_element = other.next_element;
prev_element = other.prev_element;
- return *this;
}
_FORCE_INLINE_ bool operator==(const Element &p_other) const {
@@ -145,9 +144,8 @@ public:
list_element(other.list_element) {
}
- ConstElement &operator=(const ConstElement &other) {
+ void operator=(const ConstElement &other) {
list_element = other.list_element;
- return *this;
}
ConstElement next() const {
diff --git a/core/templates/vector.h b/core/templates/vector.h
index a955d49101..2f51a83848 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -132,9 +132,8 @@ public:
insert(i, p_val);
}
- inline Vector &operator=(const Vector &p_from) {
+ inline void operator=(const Vector &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
Vector<uint8_t> to_byte_array() const {
@@ -144,27 +143,28 @@ public:
return ret;
}
- Vector<T> subarray(int p_from, int p_to) const {
- if (p_from < 0) {
- p_from = size() + p_from;
- }
- if (p_to < 0) {
- p_to = size() + p_to;
+ Vector<T> slice(int p_begin, int p_end) const {
+ Vector<T> result;
+
+ if (p_end < 0) {
+ p_end += size() + 1;
}
- ERR_FAIL_INDEX_V(p_from, size(), Vector<T>());
- ERR_FAIL_INDEX_V(p_to, size(), Vector<T>());
+ ERR_FAIL_INDEX_V(p_begin, size(), result);
+ ERR_FAIL_INDEX_V(p_end, size() + 1, result);
+
+ ERR_FAIL_COND_V(p_begin > p_end, result);
+
+ int result_size = p_end - p_begin;
+ result.resize(result_size);
- Vector<T> slice;
- int span = 1 + p_to - p_from;
- slice.resize(span);
- const T *r = ptr();
- T *w = slice.ptrw();
- for (int i = 0; i < span; ++i) {
- w[i] = r[p_from + i];
+ const T *const r = ptr();
+ T *const w = result.ptrw();
+ for (int i = 0; i < result_size; ++i) {
+ w[i] = r[p_begin + i];
}
- return slice;
+ return result;
}
bool operator==(const Vector<T> &p_arr) const {
diff --git a/core/templates/vmap.h b/core/templates/vmap.h
index 2aa22f97cf..0ff105ccbf 100644
--- a/core/templates/vmap.h
+++ b/core/templates/vmap.h
@@ -193,9 +193,8 @@ public:
_FORCE_INLINE_ VMap() {}
_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
- inline VMap &operator=(const VMap &p_from) {
+ inline void operator=(const VMap &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
};
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index b049c29688..45f2e0c5ac 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -365,55 +365,30 @@ Array Array::recursive_duplicate(bool p_deep, int recursion_count) const {
return new_arr;
}
-int Array::_clamp_slice_index(int p_index) const {
- int arr_size = size();
- int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
- if (fixed_index < 0) {
- fixed_index = arr_size + fixed_index;
- }
- return fixed_index;
-}
+Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const {
+ Array result;
-Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
-
- Array new_arr;
+ ERR_FAIL_COND_V_MSG(p_step == 0, result, "Slice step cannot be zero.");
- ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
-
- if (is_empty()) { // Don't try to slice empty arrays.
- return new_arr;
- }
- if (p_step > 0) {
- if (p_begin >= size() || p_end < -size()) {
- return new_arr;
- }
- } else { // p_step < 0
- if (p_begin < -size() || p_end >= size()) {
- return new_arr;
- }
+ if (p_end < 0) {
+ p_end += size() + 1;
}
- int begin = _clamp_slice_index(p_begin);
- int end = _clamp_slice_index(p_end);
+ ERR_FAIL_INDEX_V(p_begin, size(), result);
+ ERR_FAIL_INDEX_V(p_end, size() + 1, result);
- int new_arr_size = MAX(((end - begin + p_step) / p_step), 0);
- new_arr.resize(new_arr_size);
+ ERR_FAIL_COND_V_MSG(p_step > 0 && p_begin > p_end, result, "Slice is positive, but bounds is decreasing");
+ ERR_FAIL_COND_V_MSG(p_step < 0 && p_begin < p_end, result, "Slice is negative, but bounds is increasing");
- if (p_step > 0) {
- int dest_idx = 0;
- for (int idx = begin; idx <= end; idx += p_step) {
- ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
- new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
- }
- } else { // p_step < 0
- int dest_idx = 0;
- for (int idx = begin; idx >= end; idx += p_step) {
- ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
- new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
- }
+ int result_size = (p_end - p_begin) / p_step;
+ result.resize(result_size);
+
+ for (int src_idx = p_begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) {
+ result[dest_idx] = p_deep ? get(src_idx).duplicate(true) : get(src_idx);
+ src_idx += p_step;
}
- return new_arr;
+ return result;
}
Array Array::filter(const Callable &p_callable) const {
diff --git a/core/variant/array.h b/core/variant/array.h
index 5d2839dda7..6a68a9b9ff 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -44,8 +44,6 @@ class Array {
void _ref(const Array &p_from) const;
void _unref() const;
- inline int _clamp_slice_index(int p_index) const;
-
protected:
Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
bool _assign(const Array &p_array);
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 98be62391f..3fb4af4944 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -87,7 +87,10 @@ struct VariantCaster<const T &> {
// Object enum casts must go here
VARIANT_ENUM_CAST(Object::ConnectFlags);
+VARIANT_ENUM_CAST(Vector2::Axis);
+VARIANT_ENUM_CAST(Vector2i::Axis);
VARIANT_ENUM_CAST(Vector3::Axis);
+VARIANT_ENUM_CAST(Vector3i::Axis);
VARIANT_ENUM_CAST(Basis::EulerOrder);
VARIANT_ENUM_CAST(Error);
@@ -103,9 +106,9 @@ VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(MIDIMessage);
VARIANT_ENUM_CAST(MouseButton);
VARIANT_ENUM_CAST(Orientation);
-VARIANT_ENUM_CAST(HAlign);
-VARIANT_ENUM_CAST(VAlign);
-VARIANT_ENUM_CAST(InlineAlign);
+VARIANT_ENUM_CAST(HorizontalAlignment);
+VARIANT_ENUM_CAST(VerticalAlignment);
+VARIANT_ENUM_CAST(InlineAlignment);
VARIANT_ENUM_CAST(PropertyHint);
VARIANT_ENUM_CAST(PropertyUsageFlags);
VARIANT_ENUM_CAST(Variant::Type);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 34b8b782d2..82f547e78c 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1471,7 +1471,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, angle, sarray(), varray());
bind_method(Vector2, angle_to, sarray("to"), varray());
bind_method(Vector2, angle_to_point, sarray("to"), varray());
- bind_method(Vector2, direction_to, sarray("b"), varray());
+ bind_method(Vector2, direction_to, sarray("to"), varray());
bind_method(Vector2, distance_to, sarray("to"), varray());
bind_method(Vector2, distance_squared_to, sarray("to"), varray());
bind_method(Vector2, length, sarray(), varray());
@@ -1486,6 +1486,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, lerp, sarray("to", "weight"), varray());
bind_method(Vector2, slerp, sarray("to", "weight"), varray());
bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
+ bind_method(Vector2, max_axis_index, sarray(), varray());
+ bind_method(Vector2, min_axis_index, sarray(), varray());
bind_method(Vector2, move_toward, sarray("to", "delta"), varray());
bind_method(Vector2, rotated, sarray("phi"), varray());
bind_method(Vector2, orthogonal, sarray(), varray());
@@ -1508,6 +1510,8 @@ static void _register_variant_builtin_methods() {
/* Vector2i */
bind_method(Vector2i, aspect, sarray(), varray());
+ bind_method(Vector2i, max_axis_index, sarray(), varray());
+ bind_method(Vector2i, min_axis_index, sarray(), varray());
bind_method(Vector2i, sign, sarray(), varray());
bind_method(Vector2i, abs, sarray(), varray());
bind_method(Vector2i, clamp, sarray("min", "max"), varray());
@@ -1547,13 +1551,13 @@ static void _register_variant_builtin_methods() {
/* Vector3 */
- bind_method(Vector3, min_axis, sarray(), varray());
- bind_method(Vector3, max_axis, sarray(), varray());
+ bind_method(Vector3, min_axis_index, sarray(), varray());
+ bind_method(Vector3, max_axis_index, sarray(), varray());
bind_method(Vector3, angle_to, sarray("to"), varray());
bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray());
- bind_method(Vector3, direction_to, sarray("b"), varray());
- bind_method(Vector3, distance_to, sarray("b"), varray());
- bind_method(Vector3, distance_squared_to, sarray("b"), varray());
+ bind_method(Vector3, direction_to, sarray("to"), varray());
+ bind_method(Vector3, distance_to, sarray("to"), varray());
+ bind_method(Vector3, distance_squared_to, sarray("to"), varray());
bind_method(Vector3, length, sarray(), varray());
bind_method(Vector3, length_squared, sarray(), varray());
bind_method(Vector3, limit_length, sarray("length"), varray(1.0));
@@ -1587,8 +1591,8 @@ static void _register_variant_builtin_methods() {
/* Vector3i */
- bind_method(Vector3i, min_axis, sarray(), varray());
- bind_method(Vector3i, max_axis, sarray(), varray());
+ bind_method(Vector3i, min_axis_index, sarray(), varray());
+ bind_method(Vector3i, max_axis_index, sarray(), varray());
bind_method(Vector3i, sign, sarray(), varray());
bind_method(Vector3i, abs, sarray(), varray());
bind_method(Vector3i, clamp, sarray("min", "max"), varray());
@@ -1848,7 +1852,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedByteArray, resize, sarray("new_size"), varray());
bind_method(PackedByteArray, has, sarray("value"), varray());
bind_method(PackedByteArray, reverse, sarray(), varray());
- bind_method(PackedByteArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedByteArray, slice, sarray("begin", "end"), varray());
bind_method(PackedByteArray, sort, sarray(), varray());
bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedByteArray, duplicate, sarray(), varray());
@@ -1909,7 +1913,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt32Array, resize, sarray("new_size"), varray());
bind_method(PackedInt32Array, has, sarray("value"), varray());
bind_method(PackedInt32Array, reverse, sarray(), varray());
- bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray());
bind_method(PackedInt32Array, to_byte_array, sarray(), varray());
bind_method(PackedInt32Array, sort, sarray(), varray());
bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true));
@@ -1929,7 +1933,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt64Array, resize, sarray("new_size"), varray());
bind_method(PackedInt64Array, has, sarray("value"), varray());
bind_method(PackedInt64Array, reverse, sarray(), varray());
- bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray());
bind_method(PackedInt64Array, to_byte_array, sarray(), varray());
bind_method(PackedInt64Array, sort, sarray(), varray());
bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true));
@@ -1949,7 +1953,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat32Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat32Array, has, sarray("value"), varray());
bind_method(PackedFloat32Array, reverse, sarray(), varray());
- bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray());
bind_method(PackedFloat32Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat32Array, sort, sarray(), varray());
bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true));
@@ -1969,7 +1973,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat64Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat64Array, has, sarray("value"), varray());
bind_method(PackedFloat64Array, reverse, sarray(), varray());
- bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray());
bind_method(PackedFloat64Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat64Array, sort, sarray(), varray());
bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true));
@@ -1989,7 +1993,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedStringArray, resize, sarray("new_size"), varray());
bind_method(PackedStringArray, has, sarray("value"), varray());
bind_method(PackedStringArray, reverse, sarray(), varray());
- bind_method(PackedStringArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedStringArray, slice, sarray("begin", "end"), varray());
bind_method(PackedStringArray, to_byte_array, sarray(), varray());
bind_method(PackedStringArray, sort, sarray(), varray());
bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true));
@@ -2009,7 +2013,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector2Array, resize, sarray("new_size"), varray());
bind_method(PackedVector2Array, has, sarray("value"), varray());
bind_method(PackedVector2Array, reverse, sarray(), varray());
- bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray());
bind_method(PackedVector2Array, to_byte_array, sarray(), varray());
bind_method(PackedVector2Array, sort, sarray(), varray());
bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true));
@@ -2029,7 +2033,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector3Array, resize, sarray("new_size"), varray());
bind_method(PackedVector3Array, has, sarray("value"), varray());
bind_method(PackedVector3Array, reverse, sarray(), varray());
- bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray());
bind_method(PackedVector3Array, to_byte_array, sarray(), varray());
bind_method(PackedVector3Array, sort, sarray(), varray());
bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true));
@@ -2049,7 +2053,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedColorArray, resize, sarray("new_size"), varray());
bind_method(PackedColorArray, has, sarray("value"), varray());
bind_method(PackedColorArray, reverse, sarray(), varray());
- bind_method(PackedColorArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedColorArray, slice, sarray("begin", "end"), varray());
bind_method(PackedColorArray, to_byte_array, sarray(), varray());
bind_method(PackedColorArray, sort, sarray(), varray());
bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true));
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 2ba24b5af8..d24f3e90f5 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -753,8 +753,14 @@ VARIANT_ACCESSOR_NUMBER(uint32_t)
VARIANT_ACCESSOR_NUMBER(int64_t)
VARIANT_ACCESSOR_NUMBER(uint64_t)
VARIANT_ACCESSOR_NUMBER(char32_t)
+
+// Bind enums to allow using them as return types.
VARIANT_ACCESSOR_NUMBER(Error)
VARIANT_ACCESSOR_NUMBER(Side)
+VARIANT_ACCESSOR_NUMBER(Vector2::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector2i::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector3::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector3i::Axis)
template <>
struct VariantInternalAccessor<Basis::EulerOrder> {
@@ -1020,6 +1026,10 @@ INITIALIZER_INT(int64_t)
INITIALIZER_INT(char32_t)
INITIALIZER_INT(Error)
INITIALIZER_INT(ObjectID)
+INITIALIZER_INT(Vector2::Axis)
+INITIALIZER_INT(Vector2i::Axis)
+INITIALIZER_INT(Vector3::Axis)
+INITIALIZER_INT(Vector3i::Axis)
template <>
struct VariantInitializer<double> {
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 3c19c2c706..47561f4621 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -1598,14 +1598,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
//try path because it's a file
- if (res_text == String() && res->get_path().is_resource_file()) {
+ if (res_text.is_empty() && res->get_path().is_resource_file()) {
//external resource
String path = res->get_path();
res_text = "Resource(\"" + path + "\")";
}
//could come up with some sort of text
- if (res_text != String()) {
+ if (!res_text.is_empty()) {
p_store_string_func(p_store_string_ud, res_text);
break;
}
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index b1350c0241..161e6278a2 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="@GlobalScope" version="4.0">
<brief_description>
- Global scope constants and variables.
+ Global scope constants and functions.
</brief_description>
<description>
- Global scope constants and variables. This is all that resides in the globals, constants regarding error codes, keycodes, property hints, etc.
+ A list of global scope enumerated constants and built-in functions. This is all that resides in the globals, constants regarding error codes, keycodes, property hints, etc.
Singletons are also documented here, since they can be accessed from anywhere.
+ For the entries related to GDScript which can be accessed in any script see [@GDScript].
</description>
<tutorials>
+ <link title="Random number generation">$DOCS_URL/tutorials/math/random_number_generation.html</link>
</tutorials>
<methods>
<method name="abs">
@@ -1208,56 +1210,59 @@
</constant>
<constant name="COUNTERCLOCKWISE" value="1" enum="ClockDirection">
</constant>
- <constant name="HALIGN_LEFT" value="0" enum="HAlign">
+ <constant name="HORIZONTAL_ALIGNMENT_LEFT" value="0" enum="HorizontalAlignment">
Horizontal left alignment, usually for text-derived classes.
</constant>
- <constant name="HALIGN_CENTER" value="1" enum="HAlign">
+ <constant name="HORIZONTAL_ALIGNMENT_CENTER" value="1" enum="HorizontalAlignment">
Horizontal center alignment, usually for text-derived classes.
</constant>
- <constant name="HALIGN_RIGHT" value="2" enum="HAlign">
+ <constant name="HORIZONTAL_ALIGNMENT_RIGHT" value="2" enum="HorizontalAlignment">
Horizontal right alignment, usually for text-derived classes.
</constant>
- <constant name="HALIGN_FILL" value="3" enum="HAlign">
+ <constant name="HORIZONTAL_ALIGNMENT_FILL" value="3" enum="HorizontalAlignment">
Expand row to fit width, usually for text-derived classes.
</constant>
- <constant name="VALIGN_TOP" value="0" enum="VAlign">
+ <constant name="VERTICAL_ALIGNMENT_TOP" value="0" enum="VerticalAlignment">
Vertical top alignment, usually for text-derived classes.
</constant>
- <constant name="VALIGN_CENTER" value="1" enum="VAlign">
+ <constant name="VERTICAL_ALIGNMENT_CENTER" value="1" enum="VerticalAlignment">
Vertical center alignment, usually for text-derived classes.
</constant>
- <constant name="VALIGN_BOTTOM" value="2" enum="VAlign">
+ <constant name="VERTICAL_ALIGNMENT_BOTTOM" value="2" enum="VerticalAlignment">
Vertical bottom alignment, usually for text-derived classes.
</constant>
- <constant name="INLINE_ALIGN_TOP_TO" value="0" enum="InlineAlign">
- Aligns the top of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
+ <constant name="VERTICAL_ALIGNMENT_FILL" value="3" enum="VerticalAlignment">
+ Expand rows to fit height, usually for text-derived classes.
</constant>
- <constant name="INLINE_ALIGN_CENTER_TO" value="1" enum="InlineAlign">
- Aligns the center of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
+ <constant name="INLINE_ALIGNMENT_TOP_TO" value="0" enum="InlineAlignment">
+ Aligns the top of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGNMENT_TO_*[/code] constant.
</constant>
- <constant name="INLINE_ALIGN_BOTTOM_TO" value="2" enum="InlineAlign">
- Aligns the bottom of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
+ <constant name="INLINE_ALIGNMENT_CENTER_TO" value="1" enum="InlineAlignment">
+ Aligns the center of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGNMENT_TO_*[/code] constant.
</constant>
- <constant name="INLINE_ALIGN_TO_TOP" value="0" enum="InlineAlign">
- Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the top of the text.
+ <constant name="INLINE_ALIGNMENT_BOTTOM_TO" value="2" enum="InlineAlignment">
+ Aligns the bottom of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGNMENT_TO_*[/code] constant.
</constant>
- <constant name="INLINE_ALIGN_TO_CENTER" value="4" enum="InlineAlign">
- Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the center of the text.
+ <constant name="INLINE_ALIGNMENT_TO_TOP" value="0" enum="InlineAlignment">
+ Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGNMENT_*_TO[/code] constant to the top of the text.
</constant>
- <constant name="INLINE_ALIGN_TO_BASELINE" value="8" enum="InlineAlign">
- Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the baseline of the text.
+ <constant name="INLINE_ALIGNMENT_TO_CENTER" value="4" enum="InlineAlignment">
+ Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGNMENT_*_TO[/code] constant to the center of the text.
</constant>
- <constant name="INLINE_ALIGN_TO_BOTTOM" value="12" enum="InlineAlign">
+ <constant name="INLINE_ALIGNMENT_TO_BASELINE" value="8" enum="InlineAlignment">
+ Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGNMENT_*_TO[/code] constant to the baseline of the text.
+ </constant>
+ <constant name="INLINE_ALIGNMENT_TO_BOTTOM" value="12" enum="InlineAlignment">
Aligns inline object (e.g. image, table) to the bottom of the text.
</constant>
- <constant name="INLINE_ALIGN_TOP" value="0" enum="InlineAlign">
- Aligns top of the inline object (e.g. image, table) to the top of the text. Equvalent to [code]INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP[/code].
+ <constant name="INLINE_ALIGNMENT_TOP" value="0" enum="InlineAlignment">
+ Aligns top of the inline object (e.g. image, table) to the top of the text. Equvalent to [code]INLINE_ALIGNMENT_TOP_TO | INLINE_ALIGNMENT_TO_TOP[/code].
</constant>
- <constant name="INLINE_ALIGN_CENTER" value="5" enum="InlineAlign">
- Aligns center of the inline object (e.g. image, table) to the center of the text. Equvalent to [code]INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER[/code].
+ <constant name="INLINE_ALIGNMENT_CENTER" value="5" enum="InlineAlignment">
+ Aligns center of the inline object (e.g. image, table) to the center of the text. Equvalent to [code]INLINE_ALIGNMENT_CENTER_TO | INLINE_ALIGNMENT_TO_CENTER[/code].
</constant>
- <constant name="INLINE_ALIGN_BOTTOM" value="14" enum="InlineAlign">
- Aligns bottom of the inline object (e.g. image, table) to the bottom of the text. Equvalent to [code]INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM[/code].
+ <constant name="INLINE_ALIGNMENT_BOTTOM" value="14" enum="InlineAlignment">
+ Aligns bottom of the inline object (e.g. image, table) to the bottom of the text. Equvalent to [code]INLINE_ALIGNMENT_BOTTOM_TO | INLINE_ALIGNMENT_TO_BOTTOM[/code].
</constant>
<constant name="KEY_SPECIAL" value="16777216" enum="Key">
Keycodes with this bit applied are non-printable.
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 170cfea6f9..bdf8a78dc3 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -6,6 +6,7 @@
<description>
[AABB] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses floating-point coordinates. The 2D counterpart to [AABB] is [Rect2].
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get an AABB with a positive size.
[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses integer coordinates.
</description>
<tutorials>
@@ -157,14 +158,15 @@
<return type="bool" />
<argument index="0" name="point" type="Vector3" />
<description>
- Returns [code]true[/code] if the [AABB] contains a point.
+ Returns [code]true[/code] if the [AABB] contains a point. Points on the faces of the AABB are considered included, though float-point precision errors may impact the accuracy of such checks.
+ [b]Note:[/b] This method is not reliable for [AABB] with a [i]negative size[/i]. Use [method abs] to get a positive sized equivalent [AABB] to check for contained points.
</description>
</method>
<method name="intersection" qualifiers="const">
<return type="AABB" />
<argument index="0" name="with" type="AABB" />
<description>
- Returns the intersection between two [AABB]. An empty AABB (size 0,0,0) is returned on failure.
+ Returns the intersection between two [AABB]. An empty AABB (size [code](0, 0, 0)[/code]) is returned on failure.
</description>
</method>
<method name="intersects" qualifiers="const">
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index 11c0fc33b8..bbb5f6b8e3 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -244,6 +244,12 @@
Returns the number of points currently in the points pool.
</description>
</method>
+ <method name="get_point_ids">
+ <return type="Array" />
+ <description>
+ Returns an array of all point IDs.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PackedVector3Array" />
<argument index="0" name="from_id" type="int" />
@@ -267,12 +273,6 @@
Returns the weight scale of the point associated with the given [code]id[/code].
</description>
</method>
- <method name="get_points">
- <return type="Array" />
- <description>
- Returns an array of all points.
- </description>
- </method>
<method name="has_point" qualifiers="const">
<return type="bool" />
<argument index="0" name="id" type="int" />
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 43e7d59665..dc821ebb8b 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -215,6 +215,12 @@
Returns the number of points currently in the points pool.
</description>
</method>
+ <method name="get_point_ids">
+ <return type="Array" />
+ <description>
+ Returns an array of all point IDs.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PackedVector2Array" />
<argument index="0" name="from_id" type="int" />
@@ -238,12 +244,6 @@
Returns the weight scale of the point associated with the given [code]id[/code].
</description>
</method>
- <method name="get_points">
- <return type="Array" />
- <description>
- Returns an array of all points.
- </description>
- </method>
<method name="has_point" qualifiers="const">
<return type="bool" />
<argument index="0" name="id" type="int" />
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index df0cc6f268..8fa4e9a309 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -68,11 +68,11 @@
<member name="dialog_text" type="String" setter="set_text" getter="get_text" default="&quot;&quot;">
The text displayed by the dialog.
</member>
- <member name="exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" override="true" default="true" />
- <member name="title" type="String" setter="set_title" getter="get_title" override="true" default="&quot;Alert!&quot;" />
- <member name="transient" type="bool" setter="set_transient" getter="is_transient" override="true" default="true" />
- <member name="visible" type="bool" setter="set_visible" getter="is_visible" override="true" default="false" />
- <member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" override="true" default="true" />
+ <member name="exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" overrides="Window" default="true" />
+ <member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Alert!&quot;" />
+ <member name="transient" type="bool" setter="set_transient" getter="is_transient" overrides="Window" default="true" />
+ <member name="visible" type="bool" setter="set_visible" getter="is_visible" overrides="Window" default="false" />
+ <member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" overrides="Window" default="true" />
</members>
<signals>
<signal name="cancelled">
diff --git a/doc/classes/AnimationNodeStateMachinePlayback.xml b/doc/classes/AnimationNodeStateMachinePlayback.xml
index b299f8654a..48507471e9 100644
--- a/doc/classes/AnimationNodeStateMachinePlayback.xml
+++ b/doc/classes/AnimationNodeStateMachinePlayback.xml
@@ -72,6 +72,6 @@
</method>
</methods>
<members>
- <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" override="true" default="true" />
+ <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="true" />
</members>
</class>
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index d505ee98cc..5b1861bc9a 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -449,7 +449,10 @@
<argument index="2" name="step" type="int" default="1" />
<argument index="3" name="deep" type="bool" default="false" />
<description>
- Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is [code]true[/code]. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing. Wraps around if [code]begin[/code] or [code]end[/code] are out of bounds or negative. Returns an empty array for invalid parameters.
+ Returns the slice of the [Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [Array].
+ If [code]end[/code] is negative, it will be relative to the end of the array.
+ If specified, [code]step[/code] is the relative index between source elements.
+ If [code]deep[/code] is true, each element will be copied by value rather than by reference.
</description>
</method>
<method name="sort">
diff --git a/doc/classes/AspectRatioContainer.xml b/doc/classes/AspectRatioContainer.xml
index 4c0af0b997..237bec4e61 100644
--- a/doc/classes/AspectRatioContainer.xml
+++ b/doc/classes/AspectRatioContainer.xml
@@ -9,10 +9,10 @@
<tutorials>
</tutorials>
<members>
- <member name="alignment_horizontal" type="int" setter="set_alignment_horizontal" getter="get_alignment_horizontal" enum="AspectRatioContainer.AlignMode" default="1">
+ <member name="alignment_horizontal" type="int" setter="set_alignment_horizontal" getter="get_alignment_horizontal" enum="AspectRatioContainer.AlignmentMode" default="1">
Specifies the horizontal relative position of child controls.
</member>
- <member name="alignment_vertical" type="int" setter="set_alignment_vertical" getter="get_alignment_vertical" enum="AspectRatioContainer.AlignMode" default="1">
+ <member name="alignment_vertical" type="int" setter="set_alignment_vertical" getter="get_alignment_vertical" enum="AspectRatioContainer.AlignmentMode" default="1">
Specifies the vertical relative position of child controls.
</member>
<member name="ratio" type="float" setter="set_ratio" getter="get_ratio" default="1.0">
@@ -36,13 +36,13 @@
The width and height of child controls is automatically adjusted to make their bounding rectangle cover the entire area of the container while keeping the aspect ratio.
When the bounding rectangle of child controls exceed the container's size and [member Control.rect_clip_content] is enabled, this allows to show only the container's area restricted by its own bounding rectangle.
</constant>
- <constant name="ALIGN_BEGIN" value="0" enum="AlignMode">
+ <constant name="ALIGNMENT_BEGIN" value="0" enum="AlignmentMode">
Aligns child controls with the beginning (left or top) of the container.
</constant>
- <constant name="ALIGN_CENTER" value="1" enum="AlignMode">
+ <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
Aligns child controls with the center of the container.
</constant>
- <constant name="ALIGN_END" value="2" enum="AlignMode">
+ <constant name="ALIGNMENT_END" value="2" enum="AlignmentMode">
Aligns child controls with the end (right or bottom) of the container.
</constant>
</constants>
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 981b3167d9..1b77a5b4d8 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -57,7 +57,7 @@
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" default="false">
If [code]true[/code], the button is in disabled state and can't be clicked or toggled.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="keep_pressed_outside" type="bool" setter="set_keep_pressed_outside" getter="is_keep_pressed_outside" default="false">
If [code]true[/code], the button stays pressed when moving the cursor outside the button while pressing it.
[b]Note:[/b] This property only affects the button's visual appearance. Signals will be emitted at the same moment regardless of this property's value.
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index f0f49f89d5..aa2ffae48c 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -53,6 +53,7 @@
<argument index="1" name="texture" type="Texture2D" />
<description>
Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots.
+ [b]Note:[/b] When setting a roughness or metallic texture on a material that has no texture assigned to those slots, [member roughness] or [member metallic] will automatically be set to [code]1.0[/code] to ensure correct appearance.
</description>
</method>
</methods>
@@ -229,6 +230,7 @@
</member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0">
A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
+ [b]Note:[/b] [member metallic] is automatically set to [code]1.0[/code] when assigning a metallic texture using [method set_texture].
</member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
@@ -301,6 +303,7 @@
</member>
<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
+ [b]Note:[/b] [member roughness] is automatically set to [code]1.0[/code] when assigning a roughness texture using [method set_texture].
</member>
<member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the roughness per-pixel. Multiplied by [member roughness].
diff --git a/doc/classes/BoxContainer.xml b/doc/classes/BoxContainer.xml
index ec81b866f6..a968e855a5 100644
--- a/doc/classes/BoxContainer.xml
+++ b/doc/classes/BoxContainer.xml
@@ -18,19 +18,16 @@
</method>
</methods>
<members>
- <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="BoxContainer.AlignMode" default="0">
- The alignment of the container's children (must be one of [constant ALIGN_BEGIN], [constant ALIGN_CENTER], or [constant ALIGN_END]).
+ <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="BoxContainer.AlignmentMode" default="0">
+ The alignment of the container's children (must be one of [constant ALIGNMENT_BEGIN], [constant ALIGNMENT_CENTER], or [constant ALIGNMENT_END]).
</member>
</members>
<constants>
- <constant name="ALIGN_BEGIN" value="0" enum="AlignMode">
- Aligns children with the beginning of the container.
+ <constant name="ALIGNMENT_BEGIN" value="0" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_CENTER" value="1" enum="AlignMode">
- Aligns children with the center of the container.
+ <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_END" value="2" enum="AlignMode">
- Aligns children with the end of the container.
+ <constant name="ALIGNMENT_END" value="2" enum="AlignmentMode">
</constant>
</constants>
</class>
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index 055d5091c7..d1a19861e4 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -64,8 +64,8 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_text_align" getter="get_text_align" enum="Button.TextAlign" default="1">
- Text alignment policy for the button's text, use one of the [enum TextAlign] constants.
+ <member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" enum="HorizontalAlignment" default="1">
+ Text alignment policy for the button's text, use one of the [enum @GlobalScope.HorizontalAlignment] constants.
</member>
<member name="clip_text" type="bool" setter="set_clip_text" getter="get_clip_text" default="false">
When this property is enabled, text that is too large to fit the button is clipped, when disabled the Button will always be wide enough to hold the text.
@@ -80,8 +80,8 @@
Button's icon, if text is present the icon will be placed before the text.
To edit margin and spacing of the icon, use [theme_item hseparation] theme property and [code]content_margin_*[/code] properties of the used [StyleBox]es.
</member>
- <member name="icon_align" type="int" setter="set_icon_align" getter="get_icon_align" enum="Button.TextAlign" default="0">
- Specifies if the icon should be aligned to the left, right, or center of a button. Uses the same [enum TextAlign] constants as the text alignment. If centered, text will draw on top of the icon.
+ <member name="icon_alignment" type="int" setter="set_icon_alignment" getter="get_icon_alignment" enum="HorizontalAlignment" default="0">
+ Specifies if the icon should be aligned to the left, right, or center of a button. Uses the same [enum @GlobalScope.HorizontalAlignment] constants as the text alignment. If centered, text will draw on top of the icon.
</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.
@@ -93,27 +93,7 @@
Base text writing direction.
</member>
</members>
- <constants>
- <constant name="ALIGN_LEFT" value="0" enum="TextAlign">
- Align the text to the left.
- </constant>
- <constant name="ALIGN_CENTER" value="1" enum="TextAlign">
- Align the text to the center.
- </constant>
- <constant name="ALIGN_RIGHT" value="2" enum="TextAlign">
- Align the text to the right.
- </constant>
- </constants>
<theme_items>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- [StyleBox] used when the [Button] is disabled.
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [Button] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the [Button]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Default text [Color] of the [Button].
</theme_item>
@@ -135,15 +115,6 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the [Button] is being pressed.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [Button]'s text.
- </theme_item>
- <theme_item name="hover" data_type="style" type="StyleBox">
- [StyleBox] used when the [Button] is being hovered.
- </theme_item>
- <theme_item name="hseparation" data_type="constant" type="int" default="2">
- The horizontal space between [Button]'s icon and text.
- </theme_item>
<theme_item name="icon_disabled_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Icon modulate [Color] used when the [Button] is disabled.
</theme_item>
@@ -162,12 +133,30 @@
<theme_item name="icon_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Icon modulate [Color] used when the [Button] is being pressed.
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- Default [StyleBox] for the [Button].
+ <theme_item name="hseparation" data_type="constant" type="int" default="2">
+ The horizontal space between [Button]'s icon and text.
</theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the [Button]'s text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [Button]'s text.
+ </theme_item>
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ [StyleBox] used when the [Button] is disabled.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [Button] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
+ </theme_item>
+ <theme_item name="hover" data_type="style" type="StyleBox">
+ [StyleBox] used when the [Button] is being hovered.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ Default [StyleBox] for the [Button].
+ </theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is being pressed.
</theme_item>
diff --git a/doc/classes/ButtonGroup.xml b/doc/classes/ButtonGroup.xml
index 9229e69fa7..e3e781ac10 100644
--- a/doc/classes/ButtonGroup.xml
+++ b/doc/classes/ButtonGroup.xml
@@ -24,7 +24,7 @@
</method>
</methods>
<members>
- <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" override="true" default="true" />
+ <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="true" />
</members>
<signals>
<signal name="pressed">
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index a3a891cdcb..6a1782fc52 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -123,13 +123,13 @@
If [code]true[/code], draws the camera's screen rectangle in the editor.
</member>
<member name="limit_bottom" type="int" setter="set_limit" getter="get_limit" default="10000000">
- Bottom scroll limit in pixels. The camera stops moving when reaching this value.
+ Bottom scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="limit_left" type="int" setter="set_limit" getter="get_limit" default="-10000000">
- Left scroll limit in pixels. The camera stops moving when reaching this value.
+ Left scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="limit_right" type="int" setter="set_limit" getter="get_limit" default="10000000">
- Right scroll limit in pixels. The camera stops moving when reaching this value.
+ Right scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="limit_smoothed" type="bool" setter="set_limit_smoothing_enabled" getter="is_limit_smoothing_enabled" default="false">
If [code]true[/code], the camera smoothly stops when reaches its limits.
@@ -137,10 +137,10 @@
[b]Note:[/b] To immediately update the camera's position to be within limits without smoothing, even with this setting enabled, invoke [method reset_smoothing].
</member>
<member name="limit_top" type="int" setter="set_limit" getter="get_limit" default="-10000000">
- Top scroll limit in pixels. The camera stops moving when reaching this value.
+ Top scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)">
- The camera's offset, useful for looking around or camera shake animations.
+ The camera's relative offset. Useful for looking around or camera shake animations. The offseted camera can go past the limits defined in [member limit_top], [member limit_bottom], [member limit_left] and [member limit_right].
</member>
<member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="Camera2D.Camera2DProcessCallback" default="1">
The camera's process callback. See [enum Camera2DProcessCallback].
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index 06e2f83f05..772396befe 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -218,10 +218,10 @@
Disables [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] simulation (default).
</constant>
<constant name="DOPPLER_TRACKING_IDLE_STEP" value="1" enum="DopplerTracking">
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
+ Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
</constant>
<constant name="DOPPLER_TRACKING_PHYSICS_STEP" value="2" enum="DopplerTracking">
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
+ Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
</constant>
</constants>
</class>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 98437ef296..cf6a8bad5e 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -143,7 +143,7 @@
<argument index="0" name="font" type="Font" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="text" type="String" />
- <argument index="3" name="align" type="int" enum="HAlign" default="0" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
<argument index="5" name="max_lines" type="int" default="-1" />
<argument index="6" name="size" type="int" default="16" />
@@ -236,7 +236,7 @@
<argument index="0" name="font" type="Font" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="text" type="String" />
- <argument index="3" name="align" type="int" enum="HAlign" default="0" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
<argument index="5" name="size" type="int" default="16" />
<argument index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
@@ -253,7 +253,7 @@
# so the Control is only created once.
var default_font = Control.new().get_font("font")
var default_font_size = Control.new().get_font_size("font_size")
- draw_string(default_font, Vector2(64, 64), "Hello world", HALIGN_LEFT, -1, font_size)
+ draw_string(default_font, Vector2(64, 64), "Hello world", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size)
[/gdscript]
[csharp]
// If using this method in a script that redraws constantly, move the
@@ -261,7 +261,7 @@
// so the Control is only created once.
Font defaultFont = new Control().GetFont("font");
int defaultFontSize = new Control().GetFontSize("font_size");
- DrawString(defaultFont, new Vector2(64, 64), "Hello world", HALIGN_LEFT, -1, defaultFontSize);
+ DrawString(defaultFont, new Vector2(64, 64), "Hello world", HORIZONTAL_ALIGNMENT_LEFT, -1, defaultFontSize);
[/csharp]
[/codeblocks]
See also [method Font.draw_string].
diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml
index 18f668a052..32ef70a5cf 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -10,28 +10,10 @@
<tutorials>
</tutorials>
<members>
- <member name="align" type="int" setter="set_text_align" getter="get_text_align" override="true" enum="Button.TextAlign" default="0" />
- <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" override="true" default="true" />
+ <member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" overrides="Button" enum="HorizontalAlignment" default="0" />
+ <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
</members>
<theme_items>
- <theme_item name="check_vadjust" data_type="constant" type="int" default="0">
- The vertical offset used when rendering the check icons (in pixels).
- </theme_item>
- <theme_item name="checked" data_type="icon" type="Texture2D">
- The check icon to display when the [CheckBox] is checked.
- </theme_item>
- <theme_item name="checked_disabled" data_type="icon" type="Texture2D">
- The check icon to display when the [CheckBox] is checked and disabled.
- </theme_item>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckBox] is disabled.
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckBox] is focused.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- The [Font] to use for the [CheckBox] text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
The [CheckBox] text's font color.
</theme_item>
@@ -53,26 +35,26 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The [CheckBox] text's font color when it's pressed.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [CheckBox]'s text.
- </theme_item>
- <theme_item name="hover" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckBox] is hovered.
- </theme_item>
- <theme_item name="hover_pressed" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckBox] is hovered and pressed.
+ <theme_item name="check_vadjust" data_type="constant" type="int" default="0">
+ The vertical offset used when rendering the check icons (in pixels).
</theme_item>
<theme_item name="hseparation" data_type="constant" type="int" default="4">
The separation between the check icon and the text (in pixels).
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background.
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
- <theme_item name="pressed" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckBox] is pressed.
+ <theme_item name="font" data_type="font" type="Font">
+ The [Font] to use for the [CheckBox] text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [CheckBox]'s text.
+ </theme_item>
+ <theme_item name="checked" data_type="icon" type="Texture2D">
+ The check icon to display when the [CheckBox] is checked.
+ </theme_item>
+ <theme_item name="checked_disabled" data_type="icon" type="Texture2D">
+ The check icon to display when the [CheckBox] is checked and disabled.
</theme_item>
<theme_item name="radio_checked" data_type="icon" type="Texture2D">
If the [CheckBox] is configured as a radio button, the icon to display when the [CheckBox] is checked.
@@ -90,5 +72,23 @@
<theme_item name="unchecked_disabled" data_type="icon" type="Texture2D">
The check icon to display when the [CheckBox] is unchecked and disabled.
</theme_item>
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckBox] is disabled.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckBox] is focused.
+ </theme_item>
+ <theme_item name="hover" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckBox] is hovered.
+ </theme_item>
+ <theme_item name="hover_pressed" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckBox] is hovered and pressed.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background.
+ </theme_item>
+ <theme_item name="pressed" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckBox] is pressed.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml
index c86fadb6b0..cf3aa869c3 100644
--- a/doc/classes/CheckButton.xml
+++ b/doc/classes/CheckButton.xml
@@ -10,22 +10,10 @@
<tutorials>
</tutorials>
<members>
- <member name="align" type="int" setter="set_text_align" getter="get_text_align" override="true" enum="Button.TextAlign" default="0" />
- <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" override="true" default="true" />
+ <member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" overrides="Button" enum="HorizontalAlignment" default="0" />
+ <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
</members>
<theme_items>
- <theme_item name="check_vadjust" data_type="constant" type="int" default="0">
- The vertical offset used when rendering the toggle icons (in pixels).
- </theme_item>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckButton] is disabled.
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckButton] is focused.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- The [Font] to use for the [CheckButton] text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
The [CheckButton] text's font color.
</theme_item>
@@ -47,20 +35,20 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The [CheckButton] text's font color when it's pressed.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [CheckButton]'s text.
- </theme_item>
- <theme_item name="hover" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckButton] is hovered.
- </theme_item>
- <theme_item name="hover_pressed" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background when the [CheckButton] is hovered and pressed.
+ <theme_item name="check_vadjust" data_type="constant" type="int" default="0">
+ The vertical offset used when rendering the toggle icons (in pixels).
</theme_item>
<theme_item name="hseparation" data_type="constant" type="int" default="4">
The separation between the toggle icon and the text (in pixels).
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- The [StyleBox] to display as a background.
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ The [Font] to use for the [CheckButton] text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [CheckButton]'s text.
</theme_item>
<theme_item name="off" data_type="icon" type="Texture2D">
The icon to display when the [CheckButton] is unchecked (for left-to-right layouts).
@@ -86,8 +74,20 @@
<theme_item name="on_mirrored" data_type="icon" type="Texture2D">
The icon to display when the [CheckButton] is checked (for right-to-left layouts).
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckButton] is disabled.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckButton] is focused.
+ </theme_item>
+ <theme_item name="hover" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckButton] is hovered.
+ </theme_item>
+ <theme_item name="hover_pressed" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background when the [CheckButton] is hovered and pressed.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ The [StyleBox] to display as a background.
</theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
The [StyleBox] to display as a background when the [CheckButton] is pressed.
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index bb1a4a79f0..04c3d73357 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -487,7 +487,7 @@
<member name="indent_use_spaces" type="bool" setter="set_indent_using_spaces" getter="is_indent_using_spaces" default="false">
Use spaces instead of tabs for indentation.
</member>
- <member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" override="true" enum="Control.LayoutDirection" default="2" />
+ <member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" overrides="Control" enum="Control.LayoutDirection" default="2" />
<member name="line_folding" type="bool" setter="set_line_folding_enabled" getter="is_line_folding_enabled" default="false">
Sets whether line folding is allowed.
</member>
@@ -497,7 +497,7 @@
<member name="symbol_lookup_on_click" type="bool" setter="set_symbol_lookup_on_click_enabled" getter="is_symbol_lookup_on_click_enabled" default="false">
Set when a validated word from [signal symbol_validate] is clicked, the [signal symbol_lookup] should be emitted.
</member>
- <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" override="true" enum="Control.TextDirection" default="1" />
+ <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" overrides="TextEdit" enum="Control.TextDirection" default="1" />
</members>
<signals>
<signal name="breakpoint_toggled">
@@ -562,24 +562,15 @@
<theme_item name="background_color" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
Sets the background [Color].
</theme_item>
- <theme_item name="bookmark" data_type="icon" type="Texture2D">
- Sets a custom [Texture2D] to draw in the bookmark gutter for bookmarked lines.
- </theme_item>
<theme_item name="bookmark_color" data_type="color" type="Color" default="Color(0.5, 0.64, 1, 0.8)">
[Color] of the bookmark icon for bookmarked lines.
</theme_item>
<theme_item name="brace_mismatch_color" data_type="color" type="Color" default="Color(1, 0.2, 0.2, 1)">
[Color] of the text to highlight mismatched braces.
</theme_item>
- <theme_item name="breakpoint" data_type="icon" type="Texture2D">
- Sets a custom [Texture2D] to draw in the breakpoint gutter for breakpointed lines.
- </theme_item>
<theme_item name="breakpoint_color" data_type="color" type="Color" default="Color(0.9, 0.29, 0.3, 1)">
[Color] of the breakpoint icon for bookmarked lines.
</theme_item>
- <theme_item name="can_fold" data_type="icon" type="Texture2D">
- Sets a custom [Texture2D] to draw in the line folding gutter when a line can be folded.
- </theme_item>
<theme_item name="caret_background_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
[Color] of the text behind the caret when block caret is enabled.
</theme_item>
@@ -589,9 +580,6 @@
<theme_item name="code_folding_color" data_type="color" type="Color" default="Color(0.8, 0.8, 0.8, 0.8)">
[Color] for all icons related to line folding.
</theme_item>
- <theme_item name="completion" data_type="style" type="StyleBox">
- [StyleBox] for the code completion popup.
- </theme_item>
<theme_item name="completion_background_color" data_type="color" type="Color" default="Color(0.17, 0.16, 0.2, 1)">
Sets the background [Color] for the code completion popup.
</theme_item>
@@ -601,42 +589,18 @@
<theme_item name="completion_font_color" data_type="color" type="Color" default="Color(0.67, 0.67, 0.67, 1)">
Font [Color] for the code completion popup.
</theme_item>
- <theme_item name="completion_lines" data_type="constant" type="int" default="7">
- Max number of options to display in the code completion popup at any one time.
- </theme_item>
- <theme_item name="completion_max_width" data_type="constant" type="int" default="50">
- Max width of options in the code completion popup. Options longer then this will be cut off.
- </theme_item>
<theme_item name="completion_scroll_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
[Color] of the scrollbar in the code completion popup.
</theme_item>
- <theme_item name="completion_scroll_width" data_type="constant" type="int" default="3">
- Width of the scrollbar in the code completion popup.
- </theme_item>
<theme_item name="completion_selected_color" data_type="color" type="Color" default="Color(0.26, 0.26, 0.27, 1)">
Background highlight [Color] for the current selected option item in the code completion popup.
</theme_item>
<theme_item name="current_line_color" data_type="color" type="Color" default="Color(0.25, 0.25, 0.26, 0.8)">
Background [Color] of the line containing the caret.
</theme_item>
- <theme_item name="executing_line" data_type="icon" type="Texture2D">
- Icon to draw in the executing gutter for executing lines.
- </theme_item>
<theme_item name="executing_line_color" data_type="color" type="Color" default="Color(0.98, 0.89, 0.27, 1)">
[Color] of the executing icon for executing lines.
</theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- Sets the [StyleBox] when in focus.
- </theme_item>
- <theme_item name="folded" data_type="icon" type="Texture2D">
- Sets a custom [Texture2D] to draw in the line folding gutter when a line is folded and can be unfolded.
- </theme_item>
- <theme_item name="folded_eol_icon" data_type="icon" type="Texture2D">
- Sets a custom [Texture2D] to draw at the end of a folded line.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- Sets the default [Font].
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Sets the font [Color].
</theme_item>
@@ -649,35 +613,62 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Sets the [Color] of the selected text. [member TextEdit.override_selected_font_color] has to be enabled.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Sets default font size.
- </theme_item>
<theme_item name="line_length_guideline_color" data_type="color" type="Color" default="Color(0.3, 0.5, 0.8, 0.1)">
[Color] of the main line length guideline, secondary guidelines will have 50% alpha applied.
</theme_item>
<theme_item name="line_number_color" data_type="color" type="Color" default="Color(0.67, 0.67, 0.67, 0.4)">
Sets the [Color] of line numbers.
</theme_item>
+ <theme_item name="search_result_border_color" data_type="color" type="Color" default="Color(0.3, 0.3, 0.3, 0.4)">
+ [Color] of the border around text that matches the search query.
+ </theme_item>
+ <theme_item name="search_result_color" data_type="color" type="Color" default="Color(0.3, 0.3, 0.3, 1)">
+ [Color] behind the text that matches the search query.
+ </theme_item>
+ <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)">
+ Sets the highlight [Color] of text selections.
+ </theme_item>
+ <theme_item name="word_highlighted_color" data_type="color" type="Color" default="Color(0.8, 0.9, 0.9, 0.15)">
+ Sets the highlight [Color] of multiple occurrences. [member TextEdit.highlight_all_occurrences] has to be enabled.
+ </theme_item>
+ <theme_item name="completion_lines" data_type="constant" type="int" default="7">
+ Max number of options to display in the code completion popup at any one time.
+ </theme_item>
+ <theme_item name="completion_max_width" data_type="constant" type="int" default="50">
+ Max width of options in the code completion popup. Options longer then this will be cut off.
+ </theme_item>
+ <theme_item name="completion_scroll_width" data_type="constant" type="int" default="3">
+ Width of the scrollbar in the code completion popup.
+ </theme_item>
<theme_item name="line_spacing" data_type="constant" type="int" default="4">
Sets the spacing between the lines.
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- Sets the [StyleBox].
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
- <theme_item name="read_only" data_type="style" type="StyleBox">
- Sets the [StyleBox] when [member TextEdit.editable] is disabled.
+ <theme_item name="font" data_type="font" type="Font">
+ Sets the default [Font].
</theme_item>
- <theme_item name="search_result_border_color" data_type="color" type="Color" default="Color(0.3, 0.3, 0.3, 0.4)">
- [Color] of the border around text that matches the search query.
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Sets default font size.
</theme_item>
- <theme_item name="search_result_color" data_type="color" type="Color" default="Color(0.3, 0.3, 0.3, 1)">
- [Color] behind the text that matches the search query.
+ <theme_item name="bookmark" data_type="icon" type="Texture2D">
+ Sets a custom [Texture2D] to draw in the bookmark gutter for bookmarked lines.
</theme_item>
- <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)">
- Sets the highlight [Color] of text selections.
+ <theme_item name="breakpoint" data_type="icon" type="Texture2D">
+ Sets a custom [Texture2D] to draw in the breakpoint gutter for breakpointed lines.
+ </theme_item>
+ <theme_item name="can_fold" data_type="icon" type="Texture2D">
+ Sets a custom [Texture2D] to draw in the line folding gutter when a line can be folded.
+ </theme_item>
+ <theme_item name="executing_line" data_type="icon" type="Texture2D">
+ Icon to draw in the executing gutter for executing lines.
+ </theme_item>
+ <theme_item name="folded" data_type="icon" type="Texture2D">
+ Sets a custom [Texture2D] to draw in the line folding gutter when a line is folded and can be unfolded.
+ </theme_item>
+ <theme_item name="folded_eol_icon" data_type="icon" type="Texture2D">
+ Sets a custom [Texture2D] to draw at the end of a folded line.
</theme_item>
<theme_item name="space" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] for space text characters.
@@ -685,8 +676,17 @@
<theme_item name="tab" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] for tab text characters.
</theme_item>
- <theme_item name="word_highlighted_color" data_type="color" type="Color" default="Color(0.8, 0.9, 0.9, 0.15)">
- Sets the highlight [Color] of multiple occurrences. [member TextEdit.highlight_all_occurrences] has to be enabled.
+ <theme_item name="completion" data_type="style" type="StyleBox">
+ [StyleBox] for the code completion popup.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ Sets the [StyleBox] when in focus.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ Sets the [StyleBox].
+ </theme_item>
+ <theme_item name="read_only" data_type="style" type="StyleBox">
+ Sets the [StyleBox] when [member TextEdit.editable] is disabled.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index fca6a7631a..22439f6ca5 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -93,6 +93,20 @@
</constant>
</constants>
<theme_items>
+ <theme_item name="h_width" data_type="constant" type="int" default="30">
+ The width of the hue selection slider.
+ </theme_item>
+ <theme_item name="label_width" data_type="constant" type="int" default="10">
+ </theme_item>
+ <theme_item name="margin" data_type="constant" type="int" default="4">
+ The margin around the [ColorPicker].
+ </theme_item>
+ <theme_item name="sv_height" data_type="constant" type="int" default="256">
+ The height of the saturation-value selection box.
+ </theme_item>
+ <theme_item name="sv_width" data_type="constant" type="int" default="256">
+ The width of the saturation-value selection box.
+ </theme_item>
<theme_item name="add_preset" data_type="icon" type="Texture2D">
The icon for the "Add Preset" button.
</theme_item>
@@ -104,14 +118,6 @@
</theme_item>
<theme_item name="color_sample" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="h_width" data_type="constant" type="int" default="30">
- The width of the hue selection slider.
- </theme_item>
- <theme_item name="label_width" data_type="constant" type="int" default="10">
- </theme_item>
- <theme_item name="margin" data_type="constant" type="int" default="4">
- The margin around the [ColorPicker].
- </theme_item>
<theme_item name="overbright_indicator" data_type="icon" type="Texture2D">
The indicator used to signalize that the color value is outside the 0-1 range.
</theme_item>
@@ -122,11 +128,5 @@
<theme_item name="screen_picker" data_type="icon" type="Texture2D">
The icon for the screen color picker button.
</theme_item>
- <theme_item name="sv_height" data_type="constant" type="int" default="256">
- The height of the saturation-value selection box.
- </theme_item>
- <theme_item name="sv_width" data_type="constant" type="int" default="256">
- The width of the saturation-value selection box.
- </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index fff27d2d56..2f78b10660 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -35,7 +35,7 @@
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha" default="true">
If [code]true[/code], the alpha channel in the displayed [ColorPicker] will be visible.
</member>
- <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" override="true" default="true" />
+ <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
</members>
<signals>
<signal name="color_changed">
@@ -56,18 +56,6 @@
</signal>
</signals>
<theme_items>
- <theme_item name="bg" data_type="icon" type="Texture2D">
- The background of the color preview rect on the button.
- </theme_item>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- [StyleBox] used when the [ColorPickerButton] is disabled.
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [ColorPickerButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the [ColorPickerButton]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Default text [Color] of the [ColorPickerButton].
</theme_item>
@@ -86,21 +74,33 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(0.8, 0.8, 0.8, 1)">
Text [Color] used when the [ColorPickerButton] is being pressed.
</theme_item>
+ <theme_item name="hseparation" data_type="constant" type="int" default="2">
+ The horizontal space between [ColorPickerButton]'s icon and text.
+ </theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the [ColorPickerButton]'s text.
+ </theme_item>
<theme_item name="font_size" data_type="font_size" type="int">
Font size of the [ColorPickerButton]'s text.
</theme_item>
+ <theme_item name="bg" data_type="icon" type="Texture2D">
+ The background of the color preview rect on the button.
+ </theme_item>
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ [StyleBox] used when the [ColorPickerButton] is disabled.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [ColorPickerButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
+ </theme_item>
<theme_item name="hover" data_type="style" type="StyleBox">
[StyleBox] used when the [ColorPickerButton] is being hovered.
</theme_item>
- <theme_item name="hseparation" data_type="constant" type="int" default="2">
- The horizontal space between [ColorPickerButton]'s icon and text.
- </theme_item>
<theme_item name="normal" data_type="style" type="StyleBox">
Default [StyleBox] for the [ColorPickerButton].
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
- </theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [ColorPickerButton] is being pressed.
</theme_item>
diff --git a/doc/classes/ConfirmationDialog.xml b/doc/classes/ConfirmationDialog.xml
index c4bdaf436d..bf4210ac98 100644
--- a/doc/classes/ConfirmationDialog.xml
+++ b/doc/classes/ConfirmationDialog.xml
@@ -27,8 +27,8 @@
</method>
</methods>
<members>
- <member name="min_size" type="Vector2i" setter="set_min_size" getter="get_min_size" override="true" default="Vector2i(200, 70)" />
- <member name="size" type="Vector2i" setter="set_size" getter="get_size" override="true" default="Vector2i(200, 100)" />
- <member name="title" type="String" setter="set_title" getter="get_title" override="true" default="&quot;Please Confirm...&quot;" />
+ <member name="min_size" type="Vector2i" setter="set_min_size" getter="get_min_size" overrides="Window" default="Vector2i(200, 70)" />
+ <member name="size" type="Vector2i" setter="set_size" getter="get_size" overrides="Window" default="Vector2i(200, 100)" />
+ <member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Please Confirm...&quot;" />
</members>
</class>
diff --git a/doc/classes/Container.xml b/doc/classes/Container.xml
index 24e73534d3..83655425fc 100644
--- a/doc/classes/Container.xml
+++ b/doc/classes/Container.xml
@@ -26,7 +26,7 @@
</method>
</methods>
<members>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="1" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
</members>
<signals>
<signal name="pre_sort_children">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 8739e0157d..ed6a71d5c3 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -666,12 +666,6 @@
Returns [code]true[/code] if layout is right-to-left.
</description>
</method>
- <method name="minimum_size_changed">
- <return type="void" />
- <description>
- Invalidates the size cache in this node and in parent nodes up to top_level. Intended to be used with [method get_minimum_size] when the return value is changed. Setting [member rect_min_size] directly calls this method automatically.
- </description>
- </method>
<method name="release_focus">
<return type="void" />
<description>
@@ -933,6 +927,12 @@
If [code]keep_offsets[/code] is [code]true[/code], control's anchors will be updated instead of offsets.
</description>
</method>
+ <method name="update_minimum_size">
+ <return type="void" />
+ <description>
+ Invalidates the size cache in this node and in parent nodes up to top level. Intended to be used with [method get_minimum_size] when the return value is changed. Setting [member rect_min_size] directly calls this method automatically.
+ </description>
+ </method>
<method name="warp_mouse">
<return type="void" />
<argument index="0" name="to_position" type="Vector2" />
diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml
index 661dbef07c..74450c311e 100644
--- a/doc/classes/DirectionalLight3D.xml
+++ b/doc/classes/DirectionalLight3D.xml
@@ -34,7 +34,7 @@
<member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5">
The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS].
</member>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" />
+ <member name="shadow_bias" type="float" setter="set_param" getter="get_param" overrides="Light3D" default="0.1" />
<member name="use_in_sky_only" type="bool" setter="set_sky_only" getter="is_sky_only" default="false">
If [code]true[/code], this [DirectionalLight3D] will not be used for anything except sky shaders. Use this for lights that impact your sky shader that you may want to hide from affecting the rest of the scene. For example, you may want to enable this when the sun in your sky shader falls below the horizon.
</member>
diff --git a/doc/classes/EditorCommandPalette.xml b/doc/classes/EditorCommandPalette.xml
index 01b8593f89..28f51228ca 100644
--- a/doc/classes/EditorCommandPalette.xml
+++ b/doc/classes/EditorCommandPalette.xml
@@ -49,6 +49,6 @@
</method>
</methods>
<members>
- <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" override="true" default="false" />
+ <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
</members>
</class>
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
index 79758281ac..1d2146348a 100644
--- a/doc/classes/EditorFileDialog.xml
+++ b/doc/classes/EditorFileDialog.xml
@@ -49,7 +49,7 @@
<member name="current_path" type="String" setter="set_current_path" getter="get_current_path" default="&quot;res://&quot;">
The file system path in the address bar.
</member>
- <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" override="true" default="false" />
+ <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
<member name="disable_overwrite_warning" type="bool" setter="set_disable_overwrite_warning" getter="is_overwrite_warning_disabled" default="false">
If [code]true[/code], the [EditorFileDialog] will not warn the user before overwriting files.
</member>
@@ -62,7 +62,7 @@
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files" default="false">
If [code]true[/code], hidden files and directories will be visible in the [EditorFileDialog].
</member>
- <member name="title" type="String" setter="set_title" getter="get_title" override="true" default="&quot;Save a File&quot;" />
+ <member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Save a File&quot;" />
</members>
<signals>
<signal name="dir_selected">
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 0c47298180..dbfbaf103d 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -10,7 +10,7 @@
<tutorials>
</tutorials>
<members>
- <member name="scroll_horizontal_enabled" type="bool" setter="set_enable_h_scroll" getter="is_h_scroll_enabled" override="true" default="false" />
+ <member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" overrides="ScrollContainer" enum="ScrollContainer.ScrollMode" default="0" />
</members>
<signals>
<signal name="object_id_selected">
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 5790d8c5af..15d31cd0f0 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -21,7 +21,17 @@
<return type="void" />
<argument index="0" name="resource" type="Resource" />
<description>
- Edits the given [Resource].
+ Edits the given [Resource]. If the resource is a [Script] you can also edit it with [method edit_script] to specify the line and column position.
+ </description>
+ </method>
+ <method name="edit_script">
+ <return type="void" />
+ <argument index="0" name="script" type="Script" />
+ <argument index="1" name="line" type="int" default="-1" />
+ <argument index="2" name="column" type="int" default="0" />
+ <argument index="3" name="grab_focus" type="bool" default="true" />
+ <description>
+ Edits the given [Script]. The line and column on which to open the script can also be specified. The script will be open with the user-configured editor for the script's language which may be an external editor.
</description>
</method>
<method name="get_base_control">
diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml
index c804bb70e0..60c329935a 100644
--- a/doc/classes/EditorNode3DGizmo.xml
+++ b/doc/classes/EditorNode3DGizmo.xml
@@ -135,7 +135,7 @@
</method>
<method name="add_mesh">
<return type="void" />
- <argument index="0" name="mesh" type="ArrayMesh" />
+ <argument index="0" name="mesh" type="Mesh" />
<argument index="1" name="material" type="Material" default="null" />
<argument index="2" name="transform" type="Transform3D" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)" />
<argument index="3" name="skeleton" type="SkinReference" default="null" />
diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml
index 9341b514c7..9636c33565 100644
--- a/doc/classes/EditorSpinSlider.xml
+++ b/doc/classes/EditorSpinSlider.xml
@@ -11,7 +11,7 @@
<members>
<member name="flat" type="bool" setter="set_flat" getter="is_flat" default="false">
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="label" type="String" setter="set_label" getter="get_label" default="&quot;&quot;">
</member>
<member name="read_only" type="bool" setter="set_read_only" getter="is_read_only" default="false">
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index 9756b26dee..d0c4d28c55 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -187,7 +187,8 @@
[b]Note:[/b] For best results, when using a custom physics interpolation solution, the physics jitter fix should be disabled by setting [member physics_jitter_fix] to [code]0[/code].
</member>
<member name="physics_ticks_per_second" type="int" setter="set_physics_ticks_per_second" getter="get_physics_ticks_per_second" default="60">
- The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. This value should generally always be set to [code]60[/code] or above, as Godot doesn't interpolate the physics step. As a result, values lower than [code]60[/code] will look stuttery. This value can be increased to make input more reactive or work around tunneling issues, but keep in mind doing so will increase CPU usage. See also [member target_fps].
+ The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. This value should generally always be set to [code]60[/code] or above, as Godot doesn't interpolate the physics step. As a result, values lower than [code]60[/code] will look stuttery. This value can be increased to make input more reactive or work around collision tunneling issues, but keep in mind doing so will increase CPU usage. See also [member target_fps] and [member ProjectSettings.physics/common/physics_ticks_per_second].
+ [b]Note:[/b] Only 8 physics ticks may be simulated per rendered frame at most. If more than 8 physics ticks have to be simulated per rendered frame to keep up with rendering, the game will appear to slow down (even if [code]delta[/code] is used consistently in physics calculations). Therefore, it is recommended not to increase [member physics_ticks_per_second] above 240. Otherwise, the game will slow down when the rendering framerate goes below 30 FPS.
</member>
<member name="print_error_messages" type="bool" setter="set_print_error_messages" getter="is_printing_error_messages" default="true">
If [code]false[/code], stops printing error and warning messages to the console and editor Output log. This can be used to hide error and warning messages during unit test suite runs. This property is equivalent to the [member ProjectSettings.application/run/disable_stderr] project setting.
@@ -195,7 +196,7 @@
[b]Note:[/b] This property does not impact the editor's Errors tab when running a project from the editor.
</member>
<member name="target_fps" type="int" setter="set_target_fps" getter="get_target_fps" default="0">
- The desired frames per second. If the hardware cannot keep up, this setting may not be respected. A value of 0 means no limit. See also [member physics_ticks_per_second].
+ The desired frames per second. If the hardware cannot keep up, this setting may not be respected. A value of 0 means no limit. See also [member physics_ticks_per_second] and [member ProjectSettings.debug/settings/fps/force_fps].
</member>
<member name="time_scale" type="float" setter="set_time_scale" getter="get_time_scale" default="1.0">
Controls how fast or slow the in-game clock ticks versus the real life one. It defaults to 1.0. A value of 2.0 means the game moves twice as fast as real life, whilst a value of 0.5 means the game moves at half the regular speed.
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index 276c1f0223..0dac9a379a 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -417,6 +417,7 @@
<argument index="0" name="string" type="String" />
<description>
Appends [code]string[/code] to the file without a line return, encoding the text as UTF-8.
+ [b]Note:[/b] This method is intended to be used to write text files. The string is stored as a UTF-8 encoded buffer without string length or terminating zero, which means that it can't be loaded back easily. If you want to store a retrievable string in a binary file, consider using [method store_pascal_string] instead. For retrieving strings from a text file, you can use [code]get_buffer(length).get_string_from_utf8()[/code] (if you know the length) or [method get_as_text].
</description>
</method>
<method name="store_var">
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index fa43f97104..1207288159 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -63,7 +63,7 @@
<member name="current_path" type="String" setter="set_current_path" getter="get_current_path" default="&quot;res://&quot;">
The currently selected file path of the file dialog.
</member>
- <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" override="true" default="false" />
+ <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
<member name="file_mode" type="int" setter="set_file_mode" getter="get_file_mode" enum="FileDialog.FileMode" default="4">
The dialog's open or save mode, which affects the selection behavior. See [enum FileMode].
</member>
@@ -76,7 +76,7 @@
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files" default="false">
If [code]true[/code], the dialog will show hidden files.
</member>
- <member name="title" type="String" setter="set_title" getter="get_title" override="true" default="&quot;Save a File&quot;" />
+ <member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Save a File&quot;" />
</members>
<signals>
<signal name="dir_selected">
@@ -125,24 +125,24 @@
</constant>
</constants>
<theme_items>
- <theme_item name="back_folder" data_type="icon" type="Texture2D">
- Custom icon for the back arrow.
- </theme_item>
- <theme_item name="file" data_type="icon" type="Texture2D">
- Custom icon for files.
- </theme_item>
<theme_item name="file_icon_modulate" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The color modulation applied to the file icon.
</theme_item>
<theme_item name="files_disabled" data_type="color" type="Color" default="Color(0, 0, 0, 0.7)">
The color tint for disabled files (when the [FileDialog] is used in open folder mode).
</theme_item>
- <theme_item name="folder" data_type="icon" type="Texture2D">
- Custom icon for folders.
- </theme_item>
<theme_item name="folder_icon_modulate" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The color modulation applied to the folder icon.
</theme_item>
+ <theme_item name="back_folder" data_type="icon" type="Texture2D">
+ Custom icon for the back arrow.
+ </theme_item>
+ <theme_item name="file" data_type="icon" type="Texture2D">
+ Custom icon for files.
+ </theme_item>
+ <theme_item name="folder" data_type="icon" type="Texture2D">
+ Custom icon for folders.
+ </theme_item>
<theme_item name="forward_folder" data_type="icon" type="Texture2D">
Custom icon for the forward arrow.
</theme_item>
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index 01bc2837f1..275d6b6577 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -96,7 +96,7 @@
<argument index="0" name="canvas_item" type="RID" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="text" type="String" />
- <argument index="3" name="align" type="int" enum="HAlign" default="0" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
<argument index="5" name="max_lines" type="int" default="-1" />
<argument index="6" name="size" type="int" default="16" />
@@ -114,7 +114,7 @@
<argument index="0" name="canvas_item" type="RID" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="text" type="String" />
- <argument index="3" name="align" type="int" enum="HAlign" default="0" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
<argument index="5" name="size" type="int" default="16" />
<argument index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
@@ -202,7 +202,7 @@
<return type="Vector2" />
<argument index="0" name="text" type="String" />
<argument index="1" name="size" type="int" default="16" />
- <argument index="2" name="align" type="int" enum="HAlign" default="0" />
+ <argument index="2" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="3" name="width" type="float" default="-1" />
<argument index="4" name="flags" type="int" default="3" />
<description>
diff --git a/doc/classes/GPUParticlesAttractorBox.xml b/doc/classes/GPUParticlesAttractorBox3D.xml
index 93fdc45e56..0795e11b16 100644
--- a/doc/classes/GPUParticlesAttractorBox.xml
+++ b/doc/classes/GPUParticlesAttractorBox3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesAttractorBox" inherits="GPUParticlesAttractor3D" version="4.0">
+<class name="GPUParticlesAttractorBox3D" inherits="GPUParticlesAttractor3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/GPUParticlesAttractorSphere.xml b/doc/classes/GPUParticlesAttractorSphere3D.xml
index 4398de55e9..590c966d70 100644
--- a/doc/classes/GPUParticlesAttractorSphere.xml
+++ b/doc/classes/GPUParticlesAttractorSphere3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesAttractorSphere" inherits="GPUParticlesAttractor3D" version="4.0">
+<class name="GPUParticlesAttractorSphere3D" inherits="GPUParticlesAttractor3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/GPUParticlesAttractorVectorField.xml b/doc/classes/GPUParticlesAttractorVectorField3D.xml
index e164343528..d0dbf886f6 100644
--- a/doc/classes/GPUParticlesAttractorVectorField.xml
+++ b/doc/classes/GPUParticlesAttractorVectorField3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesAttractorVectorField" inherits="GPUParticlesAttractor3D" version="4.0">
+<class name="GPUParticlesAttractorVectorField3D" inherits="GPUParticlesAttractor3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/GPUParticlesCollisionBox.xml b/doc/classes/GPUParticlesCollisionBox3D.xml
index d2bf4ef538..e899637206 100644
--- a/doc/classes/GPUParticlesCollisionBox.xml
+++ b/doc/classes/GPUParticlesCollisionBox3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesCollisionBox" inherits="GPUParticlesCollision3D" version="4.0">
+<class name="GPUParticlesCollisionBox3D" inherits="GPUParticlesCollision3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/GPUParticlesCollisionHeightField.xml b/doc/classes/GPUParticlesCollisionHeightField3D.xml
index 99b2ad3ce0..801120d911 100644
--- a/doc/classes/GPUParticlesCollisionHeightField.xml
+++ b/doc/classes/GPUParticlesCollisionHeightField3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesCollisionHeightField" inherits="GPUParticlesCollision3D" version="4.0">
+<class name="GPUParticlesCollisionHeightField3D" inherits="GPUParticlesCollision3D" version="4.0">
<brief_description>
</brief_description>
<description>
@@ -13,9 +13,9 @@
</member>
<member name="follow_camera_push_ratio" type="float" setter="set_follow_camera_push_ratio" getter="get_follow_camera_push_ratio" default="0.1">
</member>
- <member name="resolution" type="int" setter="set_resolution" getter="get_resolution" enum="GPUParticlesCollisionHeightField.Resolution" default="2">
+ <member name="resolution" type="int" setter="set_resolution" getter="get_resolution" enum="GPUParticlesCollisionHeightField3D.Resolution" default="2">
</member>
- <member name="update_mode" type="int" setter="set_update_mode" getter="get_update_mode" enum="GPUParticlesCollisionHeightField.UpdateMode" default="0">
+ <member name="update_mode" type="int" setter="set_update_mode" getter="get_update_mode" enum="GPUParticlesCollisionHeightField3D.UpdateMode" default="0">
</member>
</members>
<constants>
diff --git a/doc/classes/GPUParticlesCollisionSDF.xml b/doc/classes/GPUParticlesCollisionSDF3D.xml
index 8d798a9d28..9e86d16eef 100644
--- a/doc/classes/GPUParticlesCollisionSDF.xml
+++ b/doc/classes/GPUParticlesCollisionSDF3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesCollisionSDF" inherits="GPUParticlesCollision3D" version="4.0">
+<class name="GPUParticlesCollisionSDF3D" inherits="GPUParticlesCollision3D" version="4.0">
<brief_description>
</brief_description>
<description>
@@ -9,7 +9,7 @@
<members>
<member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3(1, 1, 1)">
</member>
- <member name="resolution" type="int" setter="set_resolution" getter="get_resolution" enum="GPUParticlesCollisionSDF.Resolution" default="2">
+ <member name="resolution" type="int" setter="set_resolution" getter="get_resolution" enum="GPUParticlesCollisionSDF3D.Resolution" default="2">
</member>
<member name="texture" type="Texture3D" setter="set_texture" getter="get_texture">
</member>
diff --git a/doc/classes/GPUParticlesCollisionSphere.xml b/doc/classes/GPUParticlesCollisionSphere3D.xml
index ddb2391fd9..82728f853b 100644
--- a/doc/classes/GPUParticlesCollisionSphere.xml
+++ b/doc/classes/GPUParticlesCollisionSphere3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GPUParticlesCollisionSphere" inherits="GPUParticlesCollision3D" version="4.0">
+<class name="GPUParticlesCollisionSphere3D" inherits="GPUParticlesCollision3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index e962992491..76b255e273 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -159,7 +159,7 @@
<member name="connection_lines_thickness" type="float" setter="set_connection_lines_thickness" getter="get_connection_lines_thickness" default="2.0">
The thickness of the lines between the nodes.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="minimap_enabled" type="bool" setter="set_minimap_enabled" getter="is_minimap_enabled" default="true">
If [code]true[/code], the minimap is visible.
</member>
@@ -169,7 +169,7 @@
<member name="minimap_size" type="Vector2" setter="set_minimap_size" getter="get_minimap_size" default="Vector2(240, 160)">
The size of the minimap rectangle. The map itself is based on the size of the grid area and is scaled to fit this rectangle.
</member>
- <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
+ <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="right_disconnects" type="bool" setter="set_right_disconnects" getter="is_right_disconnects_enabled" default="false">
If [code]true[/code], enables disconnection of existing connections in the GraphEdit by dragging the right end.
</member>
@@ -290,28 +290,21 @@
<theme_items>
<theme_item name="activity" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
</theme_item>
- <theme_item name="bezier_len_neg" data_type="constant" type="int" default="160">
- </theme_item>
- <theme_item name="bezier_len_pos" data_type="constant" type="int" default="80">
- </theme_item>
- <theme_item name="bg" data_type="style" type="StyleBox">
- The background drawn under the grid.
- </theme_item>
<theme_item name="grid_major" data_type="color" type="Color" default="Color(1, 1, 1, 0.2)">
Color of major grid lines.
</theme_item>
<theme_item name="grid_minor" data_type="color" type="Color" default="Color(1, 1, 1, 0.05)">
Color of minor grid lines.
</theme_item>
- <theme_item name="layout" data_type="icon" type="Texture2D">
+ <theme_item name="selection_fill" data_type="color" type="Color" default="Color(1, 1, 1, 0.3)">
+ The fill color of the selection rectangle.
</theme_item>
- <theme_item name="minimap" data_type="icon" type="Texture2D">
+ <theme_item name="selection_stroke" data_type="color" type="Color" default="Color(1, 1, 1, 0.8)">
+ The outline color of the selection rectangle.
</theme_item>
- <theme_item name="minus" data_type="icon" type="Texture2D">
- The icon for the zoom out button.
+ <theme_item name="bezier_len_neg" data_type="constant" type="int" default="160">
</theme_item>
- <theme_item name="more" data_type="icon" type="Texture2D">
- The icon for the zoom in button.
+ <theme_item name="bezier_len_pos" data_type="constant" type="int" default="80">
</theme_item>
<theme_item name="port_grab_distance_horizontal" data_type="constant" type="int" default="24">
The horizontal range within which a port can be grabbed (on both sides).
@@ -319,17 +312,24 @@
<theme_item name="port_grab_distance_vertical" data_type="constant" type="int" default="6">
The vertical range within which a port can be grabbed (on both sides).
</theme_item>
- <theme_item name="reset" data_type="icon" type="Texture2D">
- The icon for the zoom reset button.
+ <theme_item name="layout" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="selection_fill" data_type="color" type="Color" default="Color(1, 1, 1, 0.3)">
- The fill color of the selection rectangle.
+ <theme_item name="minimap" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="selection_stroke" data_type="color" type="Color" default="Color(1, 1, 1, 0.8)">
- The outline color of the selection rectangle.
+ <theme_item name="minus" data_type="icon" type="Texture2D">
+ The icon for the zoom out button.
+ </theme_item>
+ <theme_item name="more" data_type="icon" type="Texture2D">
+ The icon for the zoom in button.
+ </theme_item>
+ <theme_item name="reset" data_type="icon" type="Texture2D">
+ The icon for the zoom reset button.
</theme_item>
<theme_item name="snap" data_type="icon" type="Texture2D">
The icon for the snap toggle button.
</theme_item>
+ <theme_item name="bg" data_type="style" type="StyleBox">
+ The background drawn under the grid.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index e9226f7c1d..d5780dce2d 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -218,7 +218,7 @@
<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" override="true" enum="Control.MouseFilter" default="0" />
+ <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>
@@ -292,18 +292,42 @@
</constant>
</constants>
<theme_items>
- <theme_item name="breakpoint" data_type="style" type="StyleBox">
- The background used when [member overlay] is set to [constant OVERLAY_BREAKPOINT].
- </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="close_color" data_type="color" type="Color" default="Color(0, 0, 0, 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, 0, 0, 1)">
+ The color modulation applied to the resizer icon.
+ </theme_item>
+ <theme_item name="title_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
+ Color of the title text.
+ </theme_item>
<theme_item name="close_offset" data_type="constant" type="int" default="18">
The vertical offset of the close button.
</theme_item>
+ <theme_item name="port_offset" data_type="constant" type="int" default="3">
+ Horizontal offset for the ports.
+ </theme_item>
+ <theme_item name="separation" data_type="constant" type="int" default="1">
+ The vertical distance between ports.
+ </theme_item>
+ <theme_item name="title_offset" data_type="constant" type="int" default="20">
+ 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].
+ </theme_item>
<theme_item name="comment" data_type="style" type="StyleBox">
The [StyleBox] used when [member comment] is enabled.
</theme_item>
@@ -317,35 +341,11 @@
<theme_item name="frame" data_type="style" type="StyleBox">
The default background for [GraphNode].
</theme_item>
- <theme_item name="port" data_type="icon" type="Texture2D">
- The icon used for representing ports.
- </theme_item>
- <theme_item name="port_offset" data_type="constant" type="int" default="3">
- Horizontal offset for the ports.
- </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="resizer" data_type="icon" type="Texture2D">
- The icon used for resizer, visible when [member resizable] is enabled.
- </theme_item>
- <theme_item name="resizer_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
- The color modulation applied to the resizer icon.
- </theme_item>
<theme_item name="selectedframe" data_type="style" type="StyleBox">
The background used when the [GraphNode] is selected.
</theme_item>
- <theme_item name="separation" data_type="constant" type="int" default="1">
- The vertical distance between ports.
- </theme_item>
- <theme_item name="title_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
- Color 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="title_offset" data_type="constant" type="int" default="20">
- Vertical offset of the title text.
- </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/HScrollBar.xml b/doc/classes/HScrollBar.xml
index fa9961710f..3197abcc3f 100644
--- a/doc/classes/HScrollBar.xml
+++ b/doc/classes/HScrollBar.xml
@@ -18,15 +18,6 @@
<theme_item name="decrement_pressed" data_type="icon" type="Texture2D">
Displayed when the decrement button is being pressed.
</theme_item>
- <theme_item name="grabber" data_type="style" type="StyleBox">
- Used as texture for the grabber, the draggable element representing current scroll.
- </theme_item>
- <theme_item name="grabber_highlight" data_type="style" type="StyleBox">
- Used when the mouse hovers over the grabber.
- </theme_item>
- <theme_item name="grabber_pressed" data_type="style" type="StyleBox">
- Used when the grabber is being dragged.
- </theme_item>
<theme_item name="increment" data_type="icon" type="Texture2D">
Icon used as a button to scroll the [ScrollBar] right. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
@@ -36,6 +27,15 @@
<theme_item name="increment_pressed" data_type="icon" type="Texture2D">
Displayed when the increment button is being pressed.
</theme_item>
+ <theme_item name="grabber" data_type="style" type="StyleBox">
+ Used as texture for the grabber, the draggable element representing current scroll.
+ </theme_item>
+ <theme_item name="grabber_highlight" data_type="style" type="StyleBox">
+ Used when the mouse hovers over the grabber.
+ </theme_item>
+ <theme_item name="grabber_pressed" data_type="style" type="StyleBox">
+ Used when the grabber is being dragged.
+ </theme_item>
<theme_item name="scroll" data_type="style" type="StyleBox">
Used as background of this [ScrollBar].
</theme_item>
diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml
index fa88085a70..1b83731a32 100644
--- a/doc/classes/HSlider.xml
+++ b/doc/classes/HSlider.xml
@@ -13,22 +13,22 @@
<theme_item name="grabber" data_type="icon" type="Texture2D">
The texture for the grabber (the draggable element).
</theme_item>
- <theme_item name="grabber_area" data_type="style" type="StyleBox">
- The background of the area to the left of the grabber.
- </theme_item>
- <theme_item name="grabber_area_highlight" data_type="style" type="StyleBox">
- </theme_item>
<theme_item name="grabber_disabled" data_type="icon" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
<theme_item name="grabber_highlight" data_type="icon" type="Texture2D">
The texture for the grabber when it's focused.
</theme_item>
- <theme_item name="slider" data_type="style" type="StyleBox">
- The background for the whole slider. Determines the height of the [code]grabber_area[/code].
- </theme_item>
<theme_item name="tick" data_type="icon" type="Texture2D">
The texture for the ticks, visible when [member Slider.tick_count] is greater than 0.
</theme_item>
+ <theme_item name="grabber_area" data_type="style" type="StyleBox">
+ The background of the area to the left of the grabber.
+ </theme_item>
+ <theme_item name="grabber_area_highlight" data_type="style" type="StyleBox">
+ </theme_item>
+ <theme_item name="slider" data_type="style" type="StyleBox">
+ The background for the whole slider. Determines the height of the [code]grabber_area[/code].
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/HSplitContainer.xml b/doc/classes/HSplitContainer.xml
index 379d4cfbdb..f2c505b1bc 100644
--- a/doc/classes/HSplitContainer.xml
+++ b/doc/classes/HSplitContainer.xml
@@ -12,13 +12,13 @@
<theme_item name="autohide" data_type="constant" type="int" default="1">
Boolean value. If 1 ([code]true[/code]), the grabber will hide automatically when it isn't under the cursor. If 0 ([code]false[/code]), it's always visible.
</theme_item>
- <theme_item name="bg" data_type="style" type="StyleBox">
+ <theme_item name="separation" data_type="constant" type="int" default="12">
+ The space between sides of the container.
</theme_item>
<theme_item name="grabber" data_type="icon" type="Texture2D">
The icon used for the grabber drawn in the middle area.
</theme_item>
- <theme_item name="separation" data_type="constant" type="int" default="12">
- The space between sides of the container.
+ <theme_item name="bg" data_type="style" type="StyleBox">
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index a50983853d..e15b065744 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -173,6 +173,24 @@
Sends the body data raw, as a byte array and does not encode it in any way.
</description>
</method>
+ <method name="set_http_proxy">
+ <return type="void" />
+ <argument index="0" name="host" type="String" />
+ <argument index="1" name="port" type="int" />
+ <description>
+ Sets the proxy server for HTTP requests.
+ The proxy server is unset if [code]host[/code] is empty or [code]port[/code] is -1.
+ </description>
+ </method>
+ <method name="set_https_proxy">
+ <return type="void" />
+ <argument index="0" name="host" type="String" />
+ <argument index="1" name="port" type="int" />
+ <description>
+ Sets the proxy server for HTTPS requests.
+ The proxy server is unset if [code]host[/code] is empty or [code]port[/code] is -1.
+ </description>
+ </method>
</methods>
<members>
<member name="blocking_mode_enabled" type="bool" setter="set_blocking_mode" getter="is_blocking_mode_enabled" default="false">
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 8a4bbee0fa..29feb107d4 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -286,7 +286,7 @@
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />
<description>
- Loads an image from file [code]path[/code]. See [url=$DOCS_URL/getting_started/workflow/assets/importing_images.html#supported-image-formats]Supported image formats[/url] for a list of supported image formats and limitations.
+ Loads an image from file [code]path[/code]. See [url=$DOCS_URL/tutorials/assets_pipeline/importing_images.html#supported-image-formats]Supported image formats[/url] for a list of supported image formats and limitations.
[b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external images at run-time, such as images located at the [code]user://[/code] directory, and may not work in exported projects.
See also [ImageTexture] description for usage examples.
</description>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index cd5ba2e17f..068106f2c7 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -243,17 +243,6 @@
Returns [code]true[/code] if you are pressing the key in the physical location on the 101/102-key US QWERTY keyboard. You can pass a [enum Key] constant.
</description>
</method>
- <method name="joy_connection_changed">
- <return type="void" />
- <argument index="0" name="device" type="int" />
- <argument index="1" name="connected" type="bool" />
- <argument index="2" name="name" type="String" />
- <argument index="3" name="guid" type="String" />
- <description>
- Notifies the [Input] singleton that a connection has changed, to update the state for the [code]device[/code] index.
- This is used internally and should not have to be called from user scripts. See [signal joy_connection_changed] for the signal emitted when this is triggered internally.
- </description>
- </method>
<method name="parse_input_event">
<return type="void" />
<argument index="0" name="event" type="InputEvent" />
diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml
index 0694b2eabc..17f6eeecab 100644
--- a/doc/classes/InputEventScreenTouch.xml
+++ b/doc/classes/InputEventScreenTouch.xml
@@ -15,7 +15,7 @@
The touch index in the case of a multi-touch event. One index = one finger.
</member>
<member name="position" type="Vector2" setter="set_position" getter="get_position" default="Vector2(0, 0)">
- The touch position.
+ The touch position, in screen (global) coordinates.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false">
If [code]true[/code], the touch's state is pressed. If [code]false[/code], the touch's state is released.
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index baa0faaae9..7263687ea8 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -374,14 +374,14 @@
The size all icons will be adjusted to.
If either X or Y component is not greater than zero, icon size won't be affected.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="icon_mode" type="int" setter="set_icon_mode" getter="get_icon_mode" enum="ItemList.IconMode" default="1">
The icon position, whether above or to the left of the text. See the [enum IconMode] constants.
</member>
<member name="icon_scale" type="float" setter="set_icon_scale" getter="get_icon_scale" default="1.0">
The scale of icon applied after [member fixed_icon_size] and transposing takes effect.
</member>
- <member name="items_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
+ <member name="item_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
The number of items currently in the list.
</member>
<member name="max_columns" type="int" setter="set_max_columns" getter="get_max_columns" default="1">
@@ -393,7 +393,7 @@
Maximum lines of text allowed in each item. Space will be reserved even when there is not enough lines of text to display.
[b]Note:[/b] This property takes effect only when [member icon_mode] is [constant ICON_MODE_TOP]. To make the text wrap, [member fixed_column_width] should be greater than zero.
</member>
- <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
+ <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="same_column_width" type="bool" setter="set_same_column_width" getter="is_same_column_width" default="false">
Whether all columns will have the same width.
If [code]true[/code], the width is equal to the largest column width of all columns.
@@ -463,21 +463,6 @@
</constant>
</constants>
<theme_items>
- <theme_item name="bg" data_type="style" type="StyleBox">
- Default [StyleBox] for the [ItemList], i.e. used when the control is not being focused.
- </theme_item>
- <theme_item name="bg_focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [ItemList] is being focused.
- </theme_item>
- <theme_item name="cursor" data_type="style" type="StyleBox">
- [StyleBox] used for the cursor, when the [ItemList] is being focused.
- </theme_item>
- <theme_item name="cursor_unfocused" data_type="style" type="StyleBox">
- [StyleBox] used for the cursor, when the [ItemList] is not being focused.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the item's text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.63, 0.63, 0.63, 1)">
Default text [Color] of the item.
</theme_item>
@@ -487,9 +472,6 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the item is selected.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the item's text.
- </theme_item>
<theme_item name="guide_color" data_type="color" type="Color" default="Color(0, 0, 0, 0.1)">
[Color] of the guideline. The guideline is a line drawn between each row of items.
</theme_item>
@@ -505,14 +487,32 @@
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the item text outline.
</theme_item>
+ <theme_item name="vseparation" data_type="constant" type="int" default="2">
+ The vertical spacing between items.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the item's text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the item's text.
+ </theme_item>
+ <theme_item name="bg" data_type="style" type="StyleBox">
+ Default [StyleBox] for the [ItemList], i.e. used when the control is not being focused.
+ </theme_item>
+ <theme_item name="bg_focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [ItemList] is being focused.
+ </theme_item>
+ <theme_item name="cursor" data_type="style" type="StyleBox">
+ [StyleBox] used for the cursor, when the [ItemList] is being focused.
+ </theme_item>
+ <theme_item name="cursor_unfocused" data_type="style" type="StyleBox">
+ [StyleBox] used for the cursor, when the [ItemList] is not being focused.
+ </theme_item>
<theme_item name="selected" data_type="style" type="StyleBox">
[StyleBox] for the selected items, used when the [ItemList] is not being focused.
</theme_item>
<theme_item name="selected_focus" data_type="style" type="StyleBox">
[StyleBox] for the selected items, used when the [ItemList] is being focused.
</theme_item>
- <theme_item name="vseparation" data_type="constant" type="int" default="2">
- The vertical spacing between items.
- </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index 24ebf08c36..e1d8b9e9f4 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -61,15 +61,15 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" enum="Label.Align" default="0">
- Controls the text's horizontal align. Supports left, center, right, and fill, or justify. Set it to one of the [enum Align] constants.
- </member>
<member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="Label.AutowrapMode" default="0">
If set to something other than [constant AUTOWRAP_OFF], the text gets wrapped inside the node's bounding rectangle. If you resize the node, it will change its height automatically to show all the text. To see how each mode behaves, see [enum AutowrapMode].
</member>
<member name="clip_text" type="bool" setter="set_clip_text" getter="is_clipping_text" default="false">
If [code]true[/code], the Label only shows the text that fits inside its bounding rectangle and will clip text horizontally.
</member>
+ <member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
+ Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
+ </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>
@@ -79,11 +79,11 @@
<member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1">
Limits the lines of text the node shows on screen.
</member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="2" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="2" />
<member name="percent_visible" type="float" setter="set_percent_visible" getter="get_percent_visible" default="1.0">
Limits the amount of visible characters. If you set [code]percent_visible[/code] to 0.5, only up to half of the text's characters will display on screen. Useful to animate the text in a dialog box.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="4" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="4" />
<member name="structured_text_bidi_override" type="int" setter="set_structured_text_bidi_override" getter="get_structured_text_bidi_override" enum="Control.StructuredTextParser" default="0">
Set BiDi algorithm override for the structured text.
</member>
@@ -102,38 +102,14 @@
<member name="uppercase" type="bool" setter="set_uppercase" getter="is_uppercase" default="false">
If [code]true[/code], all the text displays as UPPERCASE.
</member>
- <member name="valign" type="int" setter="set_valign" getter="get_valign" enum="Label.VAlign" default="0">
- Controls the text's vertical align. Supports top, center, bottom, and fill. Set it to one of the [enum VAlign] constants.
+ <member name="vertical_alignment" type="int" setter="set_vertical_alignment" getter="get_vertical_alignment" enum="VerticalAlignment" default="0">
+ Controls the text's vertical alignment. Supports top, center, bottom, and fill. Set it to one of the [enum VerticalAlignment] constants.
</member>
<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1">
Restricts the number of characters to display. Set to -1 to disable.
</member>
</members>
<constants>
- <constant name="ALIGN_LEFT" value="0" enum="Align">
- Align rows to the left (default).
- </constant>
- <constant name="ALIGN_CENTER" value="1" enum="Align">
- Align rows centered.
- </constant>
- <constant name="ALIGN_RIGHT" value="2" enum="Align">
- Align rows to the right.
- </constant>
- <constant name="ALIGN_FILL" value="3" enum="Align">
- Expand row to fit the width.
- </constant>
- <constant name="VALIGN_TOP" value="0" enum="VAlign">
- Align the whole text to the top.
- </constant>
- <constant name="VALIGN_CENTER" value="1" enum="VAlign">
- Align the whole text to the center.
- </constant>
- <constant name="VALIGN_BOTTOM" value="2" enum="VAlign">
- Align the whole text to the bottom.
- </constant>
- <constant name="VALIGN_FILL" value="3" enum="VAlign">
- Align the whole text by spreading the rows.
- </constant>
<constant name="AUTOWRAP_OFF" value="0" enum="AutowrapMode">
Autowrap is disabled.
</constant>
@@ -163,9 +139,6 @@
</constant>
</constants>
<theme_items>
- <theme_item name="font" data_type="font" type="Font">
- [Font] used for the [Label]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Default text [Color] of the [Label].
</theme_item>
@@ -175,15 +148,9 @@
<theme_item name="font_shadow_color" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
[Color] of the text's shadow effect.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [Label]'s text.
- </theme_item>
<theme_item name="line_spacing" data_type="constant" type="int" default="3">
Vertical space between lines in multiline [Label].
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- Background [StyleBox] for the [Label].
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
Text outline size.
</theme_item>
@@ -196,5 +163,14 @@
<theme_item name="shadow_outline_size" data_type="constant" type="int" default="1">
The size of the shadow outline.
</theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] used for the [Label]'s text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [Label]'s text.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ Background [StyleBox] for the [Label].
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml
index 4d9abbbb19..5e673cc19b 100644
--- a/doc/classes/Line2D.xml
+++ b/doc/classes/Line2D.xml
@@ -82,7 +82,7 @@
The smoothness of the rounded joints and caps. This is only used if a cap or joint is set as round.
</member>
<member name="sharp_limit" type="float" setter="set_sharp_limit" getter="get_sharp_limit" default="2.0">
- The direction difference in radians between vector points. This value is only used if [code]joint mode[/code] is set to [constant LINE_JOINT_SHARP].
+ The direction difference in radians between vector points. This value is only used if [member joint_mode] is set to [constant LINE_JOINT_SHARP].
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The texture used for the line's texture. Uses [code]texture_mode[/code] for drawing style.
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index a75bd2f704..06094300de 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -159,8 +159,8 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" enum="LineEdit.Align" default="0">
- Text alignment as defined in the [enum Align] enum.
+ <member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
+ Text alignment as defined in the [enum HorizontalAlignment] enum.
</member>
<member name="caret_blink" type="bool" setter="set_caret_blink_enabled" getter="is_caret_blink_enabled" default="false">
If [code]true[/code], the caret (text cursor) blinks.
@@ -199,7 +199,7 @@
<member name="flat" type="bool" setter="set_flat" getter="is_flat" default="false">
If [code]true[/code], the [LineEdit] don't display decoration.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<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>
@@ -232,7 +232,7 @@
If [code]false[/code], using middle mouse button to paste clipboard will be disabled.
[b]Note:[/b] This method is only implemented on Linux.
</member>
- <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
+ <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" overrides="Control" enum="Control.CursorShape" default="1" />
<member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6">
Opacity of the [member placeholder_text]. From [code]0[/code] to [code]1[/code].
</member>
@@ -292,18 +292,6 @@
</signal>
</signals>
<constants>
- <constant name="ALIGN_LEFT" value="0" enum="Align">
- Aligns the text on the left-hand side of the [LineEdit].
- </constant>
- <constant name="ALIGN_CENTER" value="1" enum="Align">
- Centers the text in the middle of the [LineEdit].
- </constant>
- <constant name="ALIGN_RIGHT" value="2" enum="Align">
- Aligns the text on the right-hand side of the [LineEdit].
- </constant>
- <constant name="ALIGN_FILL" value="3" enum="Align">
- Expand row to fit the [LineEdit]'s width.
- </constant>
<constant name="MENU_CUT" value="0" enum="MenuItems">
Cuts (copies and clears) the selected text.
</constant>
@@ -397,21 +385,12 @@
<theme_item name="caret_color" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)">
Color of the [LineEdit]'s caret (text cursor).
</theme_item>
- <theme_item name="clear" data_type="icon" type="Texture2D">
- Texture for the clear button. See [member clear_button_enabled].
- </theme_item>
<theme_item name="clear_button_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Color used as default tint for the clear button.
</theme_item>
<theme_item name="clear_button_color_pressed" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Color used for the clear button when it's pressed.
</theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- Background used when [LineEdit] has GUI focus.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- Font used for the text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Default font color.
</theme_item>
@@ -421,26 +400,35 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Font color for selected text (inside the selection rectangle).
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [LineEdit]'s text.
- </theme_item>
<theme_item name="font_uneditable_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 0.5)">
Font color when editing is disabled.
</theme_item>
+ <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)">
+ Color of the selection rectangle.
+ </theme_item>
<theme_item name="minimum_character_width" data_type="constant" type="int" default="4">
Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of 'M' characters (i.e. this amount of 'M' characters can be displayed without scrolling).
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- Default background for the [LineEdit].
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ Font used for the text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [LineEdit]'s text.
+ </theme_item>
+ <theme_item name="clear" data_type="icon" type="Texture2D">
+ Texture for the clear button. See [member clear_button_enabled].
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ Background used when [LineEdit] has GUI focus.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ Default background for the [LineEdit].
+ </theme_item>
<theme_item name="read_only" data_type="style" type="StyleBox">
Background used when [LineEdit] is in read-only mode ([member editable] is set to [code]false[/code]).
</theme_item>
- <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)">
- Color of the selection rectangle.
- </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml
index 0329ed833f..17a9e13842 100644
--- a/doc/classes/LinkButton.xml
+++ b/doc/classes/LinkButton.xml
@@ -33,11 +33,11 @@
</method>
</methods>
<members>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="0" />
<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_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="2" />
+ <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" overrides="Control" enum="Control.CursorShape" default="2" />
<member name="structured_text_bidi_override" type="int" setter="set_structured_text_bidi_override" getter="get_structured_text_bidi_override" enum="Control.StructuredTextParser" default="0">
Set BiDi algorithm override for the structured text.
</member>
@@ -66,12 +66,6 @@
</constant>
</constants>
<theme_items>
- <theme_item name="focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [LinkButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the [LinkButton]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Default text [Color] of the [LinkButton].
</theme_item>
@@ -87,14 +81,20 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the [LinkButton] is being pressed.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the [LinkButton]'s text.
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
<theme_item name="underline_spacing" data_type="constant" type="int" default="2">
The vertical space between the baseline of text and the underline.
</theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the [LinkButton]'s text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the [LinkButton]'s text.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [LinkButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index 7f9d3d96dc..b0774d4cab 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -27,16 +27,16 @@
</method>
</methods>
<members>
- <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" />
- <member name="flat" type="bool" setter="set_flat" getter="is_flat" override="true" default="true" />
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" />
- <member name="items_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
+ <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" overrides="BaseButton" enum="BaseButton.ActionMode" default="0" />
+ <member name="flat" type="bool" setter="set_flat" getter="is_flat" overrides="Button" default="true" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="0" />
+ <member name="item_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
The number of items currently in the list.
</member>
<member name="switch_on_hover" type="bool" setter="set_switch_on_hover" getter="is_switch_on_hover" default="false">
If [code]true[/code], when the cursor hovers above another [MenuButton] within the same parent which also has [code]switch_on_hover[/code] enabled, it will close the current [MenuButton] and open the other one.
</member>
- <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" override="true" default="true" />
+ <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
</members>
<signals>
<signal name="about_to_popup">
@@ -46,15 +46,6 @@
</signal>
</signals>
<theme_items>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- [StyleBox] used when the [MenuButton] is disabled.
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [MenuButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the [MenuButton]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Default text [Color] of the [MenuButton].
</theme_item>
@@ -73,21 +64,30 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the [MenuButton] is being pressed.
</theme_item>
+ <theme_item name="hseparation" data_type="constant" type="int" default="3">
+ The horizontal space between [MenuButton]'s icon and text.
+ </theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the [MenuButton]'s text.
+ </theme_item>
<theme_item name="font_size" data_type="font_size" type="int">
Font size of the [MenuButton]'s text.
</theme_item>
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ [StyleBox] used when the [MenuButton] is disabled.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [MenuButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
+ </theme_item>
<theme_item name="hover" data_type="style" type="StyleBox">
[StyleBox] used when the [MenuButton] is being hovered.
</theme_item>
- <theme_item name="hseparation" data_type="constant" type="int" default="3">
- The horizontal space between [MenuButton]'s icon and text.
- </theme_item>
<theme_item name="normal" data_type="style" type="StyleBox">
Default [StyleBox] for the [MenuButton].
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
- </theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [MenuButton] is being pressed.
</theme_item>
diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml
index 636ed368d1..02144d641e 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -35,7 +35,7 @@
<member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" default="true">
If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's borders.
</member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="2" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="2" />
<member name="patch_margin_bottom" type="int" setter="set_patch_margin" getter="get_patch_margin" default="0">
The height of the 9-slice's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values individually to create panels with non-uniform borders.
</member>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 8a12314ba8..81b94c036d 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -261,7 +261,7 @@
<return type="Node" />
<argument index="0" name="path" type="NodePath" />
<description>
- Fetches a node. The [NodePath] can be either a relative path (from the current node) or an absolute path (in the scene tree) to a node. If the path does not exist, a [code]null instance[/code] is returned and an error is logged. Attempts to access methods on the return value will result in an "Attempt to call &lt;method&gt; on a null instance." error.
+ Fetches a node. The [NodePath] can be either a relative path (from the current node) or an absolute path (in the scene tree) to a node. If the path does not exist, [code]null[/code] is returned and an error is logged. Attempts to access methods on the return value will result in an "Attempt to call &lt;method&gt; on a null instance." error.
[b]Note:[/b] Fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]).
[b]Example:[/b] Assume your current node is Character and the following tree:
[codeblock]
@@ -322,7 +322,7 @@
<method name="get_parent" qualifiers="const">
<return type="Node" />
<description>
- Returns the parent node of the current node, or a [code]null instance[/code] if the node lacks a parent.
+ Returns the parent node of the current node, or [code]null[/code] if the node lacks a parent.
</description>
</method>
<method name="get_path" qualifiers="const">
@@ -726,7 +726,7 @@
<signals>
<signal name="ready">
<description>
- Emitted when the node is ready.
+ Emitted when the node is ready. Comes after [method _ready] callback and follows the same rules.
</description>
</signal>
<signal name="renamed">
@@ -791,8 +791,8 @@
<constant name="NOTIFICATION_DRAG_END" value="22">
Notification received when a drag ends.
</constant>
- <constant name="NOTIFICATION_PATH_CHANGED" value="23">
- Notification received when the node's [NodePath] changed.
+ <constant name="NOTIFICATION_PATH_RENAMED" value="23">
+ Notification received when the node's name or one of its parents' name is changed. This notification is [i]not[/i] received when the node is removed from the scene tree to be added to another parent later on.
</constant>
<constant name="NOTIFICATION_INTERNAL_PROCESS" value="25">
Notification received every frame when the internal process flag is set (see [method set_process_internal]).
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 7088844547..a5bd8e2768 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -31,6 +31,13 @@
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
+ <method name="crash">
+ <return type="void" />
+ <argument index="0" name="message" type="String" />
+ <description>
+ Crashes the engine (or the editor if called within a [code]@tool[/code] script). This should [i]only[/i] be used for testing the system's crash handler, not for any other purpose. For general error reporting, use (in order of preference) [method @GDScript.assert], [method @GlobalScope.push_error] or [method alert]. See also [method kill].
+ </description>
+ </method>
<method name="create_instance">
<return type="int" />
<argument index="0" name="arguments" type="PackedStringArray" />
@@ -374,7 +381,7 @@
<return type="int" enum="Error" />
<argument index="0" name="pid" type="int" />
<description>
- Kill (terminate) the process identified by the given process ID ([code]pid[/code]), e.g. the one returned by [method execute] in non-blocking mode.
+ Kill (terminate) the process identified by the given process ID ([code]pid[/code]), e.g. the one returned by [method execute] in non-blocking mode. See also [method crash].
[b]Note:[/b] This method can also be used to kill processes that were not spawned by the game.
[b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
</description>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index a3616af999..d2f9b08fbf 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -163,12 +163,12 @@
</method>
</methods>
<members>
- <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" />
- <member name="align" type="int" setter="set_text_align" getter="get_text_align" override="true" enum="Button.TextAlign" default="0" />
+ <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" overrides="BaseButton" enum="BaseButton.ActionMode" default="0" />
+ <member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" overrides="Button" enum="HorizontalAlignment" default="0" />
<member name="selected" type="int" setter="_select_int" getter="get_selected" default="-1">
The index of the currently selected item, or [code]-1[/code] if no item is selected.
</member>
- <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" override="true" default="true" />
+ <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
</members>
<signals>
<signal name="item_focused">
@@ -185,24 +185,6 @@
</signal>
</signals>
<theme_items>
- <theme_item name="arrow" data_type="icon" type="Texture2D">
- The arrow icon to be drawn on the right end of the button.
- </theme_item>
- <theme_item name="arrow_margin" data_type="constant" type="int" default="2">
- The horizontal space between the arrow icon and the right edge of the button.
- </theme_item>
- <theme_item name="disabled" data_type="style" type="StyleBox">
- [StyleBox] used when the [OptionButton] is disabled (for left-to-right layouts).
- </theme_item>
- <theme_item name="disabled_mirrored" data_type="style" type="StyleBox">
- [StyleBox] used when the [OptionButton] is disabled (for right-to-left layouts).
- </theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [OptionButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the [OptionButton]'s text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Default text [Color] of the [OptionButton].
</theme_item>
@@ -221,27 +203,45 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the [OptionButton] is being pressed.
</theme_item>
+ <theme_item name="arrow_margin" data_type="constant" type="int" default="2">
+ The horizontal space between the arrow icon and the right edge of the button.
+ </theme_item>
+ <theme_item name="hseparation" data_type="constant" type="int" default="2">
+ The horizontal space between [OptionButton]'s icon and text.
+ </theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the [OptionButton]'s text.
+ </theme_item>
<theme_item name="font_size" data_type="font_size" type="int">
Font size of the [OptionButton]'s text.
</theme_item>
+ <theme_item name="arrow" data_type="icon" type="Texture2D">
+ The arrow icon to be drawn on the right end of the button.
+ </theme_item>
+ <theme_item name="disabled" data_type="style" type="StyleBox">
+ [StyleBox] used when the [OptionButton] is disabled (for left-to-right layouts).
+ </theme_item>
+ <theme_item name="disabled_mirrored" data_type="style" type="StyleBox">
+ [StyleBox] used when the [OptionButton] is disabled (for right-to-left layouts).
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [OptionButton] is focused. It is displayed over the current [StyleBox], so using [StyleBoxEmpty] will just disable the focus visual effect.
+ </theme_item>
<theme_item name="hover" data_type="style" type="StyleBox">
[StyleBox] used when the [OptionButton] is being hovered (for left-to-right layouts).
</theme_item>
<theme_item name="hover_mirrored" data_type="style" type="StyleBox">
[StyleBox] used when the [OptionButton] is being hovered (for right-to-left layouts).
</theme_item>
- <theme_item name="hseparation" data_type="constant" type="int" default="2">
- The horizontal space between [OptionButton]'s icon and text.
- </theme_item>
<theme_item name="normal" data_type="style" type="StyleBox">
Default [StyleBox] for the [OptionButton] (for left-to-right layouts).
</theme_item>
<theme_item name="normal_mirrored" data_type="style" type="StyleBox">
Default [StyleBox] for the [OptionButton] (for right-to-left layouts).
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
- </theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [OptionButton] is being pressed (for left-to-right layouts).
</theme_item>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index fd098481e4..b16d45b8ca 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -366,18 +366,19 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedByteArray" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
+ Returns the slice of the [PackedByteArray], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedByteArray].
+ If [code]end[/code]is negative, it will be relative to the end of the array.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedByteArray" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
- Returns the slice of the [PackedByteArray] between indices (inclusive) as a new [PackedByteArray]. Any negative index is considered to be from the end of the array.
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_float32_array" qualifiers="const">
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index f69c5504da..13d7440bb9 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -129,17 +129,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedColorArray" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedColorArray" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index ccac607386..151014192f 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -130,17 +130,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedFloat32Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedFloat32Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index b164283b3e..963a02ace8 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -130,17 +130,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedFloat64Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedFloat64Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index c6ff31ebdd..cef113dee9 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -130,17 +130,17 @@
Returns the array size.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedInt32Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedInt32Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index ff48eb1aad..072df519c6 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -130,17 +130,17 @@
Returns the array size.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedInt64Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedInt64Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index 4204277ea2..0bded150a3 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -130,17 +130,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedStringArray" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedStringArray" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index e6a7b2fa41..8e993c41ab 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -130,17 +130,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedVector2Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedVector2Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index 6992bbca01..df69e3cd4a 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -129,17 +129,17 @@
Returns the size of the array.
</description>
</method>
- <method name="sort">
- <return type="void" />
+ <method name="slice" qualifiers="const">
+ <return type="PackedVector3Array" />
+ <argument index="0" name="begin" type="int" />
+ <argument index="1" name="end" type="int" />
<description>
- Sorts the elements of the array in ascending order.
</description>
</method>
- <method name="subarray" qualifiers="const">
- <return type="PackedVector3Array" />
- <argument index="0" name="from" type="int" />
- <argument index="1" name="to" type="int" />
+ <method name="sort">
+ <return type="void" />
<description>
+ Sorts the elements of the array in ascending order.
</description>
</method>
<method name="to_byte_array" qualifiers="const">
diff --git a/doc/classes/PanelContainer.xml b/doc/classes/PanelContainer.xml
index 95d038e2af..80005cce15 100644
--- a/doc/classes/PanelContainer.xml
+++ b/doc/classes/PanelContainer.xml
@@ -10,7 +10,7 @@
<link title="2D Role Playing Game Demo">https://godotengine.org/asset-library/asset/520</link>
</tutorials>
<members>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="0" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="0" />
</members>
<theme_items>
<theme_item name="panel" data_type="style" type="StyleBox">
diff --git a/doc/classes/ParallaxBackground.xml b/doc/classes/ParallaxBackground.xml
index 5670660d01..592f12d9d7 100644
--- a/doc/classes/ParallaxBackground.xml
+++ b/doc/classes/ParallaxBackground.xml
@@ -9,7 +9,7 @@
<tutorials>
</tutorials>
<members>
- <member name="layer" type="int" setter="set_layer" getter="get_layer" override="true" default="-100" />
+ <member name="layer" type="int" setter="set_layer" getter="get_layer" overrides="CanvasLayer" default="-100" />
<member name="scroll_base_offset" type="Vector2" setter="set_scroll_base_offset" getter="get_scroll_base_offset" default="Vector2(0, 0)">
The base position offset for all [ParallaxLayer] children.
</member>
diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml
index 6ff57bd58a..ed778af26a 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -6,7 +6,7 @@
<description>
ParticlesMaterial defines particle properties and behavior. It is used in the [code]process_material[/code] of [GPUParticles3D] and [GPUParticles2D] emitter nodes.
Some of this material's properties are applied to each particle when emitted, while others can have a [CurveTexture] applied to vary values over the lifetime of the particle.
- When a randomness ratio is applied to a property it is used to scale that property by a random amount. The random ratio is used to interpolate between [code]1.0[/code] and a random number less than one, the result is multiplied by the property to obtain the randomized property. For example a random ratio of [code]0.4[/code] would scale the original property between [code]0.4-1.0[/code] of its original value.
+ Particle animation is available only in [GPUParticles2D]. To use it, attach a [CanvasItemMaterial], with [member CanvasItemMaterial.particles_animation] enabled, to the particles node.
</description>
<tutorials>
</tutorials>
@@ -104,7 +104,8 @@
Each particle's animation speed will vary along this [CurveTexture].
</member>
<member name="anim_speed_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum particle animation speed.
+ Maximum particle animation speed. Animation speed of [code]1[/code] means that the particles will make full [code]0[/code] to [code]1[/code] offset cycle during lifetime, [code]2[/code] means [code]2[/code] cycles etc.
+ With animation speed greater than [code]1[/code], remember to enable [member CanvasItemMaterial.particles_anim_loop] property if you want the animation to repeat.
</member>
<member name="anim_speed_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
Minimum particle animation speed.
@@ -198,7 +199,7 @@
Minimum initial velocity.
</member>
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
- Particle lifetime randomness ratio.
+ Particle lifetime randomness ratio. The lifetime will be multipled by a value interpolated between [code]1.0[/code] and a random number less than one. For example a random ratio of [code]0.4[/code] would scale the original lifetime between [code]0.4-1.0[/code] of its original value.
</member>
<member name="linear_accel_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's linear acceleration will vary along this [CurveTexture].
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index 08f9de53ca..43e27ea437 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -57,6 +57,6 @@
</method>
</methods>
<members>
- <member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable" override="true" default="false" />
+ <member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable" overrides="CollisionObject2D" default="false" />
</members>
</class>
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index 868b58ea9f..556e2dae85 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -711,13 +711,6 @@
Activates or deactivates the 2D physics engine.
</description>
</method>
- <method name="set_collision_iterations">
- <return type="void" />
- <argument index="0" name="iterations" type="int" />
- <description>
- Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount of iterations, the more accurate the collisions will be. However, a greater amount of iterations requires more CPU power, which can decrease performance. The default value is [code]8[/code].
- </description>
- </method>
<method name="shape_get_data" qualifiers="const">
<return type="Variant" />
<argument index="0" name="shape" type="RID" />
@@ -798,21 +791,27 @@
<constant name="SPACE_PARAM_CONTACT_MAX_SEPARATION" value="1" enum="SpaceParameter">
Constant to set/get the maximum distance a shape can be from another before they are considered separated.
</constant>
- <constant name="SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION" value="2" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION" value="2" enum="SpaceParameter">
Constant to set/get the maximum distance a shape can penetrate another shape before it is considered a collision.
</constant>
- <constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="3" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONTACT_DEFAULT_BIAS" value="3" enum="SpaceParameter">
+ Constant to set/get the default solver bias for all physics contacts. A solver bias is a factor controlling how much two objects "rebound", after overlapping, to avoid leaving them in that state because of numerical imprecision.
+ </constant>
+ <constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="4" enum="SpaceParameter">
Constant to set/get the threshold linear velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
- <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="4" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="5" enum="SpaceParameter">
Constant to set/get the threshold angular velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
- <constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="5" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="6" enum="SpaceParameter">
Constant to set/get the maximum time of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after this time.
</constant>
- <constant name="SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS" value="6" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS" value="7" enum="SpaceParameter">
Constant to set/get the default solver bias for all physics constraints. A solver bias is a factor controlling how much two objects "rebound", after violating a constraint, to avoid leaving them in that state because of numerical imprecision.
</constant>
+ <constant name="SPACE_PARAM_SOLVER_ITERATIONS" value="8" enum="SpaceParameter">
+ Constant to set/get the number of solver iterations for all contacts and constraints. The greater the amount of iterations, the more accurate the collisions will be. However, a greater amount of iterations requires more CPU power, which can decrease performance.
+ </constant>
<constant name="SHAPE_WORLD_BOUNDARY" value="0" enum="ShapeType">
This is the constant for creating world boundary shapes. A world boundary shape is an [i]infinite[/i] line with an origin point, and a normal. Thus, it can be used for front/behind checks.
</constant>
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index dd8003be1d..027c593de3 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -846,14 +846,6 @@
Activates or deactivates the 3D physics engine.
</description>
</method>
- <method name="set_collision_iterations">
- <return type="void" />
- <argument index="0" name="iterations" type="int" />
- <description>
- Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount of iterations, the more accurate the collisions will be. However, a greater amount of iterations requires more CPU power, which can decrease performance. The default value is [code]8[/code].
- [b]Note:[/b] Only has an effect when using the default GodotPhysics engine, not the Bullet physics engine.
- </description>
- </method>
<method name="shape_get_data" qualifiers="const">
<return type="Variant" />
<argument index="0" name="shape" type="RID" />
@@ -1152,16 +1144,16 @@
Maximum acceleration for the motor at the axes.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT" value="0" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is linear motion possible within the given limits.
+ If set, linear motion is possible within the given limits.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT" value="1" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is rotational motion possible.
+ If set, rotational motion is possible.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_MOTOR" value="4" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is a rotational motor across these axes.
+ If set, there is a rotational motor across these axes.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR" value="5" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is a linear motor on this axis that targets a specific velocity.
+ If set, there is a linear motor on this axis that targets a specific velocity.
</constant>
<constant name="SHAPE_WORLD_BOUNDARY" value="0" enum="ShapeType">
The [Shape3D] is a [WorldBoundaryShape3D].
@@ -1343,23 +1335,29 @@
<constant name="SPACE_PARAM_CONTACT_MAX_SEPARATION" value="1" enum="SpaceParameter">
Constant to set/get the maximum distance a shape can be from another before they are considered separated.
</constant>
- <constant name="SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION" value="2" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION" value="2" enum="SpaceParameter">
Constant to set/get the maximum distance a shape can penetrate another shape before it is considered a collision.
</constant>
- <constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="3" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONTACT_DEFAULT_BIAS" value="3" enum="SpaceParameter">
+ Constant to set/get the default solver bias for all physics contacts. A solver bias is a factor controlling how much two objects "rebound", after overlapping, to avoid leaving them in that state because of numerical imprecision.
+ </constant>
+ <constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="4" enum="SpaceParameter">
Constant to set/get the threshold linear velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
- <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="4" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="5" enum="SpaceParameter">
Constant to set/get the threshold angular velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
- <constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="5" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="6" enum="SpaceParameter">
Constant to set/get the maximum time of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after this time.
</constant>
- <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO" value="6" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO" value="7" enum="SpaceParameter">
</constant>
- <constant name="SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS" value="7" enum="SpaceParameter">
+ <constant name="SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS" value="8" enum="SpaceParameter">
Constant to set/get the default solver bias for all physics constraints. A solver bias is a factor controlling how much two objects "rebound", after violating a constraint, to avoid leaving them in that state because of numerical imprecision.
</constant>
+ <constant name="SPACE_PARAM_SOLVER_ITERATIONS" value="9" enum="SpaceParameter">
+ Constant to set/get the number of solver iterations for contacts and constraints. The greater the amount of iterations, the more accurate the collisions and constraints will be. However, a greater amount of iterations requires more CPU power, which can decrease performance.
+ </constant>
<constant name="BODY_AXIS_LINEAR_X" value="1" enum="BodyAxis">
</constant>
<constant name="BODY_AXIS_LINEAR_Y" value="2" enum="BodyAxis">
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml
index a47f72b2b6..dc5dd47287 100644
--- a/doc/classes/Popup.xml
+++ b/doc/classes/Popup.xml
@@ -9,14 +9,14 @@
<tutorials>
</tutorials>
<members>
- <member name="borderless" type="bool" setter="set_flag" getter="get_flag" override="true" default="true" />
+ <member name="borderless" type="bool" setter="set_flag" getter="get_flag" overrides="Window" default="true" />
<member name="close_on_parent_focus" type="bool" setter="set_close_on_parent_focus" getter="get_close_on_parent_focus" default="true">
If [code]true[/code], the [Popup] will close when its parent is focused.
</member>
- <member name="transient" type="bool" setter="set_transient" getter="is_transient" override="true" default="true" />
- <member name="unresizable" type="bool" setter="set_flag" getter="get_flag" override="true" default="true" />
- <member name="visible" type="bool" setter="set_visible" getter="is_visible" override="true" default="false" />
- <member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" override="true" default="true" />
+ <member name="transient" type="bool" setter="set_transient" getter="is_transient" overrides="Window" default="true" />
+ <member name="unresizable" type="bool" setter="set_flag" getter="get_flag" overrides="Window" default="true" />
+ <member name="visible" type="bool" setter="set_visible" getter="is_visible" overrides="Window" default="false" />
+ <member name="wrap_controls" type="bool" setter="set_wrap_controls" getter="is_wrapping_controls" overrides="Window" default="true" />
</members>
<signals>
<signal name="popup_hide">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 4eb3ef34b4..b45f62394d 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -107,6 +107,7 @@
<description>
Adds a new item with text [code]label[/code].
An [code]id[/code] can optionally be provided, as well as an accelerator ([code]accel[/code]). If no [code]id[/code] is provided, one will be created from the index. If no [code]accel[/code] is provided then the default [code]0[/code] will be assigned to it. See [method get_item_accelerator] for more info on accelerators.
+ [b]Note:[/b] The provided [code]id[/code] is used only in [signal id_pressed] and [signal id_focused] signals. It's not related to the [code]index[/code] arguments in e.g. [method set_item_checked].
</description>
</method>
<method name="add_multistate_item">
@@ -181,7 +182,7 @@
</method>
<method name="clear_item_opentype_features">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Removes all OpenType features form the item's text.
</description>
@@ -194,49 +195,49 @@
</method>
<method name="get_item_accelerator" qualifiers="const">
<return type="int" enum="Key" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the accelerator of the item at index [code]idx[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
+ Returns the accelerator of the item at the given [code]index[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
</description>
</method>
<method name="get_item_icon" qualifiers="const">
<return type="Texture2D" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the icon of the item at index [code]idx[/code].
+ Returns the icon of the item at the given [code]index[/code].
</description>
</method>
<method name="get_item_id" qualifiers="const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the id of the item at index [code]idx[/code]. [code]id[/code] can be manually assigned, while index can not.
+ Returns the id of the item at the given [code]index[/code]. [code]id[/code] can be manually assigned, while index can not.
</description>
</method>
<method name="get_item_index" qualifiers="const">
<return type="int" />
<argument index="0" name="id" type="int" />
<description>
- Returns the index of the item containing the specified [code]id[/code]. Index is automatically assigned to each item by the engine. Index can not be set manually.
+ Returns the index of the item containing the specified [code]id[/code]. Index is automatically assigned to each item by the engine and can not be set manually.
</description>
</method>
<method name="get_item_language" qualifiers="const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Returns item's text language code.
</description>
</method>
<method name="get_item_metadata" qualifiers="const">
<return type="Variant" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Returns the metadata of the specified item, which might be of any type. You can set it with [method set_item_metadata], which provides a simple way of assigning context data to items.
</description>
</method>
<method name="get_item_opentype_feature" qualifiers="const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="tag" type="String" />
<description>
Returns OpenType feature [code]tag[/code] of the item's text.
@@ -244,160 +245,161 @@
</method>
<method name="get_item_shortcut" qualifiers="const">
<return type="Shortcut" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the [Shortcut] associated with the specified [code]idx[/code] item.
+ Returns the [Shortcut] associated with the item at the given [code]index[/code].
</description>
</method>
<method name="get_item_submenu" qualifiers="const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the submenu name of the item at index [code]idx[/code]. See [method add_submenu_item] for more info on how to add a submenu.
+ Returns the submenu name of the item at the given [code]index[/code]. See [method add_submenu_item] for more info on how to add a submenu.
</description>
</method>
<method name="get_item_text" qualifiers="const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the text of the item at index [code]idx[/code].
+ Returns the text of the item at the given [code]index[/code].
</description>
</method>
<method name="get_item_text_direction" qualifiers="const">
<return type="int" enum="Control.TextDirection" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Returns item's text base writing direction.
</description>
</method>
<method name="get_item_tooltip" qualifiers="const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns the tooltip associated with the specified index index [code]idx[/code].
+ Returns the tooltip associated with the item at the given [code]index[/code].
</description>
</method>
<method name="is_item_checkable" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns [code]true[/code] if the item at index [code]idx[/code] is checkable in some way, i.e. if it has a checkbox or radio button.
+ Returns [code]true[/code] if the item at the given [code]index[/code] is checkable in some way, i.e. if it has a checkbox or radio button.
[b]Note:[/b] Checkable items just display a checkmark or radio button, but don't have any built-in checking behavior and must be checked/unchecked manually.
</description>
</method>
<method name="is_item_checked" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns [code]true[/code] if the item at index [code]idx[/code] is checked.
+ Returns [code]true[/code] if the item at the given [code]index[/code] is checked.
</description>
</method>
<method name="is_item_disabled" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns [code]true[/code] if the item at index [code]idx[/code] is disabled. When it is disabled it can't be selected, or its action invoked.
+ Returns [code]true[/code] if the item at the given [code]index[/code] is disabled. When it is disabled it can't be selected, or its action invoked.
See [method set_item_disabled] for more info on how to disable an item.
</description>
</method>
<method name="is_item_radio_checkable" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Returns [code]true[/code] if the item at index [code]idx[/code] has radio button-style checkability.
+ Returns [code]true[/code] if the item at the given [code]index[/code] has radio button-style checkability.
[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/unchecking items in radio groups.
</description>
</method>
<method name="is_item_separator" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Returns [code]true[/code] if the item is a separator. If it is, it will be displayed as a line. See [method add_separator] for more info on how to add a separator.
</description>
</method>
<method name="is_item_shortcut_disabled" qualifiers="const">
<return type="bool" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Returns [code]true[/code] if the specified item's shortcut is disabled.
</description>
</method>
<method name="remove_item">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Removes the item at index [code]idx[/code] from the menu.
+ Removes the item at the given [code]index[/code] from the menu.
[b]Note:[/b] The indices of items after the removed item will be shifted by one.
</description>
</method>
<method name="set_item_accelerator">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="accel" type="int" enum="Key" />
<description>
- Sets the accelerator of the item at index [code]idx[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
+ Sets the accelerator of the item at the given [code]index[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
</description>
</method>
<method name="set_item_as_checkable">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="enable" type="bool" />
<description>
- Sets whether the item at index [code]idx[/code] has a checkbox. If [code]false[/code], sets the type of the item to plain text.
+ Sets whether the item at the given [code]index[/code] has a checkbox. If [code]false[/code], sets the type of the item to plain text.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
</description>
</method>
<method name="set_item_as_radio_checkable">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="enable" type="bool" />
<description>
- Sets the type of the item at the specified index [code]idx[/code] to radio button. If [code]false[/code], sets the type of the item to plain text.
+ Sets the type of the item at the given [code]index[/code] to radio button. If [code]false[/code], sets the type of the item to plain text.
</description>
</method>
<method name="set_item_as_separator">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="enable" type="bool" />
<description>
- Mark the item at index [code]idx[/code] as a separator, which means that it would be displayed as a line. If [code]false[/code], sets the type of the item to plain text.
+ Mark the item at the given [code]index[/code] as a separator, which means that it would be displayed as a line. If [code]false[/code], sets the type of the item to plain text.
</description>
</method>
<method name="set_item_checked">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="checked" type="bool" />
<description>
- Sets the checkstate status of the item at index [code]idx[/code].
+ Sets the checkstate status of the item at the given [code]index[/code].
</description>
</method>
<method name="set_item_disabled">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="disabled" type="bool" />
<description>
- Enables/disables the item at index [code]idx[/code]. When it is disabled, it can't be selected and its action can't be invoked.
+ Enables/disables the item at the given [code]index[/code]. When it is disabled, it can't be selected and its action can't be invoked.
</description>
</method>
<method name="set_item_icon">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="icon" type="Texture2D" />
<description>
- Replaces the [Texture2D] icon of the specified [code]idx[/code].
+ Replaces the [Texture2D] icon of the item at the given [code]index[/code].
</description>
</method>
<method name="set_item_id">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="id" type="int" />
<description>
- Sets the [code]id[/code] of the item at index [code]idx[/code].
+ Sets the [code]id[/code] of the item at the given [code]index[/code].
+ The [code]id[/code] is used in [signal id_pressed] and [signal id_focused] signals.
</description>
</method>
<method name="set_item_language">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="language" type="String" />
<description>
Sets language code of item's text used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
@@ -405,7 +407,7 @@
</method>
<method name="set_item_metadata">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="metadata" type="Variant" />
<description>
Sets the metadata of an item, which may be of any type. You can later get it with [method get_item_metadata], which provides a simple way of assigning context data to items.
@@ -413,7 +415,7 @@
</method>
<method name="set_item_multistate">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="state" type="int" />
<description>
Sets the state of a multistate item. See [method add_multistate_item] for details.
@@ -421,7 +423,7 @@
</method>
<method name="set_item_opentype_feature">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="tag" type="String" />
<argument index="2" name="value" type="int" />
<description>
@@ -430,40 +432,40 @@
</method>
<method name="set_item_shortcut">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="shortcut" type="Shortcut" />
<argument index="2" name="global" type="bool" default="false" />
<description>
- Sets a [Shortcut] for the specified item [code]idx[/code].
+ Sets a [Shortcut] for the item at the given [code]index[/code].
</description>
</method>
<method name="set_item_shortcut_disabled">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="disabled" type="bool" />
<description>
- Disables the [Shortcut] of the specified index [code]idx[/code].
+ Disables the [Shortcut] of the item at the given [code]index[/code].
</description>
</method>
<method name="set_item_submenu">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="submenu" type="String" />
<description>
- Sets the submenu of the item at index [code]idx[/code]. The submenu is the name of a child [PopupMenu] node that would be shown when the item is clicked.
+ Sets the submenu of the item at the given [code]index[/code]. The submenu is the name of a child [PopupMenu] node that would be shown when the item is clicked.
</description>
</method>
<method name="set_item_text">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="text" type="String" />
<description>
- Sets the text of the item at index [code]idx[/code].
+ Sets the text of the item at the given [code]index[/code].
</description>
</method>
<method name="set_item_text_direction">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="direction" type="int" enum="Control.TextDirection" />
<description>
Sets item's text base writing direction.
@@ -471,22 +473,22 @@
</method>
<method name="set_item_tooltip">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<argument index="1" name="tooltip" type="String" />
<description>
- Sets the [String] tooltip of the item at the specified index [code]idx[/code].
+ Sets the [String] tooltip of the item at the given [code]index[/code].
</description>
</method>
<method name="toggle_item_checked">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
- Toggles the check state of the item of the specified index [code]idx[/code].
+ Toggles the check state of the item at the given [code]index[/code].
</description>
</method>
<method name="toggle_item_multistate">
<return type="void" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="index" type="int" />
<description>
Cycle to the next state of a multistate item. See [method add_multistate_item] for details.
</description>
@@ -505,7 +507,7 @@
<member name="hide_on_state_item_selection" type="bool" setter="set_hide_on_state_item_selection" getter="is_hide_on_state_item_selection" default="false">
If [code]true[/code], hides the [PopupMenu] when a state item is selected.
</member>
- <member name="items_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
+ <member name="item_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
The number of items currently in the list.
</member>
<member name="submenu_popup_delay" type="float" setter="set_submenu_popup_delay" getter="get_submenu_popup_delay" default="0.3">
@@ -533,12 +535,6 @@
</signal>
</signals>
<theme_items>
- <theme_item name="checked" data_type="icon" type="Texture2D">
- [Texture2D] icon for the checked checkbox items.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] used for the menu items.
- </theme_item>
<theme_item name="font_accelerator_color" data_type="color" type="Color" default="Color(0.7, 0.7, 0.7, 0.8)">
The text [Color] used for shortcuts and accelerators that show next to the menu item name when defined. See [method get_item_accelerator] for more info on accelerators.
</theme_item>
@@ -557,12 +553,6 @@
<theme_item name="font_separator_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
[Color] used for labeled separators' text. See [method add_separator].
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the menu items.
- </theme_item>
- <theme_item name="hover" data_type="style" type="StyleBox">
- [StyleBox] displayed when the [PopupMenu] item is hovered.
- </theme_item>
<theme_item name="hseparation" data_type="constant" type="int" default="4">
The horizontal space between the item's name and the shortcut text/submenu arrow.
</theme_item>
@@ -570,20 +560,20 @@
</theme_item>
<theme_item name="item_start_padding" data_type="constant" type="int" default="2">
</theme_item>
- <theme_item name="labeled_separator_left" data_type="style" type="StyleBox">
- [StyleBox] for the left side of labeled separator. See [method add_separator].
- </theme_item>
- <theme_item name="labeled_separator_right" data_type="style" type="StyleBox">
- [StyleBox] for the right side of labeled separator. See [method add_separator].
- </theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the item text outline.
</theme_item>
- <theme_item name="panel" data_type="style" type="StyleBox">
- Default [StyleBox] of the [PopupMenu] items.
+ <theme_item name="vseparation" data_type="constant" type="int" default="4">
+ The vertical space between each menu item.
</theme_item>
- <theme_item name="panel_disabled" data_type="style" type="StyleBox">
- [StyleBox] used when the [PopupMenu] item is disabled.
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] used for the menu items.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the menu items.
+ </theme_item>
+ <theme_item name="checked" data_type="icon" type="Texture2D">
+ [Texture2D] icon for the checked checkbox items.
</theme_item>
<theme_item name="radio_checked" data_type="icon" type="Texture2D">
[Texture2D] icon for the checked radio button items.
@@ -591,9 +581,6 @@
<theme_item name="radio_unchecked" data_type="icon" type="Texture2D">
[Texture2D] icon for the unchecked radio button items.
</theme_item>
- <theme_item name="separator" data_type="style" type="StyleBox">
- [StyleBox] used for the separators. See [method add_separator].
- </theme_item>
<theme_item name="submenu" data_type="icon" type="Texture2D">
[Texture2D] icon for the submenu arrow (for left-to-right layouts).
</theme_item>
@@ -603,8 +590,23 @@
<theme_item name="unchecked" data_type="icon" type="Texture2D">
[Texture2D] icon for the unchecked checkbox items.
</theme_item>
- <theme_item name="vseparation" data_type="constant" type="int" default="4">
- The vertical space between each menu item.
+ <theme_item name="hover" data_type="style" type="StyleBox">
+ [StyleBox] displayed when the [PopupMenu] item is hovered.
+ </theme_item>
+ <theme_item name="labeled_separator_left" data_type="style" type="StyleBox">
+ [StyleBox] for the left side of labeled separator. See [method add_separator].
+ </theme_item>
+ <theme_item name="labeled_separator_right" data_type="style" type="StyleBox">
+ [StyleBox] for the right side of labeled separator. See [method add_separator].
+ </theme_item>
+ <theme_item name="panel" data_type="style" type="StyleBox">
+ Default [StyleBox] of the [PopupMenu] items.
+ </theme_item>
+ <theme_item name="panel_disabled" data_type="style" type="StyleBox">
+ [StyleBox] used when the [PopupMenu] item is disabled.
+ </theme_item>
+ <theme_item name="separator" data_type="style" type="StyleBox">
+ [StyleBox] used for the separators. See [method add_separator].
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml
index 88132967a0..24cc490ce7 100644
--- a/doc/classes/ProgressBar.xml
+++ b/doc/classes/ProgressBar.xml
@@ -12,19 +12,10 @@
<member name="percent_visible" type="bool" setter="set_percent_visible" getter="is_percent_visible" default="true">
If [code]true[/code], the fill percentage is displayed on the bar.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="0" />
- <member name="step" type="float" setter="set_step" getter="get_step" override="true" default="0.01" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" />
+ <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="0.01" />
</members>
<theme_items>
- <theme_item name="bg" data_type="style" type="StyleBox">
- The style of the background.
- </theme_item>
- <theme_item name="fg" data_type="style" type="StyleBox">
- The style of the progress (i.e. the part that fills the bar).
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- Font used to draw the fill percentage if [member percent_visible] is [code]true[/code].
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)">
The color of the text.
</theme_item>
@@ -34,11 +25,20 @@
<theme_item name="font_shadow_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
The color of the text's shadow.
</theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ Font used to draw the fill percentage if [member percent_visible] is [code]true[/code].
+ </theme_item>
<theme_item name="font_size" data_type="font_size" type="int">
Font size used to draw the fill percentage if [member percent_visible] is [code]true[/code].
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
+ <theme_item name="bg" data_type="style" type="StyleBox">
+ The style of the background.
+ </theme_item>
+ <theme_item name="fg" data_type="style" type="StyleBox">
+ The style of the progress (i.e. the part that fills the bar).
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 7fdac7ccd4..ce9f41410a 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -432,8 +432,9 @@
</member>
<member name="debug/settings/fps/force_fps" type="int" setter="" getter="" default="0">
Maximum number of frames per second allowed. The actual number of frames per second may still be below this value if the game is lagging.
- If [member display/window/vsync/vsync_mode] is set to [code]Enabled[/code] or [code]Adaptive[/code], it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate.
+ If [member display/window/vsync/vsync_mode] is set to [code]Enabled[/code] or [code]Adaptive[/code], it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate. See also [member physics/common/physics_ticks_per_second].
This setting is therefore mostly relevant for lowering the maximum FPS below VSync, e.g. to perform non-real-time rendering of static frames, or test the project under lag conditions.
+ [b]Note:[/b] This property is only read when the project starts. To change the rendering FPS cap at runtime, set [member Engine.target_fps] instead.
</member>
<member name="debug/settings/gdscript/max_call_stack" type="int" setter="" getter="" default="1024">
Maximum call stack allowed for debugging GDScript.
@@ -1481,8 +1482,9 @@
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead.
</member>
<member name="physics/common/physics_ticks_per_second" type="int" setter="" getter="" default="60">
- The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run.
+ The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. See also [member debug/settings/fps/force_fps].
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_ticks_per_second] instead.
+ [b]Note:[/b] Only 8 physics ticks may be simulated per rendered frame at most. If more than 8 physics ticks have to be simulated per rendered frame to keep up with rendering, the game will appear to slow down (even if [code]delta[/code] is used consistently in physics calculations). Therefore, it is recommended not to increase [member physics/common/physics_ticks_per_second] above 240. Otherwise, the game will slow down when the rendering framerate goes below 30 FPS.
</member>
<member name="rendering/2d/opengl/batching_send_null" type="int" setter="" getter="" default="0">
</member>
@@ -1576,7 +1578,7 @@
Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color].
</member>
<member name="rendering/environment/defaults/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
- [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
+ [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, you do not need to set this property.
</member>
<member name="rendering/environment/glow/upscale_mode" type="int" setter="" getter="" default="1">
Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
diff --git a/doc/classes/ProximityGroup3D.xml b/doc/classes/ProximityGroup3D.xml
deleted file mode 100644
index 15735bd6f6..0000000000
--- a/doc/classes/ProximityGroup3D.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ProximityGroup3D" inherits="Node3D" version="4.0">
- <brief_description>
- General-purpose proximity detection node.
- </brief_description>
- <description>
- General-purpose proximity detection node.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- <method name="broadcast">
- <return type="void" />
- <argument index="0" name="method" type="String" />
- <argument index="1" name="parameters" type="Variant" />
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="dispatch_mode" type="int" setter="set_dispatch_mode" getter="get_dispatch_mode" enum="ProximityGroup3D.DispatchMode" default="0">
- </member>
- <member name="grid_radius" type="Vector3" setter="set_grid_radius" getter="get_grid_radius" default="Vector3(1, 1, 1)">
- </member>
- <member name="group_name" type="String" setter="set_group_name" getter="get_group_name" default="&quot;&quot;">
- </member>
- </members>
- <signals>
- <signal name="broadcast">
- <argument index="0" name="method" type="String" />
- <argument index="1" name="parameters" type="Array" />
- <description>
- </description>
- </signal>
- </signals>
- <constants>
- <constant name="MODE_PROXY" value="0" enum="DispatchMode">
- </constant>
- <constant name="MODE_SIGNAL" value="1" enum="DispatchMode">
- </constant>
- </constants>
-</class>
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 4dc3859ca5..65d1654c21 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -7,6 +7,7 @@
[Rect2] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses floating-point coordinates. If you need integer coordinates, use [Rect2i] instead.
The 3D counterpart to [Rect2] is [AABB].
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get a Rect2 with a positive size.
</description>
<tutorials>
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index d66b589ec1..5909784135 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -6,6 +6,7 @@
<description>
[Rect2i] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses integer coordinates. If you need floating-point coordinates, use [Rect2] instead.
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get a Rect2i with a positive size.
</description>
<tutorials>
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 6bfaca8928..84956805c9 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -22,7 +22,7 @@
<argument index="1" name="width" type="int" default="0" />
<argument index="2" name="height" type="int" default="0" />
<argument index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="4" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="4" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<description>
Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image and a [code]color[/code] to tint the image.
If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
@@ -279,7 +279,7 @@
</method>
<method name="push_paragraph">
<return type="void" />
- <argument index="0" name="align" type="int" enum="RichTextLabel.Align" />
+ <argument index="0" name="alignment" type="int" enum="HorizontalAlignment" />
<argument index="1" name="base_direction" type="int" enum="Control.TextDirection" default="0" />
<argument index="2" name="language" type="String" default="&quot;&quot;" />
<argument index="3" name="st_parser" type="int" enum="Control.StructuredTextParser" default="0" />
@@ -296,7 +296,7 @@
<method name="push_table">
<return type="void" />
<argument index="0" name="columns" type="int" />
- <argument index="1" name="inline_align" type="int" enum="InlineAlign" default="0" />
+ <argument index="1" name="inline_align" type="int" enum="InlineAlignment" default="0" />
<description>
Adds a [code][table=columns,inline_align][/code] tag to the tag stack.
</description>
@@ -399,7 +399,7 @@
The range of characters to display, as a [float] between 0.0 and 1.0. When assigned an out of range value, it's the same as assigning 1.0.
[b]Note:[/b] Setting this property updates [member visible_characters] based on current [method get_total_character_count].
</member>
- <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
+ <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="scroll_active" type="bool" setter="set_scroll_active" getter="is_scroll_active" default="true">
If [code]true[/code], the scrollbar is visible. Setting this to [code]false[/code] does not block scrolling completely. See [method scroll_to_line].
</member>
@@ -451,18 +451,6 @@
</signal>
</signals>
<constants>
- <constant name="ALIGN_LEFT" value="0" enum="Align">
- Makes text left aligned.
- </constant>
- <constant name="ALIGN_CENTER" value="1" enum="Align">
- Makes text centered.
- </constant>
- <constant name="ALIGN_RIGHT" value="2" enum="Align">
- Makes text right aligned.
- </constant>
- <constant name="ALIGN_FILL" value="3" enum="Align">
- Makes text fill width.
- </constant>
<constant name="LIST_NUMBERS" value="0" enum="ListType">
Each list item has a number marker.
</constant>
@@ -529,24 +517,9 @@
</constant>
</constants>
<theme_items>
- <theme_item name="bold_font" data_type="font" type="Font">
- The font used for bold text.
- </theme_item>
- <theme_item name="bold_font_size" data_type="font_size" type="int">
- The font size used for bold text.
- </theme_item>
- <theme_item name="bold_italics_font" data_type="font" type="Font">
- The font used for bold italics text.
- </theme_item>
- <theme_item name="bold_italics_font_size" data_type="font_size" type="int">
- The font size used for bold italics text.
- </theme_item>
<theme_item name="default_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The default text color.
</theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- The background The background used when the [RichTextLabel] is focused.
- </theme_item>
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The default tint of text outline.
</theme_item>
@@ -556,36 +529,24 @@
<theme_item name="font_shadow_color" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
The color of the font's shadow.
</theme_item>
- <theme_item name="italics_font" data_type="font" type="Font">
- The font used for italics text.
- </theme_item>
- <theme_item name="italics_font_size" data_type="font_size" type="int">
- The font size used for italics text.
- </theme_item>
- <theme_item name="line_separation" data_type="constant" type="int" default="0">
- The vertical space between lines.
- </theme_item>
- <theme_item name="mono_font" data_type="font" type="Font">
- The font used for monospace text.
+ <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.1, 0.1, 1, 0.8)">
+ The color of the selection box.
</theme_item>
- <theme_item name="mono_font_size" data_type="font_size" type="int">
- The font size used for monospace text.
+ <theme_item name="table_border" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
+ The default cell border color.
</theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- The normal background for the [RichTextLabel].
+ <theme_item name="table_even_row_bg" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
+ The default background color for even rows.
</theme_item>
- <theme_item name="normal_font" data_type="font" type="Font">
- The default text font.
+ <theme_item name="table_odd_row_bg" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
+ The default background color for odd rows.
</theme_item>
- <theme_item name="normal_font_size" data_type="font_size" type="int">
- The default text font size.
+ <theme_item name="line_separation" data_type="constant" type="int" default="0">
+ The vertical space between lines.
</theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
- <theme_item name="selection_color" data_type="color" type="Color" default="Color(0.1, 0.1, 1, 0.8)">
- The color of the selection box.
- </theme_item>
<theme_item name="shadow_offset_x" data_type="constant" type="int" default="1">
The horizontal offset of the font's shadow.
</theme_item>
@@ -595,20 +556,47 @@
<theme_item name="shadow_outline_size" data_type="constant" type="int" default="1">
The size of the shadow outline.
</theme_item>
- <theme_item name="table_border" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
- The default cell border color.
- </theme_item>
- <theme_item name="table_even_row_bg" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
- The default background color for even rows.
- </theme_item>
<theme_item name="table_hseparation" data_type="constant" type="int" default="3">
The horizontal separation of elements in a table.
</theme_item>
- <theme_item name="table_odd_row_bg" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
- The default background color for odd rows.
- </theme_item>
<theme_item name="table_vseparation" data_type="constant" type="int" default="3">
The vertical separation of elements in a table.
</theme_item>
+ <theme_item name="bold_font" data_type="font" type="Font">
+ The font used for bold text.
+ </theme_item>
+ <theme_item name="bold_italics_font" data_type="font" type="Font">
+ The font used for bold italics text.
+ </theme_item>
+ <theme_item name="italics_font" data_type="font" type="Font">
+ The font used for italics text.
+ </theme_item>
+ <theme_item name="mono_font" data_type="font" type="Font">
+ The font used for monospace text.
+ </theme_item>
+ <theme_item name="normal_font" data_type="font" type="Font">
+ The default text font.
+ </theme_item>
+ <theme_item name="bold_font_size" data_type="font_size" type="int">
+ The font size used for bold text.
+ </theme_item>
+ <theme_item name="bold_italics_font_size" data_type="font_size" type="int">
+ The font size used for bold italics text.
+ </theme_item>
+ <theme_item name="italics_font_size" data_type="font_size" type="int">
+ The font size used for italics text.
+ </theme_item>
+ <theme_item name="mono_font_size" data_type="font_size" type="int">
+ The font size used for monospace text.
+ </theme_item>
+ <theme_item name="normal_font_size" data_type="font_size" type="int">
+ The default text font size.
+ </theme_item>
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ The background The background used when the [RichTextLabel] is focused.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ The normal background for the [RichTextLabel].
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml
index b0509a322e..80f0a54e70 100644
--- a/doc/classes/SceneTreeTimer.xml
+++ b/doc/classes/SceneTreeTimer.xml
@@ -22,12 +22,13 @@
}
[/csharp]
[/codeblocks]
+ The timer will be automatically freed after its time elapses.
</description>
<tutorials>
</tutorials>
<members>
<member name="time_left" type="float" setter="set_time_left" getter="get_time_left">
- The time remaining.
+ The time remaining (in seconds).
</member>
</members>
<signals>
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
index 349adb9111..33ca5b4dc9 100644
--- a/doc/classes/ScriptCreateDialog.xml
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -39,8 +39,8 @@
</method>
</methods>
<members>
- <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" override="true" default="false" />
- <member name="title" type="String" setter="set_title" getter="get_title" override="true" default="&quot;Attach Node Script&quot;" />
+ <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
+ <member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Attach Node Script&quot;" />
</members>
<signals>
<signal name="script_created">
diff --git a/doc/classes/ScrollBar.xml b/doc/classes/ScrollBar.xml
index 1f1415bebe..2dcde10616 100644
--- a/doc/classes/ScrollBar.xml
+++ b/doc/classes/ScrollBar.xml
@@ -12,8 +12,8 @@
<member name="custom_step" type="float" setter="set_custom_step" getter="get_custom_step" default="-1.0">
Overrides the step used when clicking increment and decrement buttons or when using arrow keys when the [ScrollBar] is focused.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="0" />
- <member name="step" type="float" setter="set_step" getter="get_step" override="true" default="0.0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" />
+ <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="0.0" />
</members>
<signals>
<signal name="scrolling">
diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml
index 976c32c243..94d9bfdc31 100644
--- a/doc/classes/ScrollContainer.xml
+++ b/doc/classes/ScrollContainer.xml
@@ -22,14 +22,14 @@
<return type="HScrollBar" />
<description>
Returns the horizontal scrollbar [HScrollBar] of this [ScrollContainer].
- [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to disable the horizontal scrollbar, use [member scroll_horizontal_enabled]. If you want to only hide it instead, use [member scroll_horizontal_visible].
+ [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to disable or hide a scrollbar, you can use [member horizontal_scroll_mode].
</description>
</method>
<method name="get_v_scrollbar">
<return type="VScrollBar" />
<description>
Returns the vertical scrollbar [VScrollBar] of this [ScrollContainer].
- [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to disable the vertical scrollbar, use [member scroll_vertical_enabled]. If you want to only hide it instead, use [member scroll_vertical_visible].
+ [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to disable or hide a scrollbar, you can use [member vertical_scroll_mode].
</description>
</method>
</methods>
@@ -37,26 +37,20 @@
<member name="follow_focus" type="bool" setter="set_follow_focus" getter="is_following_focus" default="false">
If [code]true[/code], the ScrollContainer will automatically scroll to focused children (including indirect children) to make sure they are fully visible.
</member>
- <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
+ <member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" enum="ScrollContainer.ScrollMode" default="1">
+ Controls whether horizontal scrollbar can be used and when it should be visible. See [enum ScrollMode] for options.
+ </member>
+ <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="scroll_deadzone" type="int" setter="set_deadzone" getter="get_deadzone" default="0">
</member>
<member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0">
The current horizontal scroll value.
</member>
- <member name="scroll_horizontal_enabled" type="bool" setter="set_enable_h_scroll" getter="is_h_scroll_enabled" default="true">
- If [code]true[/code], enables horizontal scrolling.
- </member>
- <member name="scroll_horizontal_visible" type="bool" setter="set_h_scroll_visible" getter="is_h_scroll_visible" default="true">
- If [code]false[/code], hides the horizontal scrollbar.
- </member>
<member name="scroll_vertical" type="int" setter="set_v_scroll" getter="get_v_scroll" default="0">
The current vertical scroll value.
</member>
- <member name="scroll_vertical_enabled" type="bool" setter="set_enable_v_scroll" getter="is_v_scroll_enabled" default="true">
- If [code]true[/code], enables vertical scrolling.
- </member>
- <member name="scroll_vertical_visible" type="bool" setter="set_v_scroll_visible" getter="is_v_scroll_visible" default="true">
- If [code]false[/code], hides the vertical scrollbar.
+ <member name="vertical_scroll_mode" type="int" setter="set_vertical_scroll_mode" getter="get_vertical_scroll_mode" enum="ScrollContainer.ScrollMode" default="1">
+ Controls whether vertical scrollbar can be used and when it should be visible. See [enum ScrollMode] for options.
</member>
</members>
<signals>
@@ -71,6 +65,20 @@
</description>
</signal>
</signals>
+ <constants>
+ <constant name="SCROLL_MODE_DISABLED" value="0" enum="ScrollMode">
+ Scrolling disabled, scrollbar will be invisible.
+ </constant>
+ <constant name="SCROLL_MODE_AUTO" value="1" enum="ScrollMode">
+ Scrolling enabled, scrollbar will be visible only if necessary, i.e. container's content is bigger than the container.
+ </constant>
+ <constant name="SCROLL_MODE_SHOW_ALWAYS" value="2" enum="ScrollMode">
+ Scrolling enabled, scrollbar will be always visible.
+ </constant>
+ <constant name="SCROLL_MODE_SHOW_NEVER" value="3" enum="ScrollMode">
+ Scrolling enabled, scrollbar will be hidden.
+ </constant>
+ </constants>
<theme_items>
<theme_item name="bg" data_type="style" type="StyleBox">
The background [StyleBox] of the [ScrollContainer].
diff --git a/doc/classes/SkeletonModification3DTwoBoneIK.xml b/doc/classes/SkeletonModification3DTwoBoneIK.xml
index 80f8ba4e5b..0e83cd0b28 100644
--- a/doc/classes/SkeletonModification3DTwoBoneIK.xml
+++ b/doc/classes/SkeletonModification3DTwoBoneIK.xml
@@ -4,7 +4,7 @@
A modification that moves two bones to reach the target.
</brief_description>
<description>
- This [SkeletonModification3D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns 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 verticies of the triangle. Because the algorithm works by making a triangle, it can only opperate on two bones.
+ This [SkeletonModification3D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns 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 opperate on two bones.
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 [SkeletonModification3DFABRIK], but gives similar, natural looking results.
A [Node3D]-based node can be used to define the pole, or bend direction, allowing control over which direction the joint takes when bending to reach the target when the target is within reach.
</description>
diff --git a/doc/classes/Slider.xml b/doc/classes/Slider.xml
index 21a45645b8..41ceb7b8b3 100644
--- a/doc/classes/Slider.xml
+++ b/doc/classes/Slider.xml
@@ -13,11 +13,11 @@
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true">
If [code]true[/code], the slider can be interacted with. If [code]false[/code], the value can be changed only by code.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="scrollable" type="bool" setter="set_scrollable" getter="is_scrollable" default="true">
If [code]true[/code], the value can be changed using the mouse wheel.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" />
<member name="tick_count" type="int" setter="set_ticks" getter="get_ticks" default="0">
Number of ticks displayed on the slider, including border ticks. Ticks are uniformly-distributed value markers.
</member>
diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml
index 615f5e3586..392d4d6a65 100644
--- a/doc/classes/SpinBox.xml
+++ b/doc/classes/SpinBox.xml
@@ -12,14 +12,14 @@
add_child(spin_box)
var line_edit = spin_box.get_line_edit()
line_edit.context_menu_enabled = false
- spin_box.align = LineEdit.ALIGN_RIGHT
+ spin_box.horizontal_alignment = LineEdit.HORIZONTAL_ALIGNMENT_RIGHT
[/gdscript]
[csharp]
var spinBox = new SpinBox();
AddChild(spinBox);
var lineEdit = spinBox.GetLineEdit();
lineEdit.ContextMenuEnabled = false;
- spinBox.Align = LineEdit.AlignEnum.Right;
+ spinBox.AlignHorizontal = LineEdit.HorizontalAlignEnum.Right;
[/csharp]
[/codeblocks]
The above code will create a [SpinBox], disable context menu on it and set the text alignment to right.
@@ -44,8 +44,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" enum="LineEdit.Align" default="0">
- Sets the text alignment of the [SpinBox].
+ <member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
</member>
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true">
If [code]true[/code], the [SpinBox] will be editable. Otherwise, it will be read only.
diff --git a/doc/classes/SpotLight3D.xml b/doc/classes/SpotLight3D.xml
index f9f9a62baa..b5276d25ea 100644
--- a/doc/classes/SpotLight3D.xml
+++ b/doc/classes/SpotLight3D.xml
@@ -11,7 +11,7 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<members>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.03" />
+ <member name="shadow_bias" type="float" setter="set_param" getter="get_param" overrides="Light3D" default="0.03" />
<member name="spot_angle" type="float" setter="set_param" getter="get_param" default="45.0">
The spotlight's angle in degrees.
</member>
diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml
index 5a7fd537e0..4ad78429e9 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -36,5 +36,10 @@
Emitted when the [member frame] changes.
</description>
</signal>
+ <signal name="texture_changed">
+ <description>
+ Emitted when the [member texture] changes.
+ </description>
+ </signal>
</signals>
</class>
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index b723c9f4d4..32abd1caea 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -60,7 +60,8 @@
If [code]true[/code], texture is flipped vertically.
</member>
<member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color(1, 1, 1, 1)">
- A color value that gets multiplied on, could be used for mood-coloring or to simulate the color of light.
+ A color value used to [i]multiply[/i] the texture's colors. Can be used for mood-coloring or to simulate the color of light.
+ [b]Note:[/b] If a [member GeometryInstance3D.material_override] is defined on the [SpriteBase3D], the material override must be configured to take vertex colors into account for albedo. Otherwise, the color defined in [member modulate] will be ignored. For a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] must be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/color] must be inserted in the shader's [code]fragment()[/code] function.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)">
The texture's drawing offset.
diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index 612f8fb740..f97b3e08d1 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -209,8 +209,7 @@
<member name="scrolling_enabled" type="bool" setter="set_scrolling_enabled" getter="get_scrolling_enabled" default="true">
if [code]true[/code], the mouse's scroll wheel can be used to navigate the scroll view.
</member>
- <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" enum="TabBar.TabAlign" default="1">
- The alignment of all tabs. See [enum TabAlign] for details.
+ <member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="1">
</member>
<member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="TabBar.CloseButtonDisplayPolicy" default="0">
Sets when the close button will appear on the tabs. See [enum CloseButtonDisplayPolicy] for details.
@@ -264,17 +263,13 @@
</signal>
</signals>
<constants>
- <constant name="ALIGN_LEFT" value="0" enum="TabAlign">
- Align the tabs to the left.
+ <constant name="ALIGNMENT_LEFT" value="0" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_CENTER" value="1" enum="TabAlign">
- Align the tabs to the center.
+ <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_RIGHT" value="2" enum="TabAlign">
- Align the tabs to the right.
+ <constant name="ALIGNMENT_RIGHT" value="2" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_MAX" value="3" enum="TabAlign">
- Represents the size of the [enum TabAlign] enum.
+ <constant name="ALIGNMENT_MAX" value="3" enum="AlignmentMode">
</constant>
<constant name="CLOSE_BUTTON_SHOW_NEVER" value="0" enum="CloseButtonDisplayPolicy">
Never show the close buttons.
@@ -290,24 +285,6 @@
</constant>
</constants>
<theme_items>
- <theme_item name="close" data_type="icon" type="Texture2D">
- The icon for the close button (see [member tab_close_display_policy]).
- </theme_item>
- <theme_item name="close_bg_highlight" data_type="style" type="StyleBox">
- Background of the close button when it's being hovered with the cursor.
- </theme_item>
- <theme_item name="close_bg_pressed" data_type="style" type="StyleBox">
- Background of the close button when it's being pressed.
- </theme_item>
- <theme_item name="decrement" data_type="icon" type="Texture2D">
- Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent.
- </theme_item>
- <theme_item name="decrement_highlight" data_type="icon" type="Texture2D">
- Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- The font used to draw tab names.
- </theme_item>
<theme_item name="font_disabled_color" data_type="color" type="Color" default="Color(0.9, 0.9, 0.9, 0.2)">
Font color of disabled tabs.
</theme_item>
@@ -317,23 +294,41 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)">
Font color of the currently selected tab.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the tab names.
- </theme_item>
<theme_item name="font_unselected_color" data_type="color" type="Color" default="Color(0.69, 0.69, 0.69, 1)">
Font color of the other, unselected tabs.
</theme_item>
<theme_item name="hseparation" data_type="constant" type="int" default="4">
The horizontal separation between the elements inside tabs.
</theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the tab text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ The font used to draw tab names.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the tab names.
+ </theme_item>
+ <theme_item name="close" data_type="icon" type="Texture2D">
+ The icon for the close button (see [member tab_close_display_policy]).
+ </theme_item>
+ <theme_item name="decrement" data_type="icon" type="Texture2D">
+ Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent.
+ </theme_item>
+ <theme_item name="decrement_highlight" data_type="icon" type="Texture2D">
+ Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
+ </theme_item>
<theme_item name="increment" data_type="icon" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent.
</theme_item>
<theme_item name="increment_highlight" data_type="icon" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the tab text outline.
+ <theme_item name="close_bg_highlight" data_type="style" type="StyleBox">
+ Background of the close button when it's being hovered with the cursor.
+ </theme_item>
+ <theme_item name="close_bg_pressed" data_type="style" type="StyleBox">
+ Background of the close button when it's being pressed.
</theme_item>
<theme_item name="tab_disabled" data_type="style" type="StyleBox">
The style of disabled tabs.
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index 1f32bba5a1..d6e1e13505 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -4,8 +4,9 @@
Tabbed container.
</brief_description>
<description>
- Sets the active tab's [code]visible[/code] property to the value [code]true[/code]. Sets all other children's to [code]false[/code].
+ Arranges [Control] children into a tabbed view, creating a tab for each one. The active tab's corresponding [Control] has its [code]visible[/code] property set to [code]true[/code], and all other children's to [code]false[/code].
Ignores non-[Control] children.
+ [b]Note:[/b] The drawing of the clickable tabs themselves is handled by this node. Adding [TabBar]s as children is not needed.
</description>
<tutorials>
</tutorials>
@@ -140,8 +141,7 @@
<member name="drag_to_rearrange_enabled" type="bool" setter="set_drag_to_rearrange_enabled" getter="get_drag_to_rearrange_enabled" default="false">
If [code]true[/code], tabs can be rearranged with mouse drag.
</member>
- <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" enum="TabContainer.TabAlign" default="1">
- The alignment of all tabs in the tab container. See the [enum TabAlign] constants for details.
+ <member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabContainer.AlignmentMode" default="1">
</member>
<member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible" default="true">
If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden.
@@ -170,26 +170,14 @@
</signal>
</signals>
<constants>
- <constant name="ALIGN_LEFT" value="0" enum="TabAlign">
- Align the tabs to the left.
+ <constant name="ALIGNMENT_LEFT" value="0" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_CENTER" value="1" enum="TabAlign">
- Align the tabs to the center.
+ <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
</constant>
- <constant name="ALIGN_RIGHT" value="2" enum="TabAlign">
- Align the tabs to the right.
+ <constant name="ALIGNMENT_RIGHT" value="2" enum="AlignmentMode">
</constant>
</constants>
<theme_items>
- <theme_item name="decrement" data_type="icon" type="Texture2D">
- Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent.
- </theme_item>
- <theme_item name="decrement_highlight" data_type="icon" type="Texture2D">
- Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- The font used to draw tab names.
- </theme_item>
<theme_item name="font_disabled_color" data_type="color" type="Color" default="Color(0.9, 0.9, 0.9, 0.2)">
Font color of disabled tabs.
</theme_item>
@@ -199,15 +187,30 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)">
Font color of the currently selected tab.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the tab names.
- </theme_item>
<theme_item name="font_unselected_color" data_type="color" type="Color" default="Color(0.69, 0.69, 0.69, 1)">
Font color of the other, unselected tabs.
</theme_item>
<theme_item name="icon_separation" data_type="constant" type="int" default="4">
Space between tab's name and its icon.
</theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the tab text outline.
+ </theme_item>
+ <theme_item name="side_margin" data_type="constant" type="int" default="8">
+ The space at the left and right edges of the tab bar.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ The font used to draw tab names.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the tab names.
+ </theme_item>
+ <theme_item name="decrement" data_type="icon" type="Texture2D">
+ Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent.
+ </theme_item>
+ <theme_item name="decrement_highlight" data_type="icon" type="Texture2D">
+ Icon for the left arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
+ </theme_item>
<theme_item name="increment" data_type="icon" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent.
</theme_item>
@@ -220,15 +223,9 @@
<theme_item name="menu_highlight" data_type="icon" type="Texture2D">
The icon for the menu button (see [method set_popup]) when it's being hovered with the cursor.
</theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the tab text outline.
- </theme_item>
<theme_item name="panel" data_type="style" type="StyleBox">
The style for the background fill.
</theme_item>
- <theme_item name="side_margin" data_type="constant" type="int" default="8">
- The space at the left and right edges of the tab bar.
- </theme_item>
<theme_item name="tab_disabled" data_type="style" type="StyleBox">
The style of disabled tabs.
</theme_item>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 16d8595b4e..ffc91decca 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -586,6 +586,13 @@
Returns whether the menu is visible. Use this instead of [code]get_menu().visible[/code] to improve performance (so the creation of the menu is avoided).
</description>
</method>
+ <method name="is_mouse_over_selection" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="edges" type="bool" />
+ <description>
+ Returns whether the mouse is over selection. If [code]edges[/code] is [code]true[/code], the edges are considered part of the selection.
+ </description>
+ </method>
<method name="is_overtype_mode_enabled" qualifiers="const">
<return type="bool" />
<description>
@@ -964,7 +971,7 @@
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true">
If [code]false[/code], existing text cannot be modified and new text cannot be added.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled" default="false">
If [code]true[/code], all occurrences of the selected text will be highlighted.
</member>
@@ -984,7 +991,7 @@
<member name="minimap_width" type="int" setter="set_minimap_width" getter="get_minimap_width" default="80">
The width, in pixels, of the minimap.
</member>
- <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
+ <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" overrides="Control" enum="Control.CursorShape" default="1" />
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
If [code]true[/code], custom [code]font_selected_color[/code] will be used for selected text.
</member>
@@ -1221,12 +1228,6 @@
<theme_item name="current_line_color" data_type="color" type="Color" default="Color(0.25, 0.25, 0.26, 0.8)">
Background [Color] of the line containing the caret.
</theme_item>
- <theme_item name="focus" data_type="style" type="StyleBox">
- Sets the [StyleBox] when in focus.
- </theme_item>
- <theme_item name="font" data_type="font" type="Font">
- Sets the default [Font].
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
Sets the font [Color].
</theme_item>
@@ -1239,21 +1240,6 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Sets default font size.
- </theme_item>
- <theme_item name="line_spacing" data_type="constant" type="int" default="4">
- Sets the spacing between the lines.
- </theme_item>
- <theme_item name="normal" data_type="style" type="StyleBox">
- Sets the [StyleBox] of this [TextEdit].
- </theme_item>
- <theme_item name="outline_size" data_type="constant" type="int" default="0">
- The size of the text outline.
- </theme_item>
- <theme_item name="read_only" data_type="style" type="StyleBox">
- Sets the [StyleBox] of this [TextEdit] when [member editable] is disabled.
- </theme_item>
<theme_item name="search_result_border_color" data_type="color" type="Color" default="Color(0.3, 0.3, 0.3, 0.4)">
[Color] of the border around text that matches the search query.
</theme_item>
@@ -1263,14 +1249,35 @@
<theme_item name="selection_color" data_type="color" type="Color" default="Color(0.49, 0.49, 0.49, 1)">
Sets the highlight [Color] of text selections.
</theme_item>
+ <theme_item name="word_highlighted_color" data_type="color" type="Color" default="Color(0.8, 0.9, 0.9, 0.15)">
+ Sets the highlight [Color] of multiple occurrences. [member highlight_all_occurrences] has to be enabled.
+ </theme_item>
+ <theme_item name="line_spacing" data_type="constant" type="int" default="4">
+ Sets the spacing between the lines.
+ </theme_item>
+ <theme_item name="outline_size" data_type="constant" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ Sets the default [Font].
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Sets default font size.
+ </theme_item>
<theme_item name="space" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] for space text characters.
</theme_item>
<theme_item name="tab" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] for tab text characters.
</theme_item>
- <theme_item name="word_highlighted_color" data_type="color" type="Color" default="Color(0.8, 0.9, 0.9, 0.15)">
- Sets the highlight [Color] of multiple occurrences. [member highlight_all_occurrences] has to be enabled.
+ <theme_item name="focus" data_type="style" type="StyleBox">
+ Sets the [StyleBox] when in focus.
+ </theme_item>
+ <theme_item name="normal" data_type="style" type="StyleBox">
+ Sets the [StyleBox] of this [TextEdit].
+ </theme_item>
+ <theme_item name="read_only" data_type="style" type="StyleBox">
+ Sets the [StyleBox] of this [TextEdit] when [member editable] is disabled.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml
index 598d0fb859..1eaccf4604 100644
--- a/doc/classes/TextLine.xml
+++ b/doc/classes/TextLine.xml
@@ -13,7 +13,7 @@
<return type="bool" />
<argument index="0" name="key" type="Variant" />
<argument index="1" name="size" type="Vector2" />
- <argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="2" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<argument index="3" name="length" type="int" default="1" />
<description>
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
@@ -122,7 +122,7 @@
<return type="bool" />
<argument index="0" name="key" type="Variant" />
<argument index="1" name="size" type="Vector2" />
- <argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="2" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<description>
Sets new size and alignment of embedded object.
</description>
@@ -144,8 +144,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" enum="HAlign" default="0">
- Text horizontal alignment.
+ <member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
</member>
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index a7122b827e..6a510e4a74 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -13,7 +13,7 @@
<return type="bool" />
<argument index="0" name="key" type="Variant" />
<argument index="1" name="size" type="Vector2" />
- <argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="2" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<argument index="3" name="length" type="int" default="1" />
<description>
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
@@ -240,7 +240,7 @@
<return type="bool" />
<argument index="0" name="key" type="Variant" />
<argument index="1" name="size" type="Vector2" />
- <argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="2" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<description>
Sets new size and alignment of embedded object.
</description>
@@ -275,7 +275,7 @@
</method>
</methods>
<members>
- <member name="align" type="int" setter="set_align" getter="get_align" enum="HAlign" default="0">
+ <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="HorizontalAlignment" default="0">
Paragraph horizontal alignment.
</member>
<member name="custom_punctuation" type="String" setter="set_custom_punctuation" getter="get_custom_punctuation" default="&quot;&quot;">
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 512078c56c..6da45fdd4a 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -886,7 +886,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="key" type="Variant" />
<argument index="2" name="size" type="Vector2" />
- <argument index="3" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="3" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<argument index="4" name="length" type="int" default="1" />
<description>
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
@@ -1213,7 +1213,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="key" type="Variant" />
<argument index="2" name="size" type="Vector2" />
- <argument index="3" name="inline_align" type="int" enum="InlineAlign" default="5" />
+ <argument index="3" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<description>
Sets new size and alignment of embedded object.
</description>
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index 32f8107e0a..af558150e2 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -893,7 +893,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="key" type="Variant" />
<argument index="2" name="size" type="Vector2" />
- <argument index="3" name="inline_align" type="int" enum="InlineAlign" />
+ <argument index="3" name="inline_align" type="int" enum="InlineAlignment" />
<argument index="4" name="length" type="int" />
<description>
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
@@ -1222,7 +1222,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="key" type="Variant" />
<argument index="2" name="size" type="Vector2" />
- <argument index="3" name="inline_align" type="int" enum="InlineAlign" />
+ <argument index="3" name="inline_align" type="int" enum="InlineAlignment" />
<description>
Sets new size and alignment of embedded object.
</description>
diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml
index ee47557b39..25725d2f67 100644
--- a/doc/classes/TextureProgressBar.xml
+++ b/doc/classes/TextureProgressBar.xml
@@ -27,7 +27,7 @@
<member name="fill_mode" type="int" setter="set_fill_mode" getter="get_fill_mode" default="0">
The fill direction. See [enum FillMode] for possible values.
</member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="1" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
<member name="nine_patch_stretch" type="bool" setter="set_nine_patch_stretch" getter="get_nine_patch_stretch" default="false">
If [code]true[/code], Godot treats the bar's textures like in [NinePatchRect]. Use the [code]stretch_margin_*[/code] properties like [member stretch_margin_bottom] to set up the nine patch's 3×3 grid. When using a radial [member fill_mode], this setting will enable stretching.
</member>
diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml
index 4f18f43ddf..a160eceb35 100644
--- a/doc/classes/TextureRect.xml
+++ b/doc/classes/TextureRect.xml
@@ -19,7 +19,7 @@
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v" default="false">
If [code]true[/code], texture is flipped vertically.
</member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" override="true" enum="Control.MouseFilter" default="1" />
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
<member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureRect.StretchMode" default="0">
Controls the texture's behavior when resizing the node's bounding rectangle. See [enum StretchMode].
</member>
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index be41cdde99..97cbf6918d 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -225,17 +225,17 @@
</description>
</operator>
<operator name="operator *">
- <return type="Transform2D" />
- <argument index="0" name="right" type="Transform2D" />
+ <return type="Rect2" />
+ <argument index="0" name="right" type="Rect2" />
<description>
- Composes these two transformation matrices by multiplying them together. This has the effect of transforming the second transform (the child) by the first transform (the parent).
+ Transforms (multiplies) the [Rect2] by the given [Transform2D] matrix.
</description>
</operator>
<operator name="operator *">
- <return type="Rect2" />
- <argument index="0" name="right" type="Rect2" />
+ <return type="Transform2D" />
+ <argument index="0" name="right" type="Transform2D" />
<description>
- Transforms (multiplies) the [Rect2] by the given [Transform2D] matrix.
+ Composes these two transformation matrices by multiplying them together. This has the effect of transforming the second transform (the child) by the first transform (the parent).
</description>
</operator>
<operator name="operator *">
diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml
index 511574f6aa..e62cb9216e 100644
--- a/doc/classes/Transform3D.xml
+++ b/doc/classes/Transform3D.xml
@@ -152,6 +152,13 @@
</description>
</operator>
<operator name="operator *">
+ <return type="AABB" />
+ <argument index="0" name="right" type="AABB" />
+ <description>
+ Transforms (multiplies) the [AABB] by the given [Transform3D] matrix.
+ </description>
+ </operator>
+ <operator name="operator *">
<return type="PackedVector3Array" />
<argument index="0" name="right" type="PackedVector3Array" />
<description>
@@ -166,13 +173,6 @@
</description>
</operator>
<operator name="operator *">
- <return type="AABB" />
- <argument index="0" name="right" type="AABB" />
- <description>
- Transforms (multiplies) the [AABB] by the given [Transform3D] matrix.
- </description>
- </operator>
- <operator name="operator *">
<return type="Vector3" />
<argument index="0" name="right" type="Vector3" />
<description>
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index 519e1cb041..a1b4404079 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -49,7 +49,7 @@
<argument index="0" name="locale" type="String" />
<description>
Returns the [Translation] instance based on the [code]locale[/code] passed in.
- It will return a [code]nullptr[/code] if there is no [Translation] instance that matches the [code]locale[/code].
+ It will return [code]null[/code] if there is no [Translation] instance that matches the [code]locale[/code].
</description>
</method>
<method name="pseudolocalize" qualifiers="const">
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index ed24905254..10bbdc0301 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -35,12 +35,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="are_column_titles_visible" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if the column titles are being shown.
- </description>
- </method>
<method name="clear">
<return type="void" />
<description>
@@ -313,13 +307,6 @@
Sets OpenType feature [code]tag[/code] for the column title.
</description>
</method>
- <method name="set_column_titles_visible">
- <return type="void" />
- <argument index="0" name="visible" type="bool" />
- <description>
- If [code]true[/code], column titles are visible.
- </description>
- </method>
</methods>
<members>
<member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect" default="false">
@@ -328,6 +315,9 @@
<member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select" default="false">
If [code]true[/code], a right mouse button click can select items.
</member>
+ <member name="column_titles_visible" type="bool" setter="set_column_titles_visible" getter="are_column_titles_visible" default="false">
+ If [code]true[/code], column titles are visible.
+ </member>
<member name="columns" type="int" setter="set_columns" getter="get_columns" default="1">
The number of columns.
</member>
@@ -335,14 +325,14 @@
The drop mode as an OR combination of flags. See [enum DropModeFlags] constants. Once dropping is done, reverts to [constant DROP_MODE_DISABLED]. Setting this during [method Control._can_drop_data] is recommended.
This controls the drop sections, i.e. the decision and drawing of possible drop locations based on the mouse position.
</member>
- <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
+ <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="hide_folding" type="bool" setter="set_hide_folding" getter="is_folding_hidden" default="false">
If [code]true[/code], the folding arrow is hidden.
</member>
<member name="hide_root" type="bool" setter="set_hide_root" getter="is_root_hidden" default="false">
If [code]true[/code], the tree's root is hidden.
</member>
- <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" />
+ <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="scroll_horizontal_enabled" type="bool" setter="set_h_scroll_enabled" getter="is_h_scroll_enabled" default="true">
If [code]true[/code], enables horizontal scrolling.
</member>
@@ -474,66 +464,15 @@
</constant>
</constants>
<theme_items>
- <theme_item name="arrow" data_type="icon" type="Texture2D">
- The arrow icon used when a foldable item is not collapsed.
- </theme_item>
- <theme_item name="arrow_collapsed" data_type="icon" type="Texture2D">
- The arrow icon used when a foldable item is collapsed (for left-to-right layouts).
- </theme_item>
- <theme_item name="arrow_collapsed_mirrored" data_type="icon" type="Texture2D">
- The arrow icon used when a foldable item is collapsed (for right-to-left layouts).
- </theme_item>
- <theme_item name="bg" data_type="style" type="StyleBox">
- Default [StyleBox] for the [Tree], i.e. used when the control is not being focused.
- </theme_item>
- <theme_item name="bg_focus" data_type="style" type="StyleBox">
- [StyleBox] used when the [Tree] is being focused.
- </theme_item>
- <theme_item name="button_margin" data_type="constant" type="int" default="4">
- The horizontal space between each button in a cell.
- </theme_item>
- <theme_item name="button_pressed" data_type="style" type="StyleBox">
- [StyleBox] used when a button in the tree is pressed.
- </theme_item>
- <theme_item name="checked" data_type="icon" type="Texture2D">
- The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is checked.
- </theme_item>
<theme_item name="children_hl_line_color" data_type="color" type="Color" default="Color(0.27, 0.27, 0.27, 1)">
The [Color] of the relationship lines between the selected [TreeItem] and its children.
</theme_item>
- <theme_item name="children_hl_line_width" data_type="constant" type="int" default="1">
- The width of the relationship lines between the selected [TreeItem] and its children.
- </theme_item>
- <theme_item name="cursor" data_type="style" type="StyleBox">
- [StyleBox] used for the cursor, when the [Tree] is being focused.
- </theme_item>
- <theme_item name="cursor_unfocused" data_type="style" type="StyleBox">
- [StyleBox] used for the cursor, when the [Tree] is not being focused.
- </theme_item>
- <theme_item name="custom_button" data_type="style" type="StyleBox">
- Default [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell.
- </theme_item>
<theme_item name="custom_button_font_highlight" data_type="color" type="Color" default="Color(0.94, 0.94, 0.94, 1)">
Text [Color] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered.
</theme_item>
- <theme_item name="custom_button_hover" data_type="style" type="StyleBox">
- [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered.
- </theme_item>
- <theme_item name="custom_button_pressed" data_type="style" type="StyleBox">
- [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's pressed.
- </theme_item>
- <theme_item name="draw_guides" data_type="constant" type="int" default="1">
- Draws the guidelines if not zero, this acts as a boolean. The guideline is a horizontal line drawn at the bottom of each item.
- </theme_item>
- <theme_item name="draw_relationship_lines" data_type="constant" type="int" default="0">
- Draws the relationship lines if not zero, this acts as a boolean. Relationship lines are drawn at the start of child items to show hierarchy.
- </theme_item>
<theme_item name="drop_position_color" data_type="color" type="Color" default="Color(1, 0.3, 0.2, 1)">
[Color] used to draw possible drop locations. See [enum DropModeFlags] constants for further description of drop locations.
</theme_item>
- <theme_item name="font" data_type="font" type="Font">
- [Font] of the item's text.
- </theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.69, 0.69, 0.69, 1)">
Default text [Color] of the item.
</theme_item>
@@ -543,36 +482,45 @@
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the item is selected.
</theme_item>
- <theme_item name="font_size" data_type="font_size" type="int">
- Font size of the item's text.
- </theme_item>
<theme_item name="guide_color" data_type="color" type="Color" default="Color(0, 0, 0, 0.1)">
[Color] of the guideline.
</theme_item>
+ <theme_item name="parent_hl_line_color" data_type="color" type="Color" default="Color(0.27, 0.27, 0.27, 1)">
+ The [Color] of the relationship lines between the selected [TreeItem] and its parents.
+ </theme_item>
+ <theme_item name="relationship_line_color" data_type="color" type="Color" default="Color(0.27, 0.27, 0.27, 1)">
+ The default [Color] of the relationship lines.
+ </theme_item>
+ <theme_item name="title_button_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
+ Default text [Color] of the title button.
+ </theme_item>
+ <theme_item name="button_margin" data_type="constant" type="int" default="4">
+ The horizontal space between each button in a cell.
+ </theme_item>
+ <theme_item name="children_hl_line_width" data_type="constant" type="int" default="1">
+ The width of the relationship lines between the selected [TreeItem] and its children.
+ </theme_item>
+ <theme_item name="draw_guides" data_type="constant" type="int" default="1">
+ Draws the guidelines if not zero, this acts as a boolean. The guideline is a horizontal line drawn at the bottom of each item.
+ </theme_item>
+ <theme_item name="draw_relationship_lines" data_type="constant" type="int" default="0">
+ Draws the relationship lines if not zero, this acts as a boolean. Relationship lines are drawn at the start of child items to show hierarchy.
+ </theme_item>
<theme_item name="hseparation" data_type="constant" type="int" default="4">
The horizontal space between item cells. This is also used as the margin at the start of an item when folding is disabled.
</theme_item>
- <theme_item name="indeterminate" data_type="icon" type="Texture2D">
- The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is indeterminate.
- </theme_item>
<theme_item name="item_margin" data_type="constant" type="int" default="12">
The horizontal margin at the start of an item. This is used when folding is enabled for the item.
</theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
The size of the text outline.
</theme_item>
- <theme_item name="parent_hl_line_color" data_type="color" type="Color" default="Color(0.27, 0.27, 0.27, 1)">
- The [Color] of the relationship lines between the selected [TreeItem] and its parents.
- </theme_item>
<theme_item name="parent_hl_line_margin" data_type="constant" type="int" default="0">
The space between the parent relationship lines for the selected [TreeItem] and the relationship lines to its siblings that are not selected.
</theme_item>
<theme_item name="parent_hl_line_width" data_type="constant" type="int" default="1">
The width of the relationship lines between the selected [TreeItem] and its parents.
</theme_item>
- <theme_item name="relationship_line_color" data_type="color" type="Color" default="Color(0.27, 0.27, 0.27, 1)">
- The default [Color] of the relationship lines.
- </theme_item>
<theme_item name="relationship_line_width" data_type="constant" type="int" default="1">
The default width of the relationship lines.
</theme_item>
@@ -582,21 +530,72 @@
<theme_item name="scroll_speed" data_type="constant" type="int" default="12">
The speed of border scrolling.
</theme_item>
+ <theme_item name="vseparation" data_type="constant" type="int" default="4">
+ The vertical padding inside each item, i.e. the distance between the item's content and top/bottom border.
+ </theme_item>
+ <theme_item name="font" data_type="font" type="Font">
+ [Font] of the item's text.
+ </theme_item>
+ <theme_item name="title_button_font" data_type="font" type="Font">
+ [Font] of the title button's text.
+ </theme_item>
+ <theme_item name="font_size" data_type="font_size" type="int">
+ Font size of the item's text.
+ </theme_item>
+ <theme_item name="arrow" data_type="icon" type="Texture2D">
+ The arrow icon used when a foldable item is not collapsed.
+ </theme_item>
+ <theme_item name="arrow_collapsed" data_type="icon" type="Texture2D">
+ The arrow icon used when a foldable item is collapsed (for left-to-right layouts).
+ </theme_item>
+ <theme_item name="arrow_collapsed_mirrored" data_type="icon" type="Texture2D">
+ The arrow icon used when a foldable item is collapsed (for right-to-left layouts).
+ </theme_item>
+ <theme_item name="checked" data_type="icon" type="Texture2D">
+ The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is checked.
+ </theme_item>
+ <theme_item name="indeterminate" data_type="icon" type="Texture2D">
+ The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is indeterminate.
+ </theme_item>
<theme_item name="select_arrow" data_type="icon" type="Texture2D">
The arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell.
</theme_item>
+ <theme_item name="unchecked" data_type="icon" type="Texture2D">
+ The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is unchecked.
+ </theme_item>
+ <theme_item name="updown" data_type="icon" type="Texture2D">
+ The updown arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell.
+ </theme_item>
+ <theme_item name="bg" data_type="style" type="StyleBox">
+ Default [StyleBox] for the [Tree], i.e. used when the control is not being focused.
+ </theme_item>
+ <theme_item name="bg_focus" data_type="style" type="StyleBox">
+ [StyleBox] used when the [Tree] is being focused.
+ </theme_item>
+ <theme_item name="button_pressed" data_type="style" type="StyleBox">
+ [StyleBox] used when a button in the tree is pressed.
+ </theme_item>
+ <theme_item name="cursor" data_type="style" type="StyleBox">
+ [StyleBox] used for the cursor, when the [Tree] is being focused.
+ </theme_item>
+ <theme_item name="cursor_unfocused" data_type="style" type="StyleBox">
+ [StyleBox] used for the cursor, when the [Tree] is not being focused.
+ </theme_item>
+ <theme_item name="custom_button" data_type="style" type="StyleBox">
+ Default [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell.
+ </theme_item>
+ <theme_item name="custom_button_hover" data_type="style" type="StyleBox">
+ [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered.
+ </theme_item>
+ <theme_item name="custom_button_pressed" data_type="style" type="StyleBox">
+ [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's pressed.
+ </theme_item>
<theme_item name="selected" data_type="style" type="StyleBox">
[StyleBox] for the selected items, used when the [Tree] is not being focused.
</theme_item>
<theme_item name="selected_focus" data_type="style" type="StyleBox">
[StyleBox] for the selected items, used when the [Tree] is being focused.
</theme_item>
- <theme_item name="title_button_color" data_type="color" type="Color" default="Color(0.88, 0.88, 0.88, 1)">
- Default text [Color] of the title button.
- </theme_item>
- <theme_item name="title_button_font" data_type="font" type="Font">
- [Font] of the title button's text.
- </theme_item>
<theme_item name="title_button_hover" data_type="style" type="StyleBox">
[StyleBox] used when the title button is being hovered.
</theme_item>
@@ -606,14 +605,5 @@
<theme_item name="title_button_pressed" data_type="style" type="StyleBox">
[StyleBox] used when the title button is being pressed.
</theme_item>
- <theme_item name="unchecked" data_type="icon" type="Texture2D">
- The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is unchecked.
- </theme_item>
- <theme_item name="updown" data_type="icon" type="Texture2D">
- The updown arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell.
- </theme_item>
- <theme_item name="vseparation" data_type="constant" type="int" default="4">
- The vertical padding inside each item, i.e. the distance between the item's content and top/bottom border.
- </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index b997d87ac0..7da98788bb 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -293,8 +293,8 @@
Returns the given column's text.
</description>
</method>
- <method name="get_text_align" qualifiers="const">
- <return type="int" enum="TreeItem.TextAlign" />
+ <method name="get_text_alignment" qualifiers="const">
+ <return type="int" enum="HorizontalAlignment" />
<argument index="0" name="column" type="int" />
<description>
Returns the given column's text alignment.
@@ -623,12 +623,12 @@
Sets the given column's text value.
</description>
</method>
- <method name="set_text_align">
+ <method name="set_text_alignment">
<return type="void" />
<argument index="0" name="column" type="int" />
- <argument index="1" name="text_align" type="int" enum="TreeItem.TextAlign" />
+ <argument index="1" name="text_alignment" type="int" enum="HorizontalAlignment" />
<description>
- Sets the given column's text alignment. See [enum TextAlign] for possible values.
+ Sets the given column's text alignment. See [enum HorizontalAlignment] for possible values.
</description>
</method>
<method name="set_text_direction">
@@ -679,14 +679,5 @@
</constant>
<constant name="CELL_MODE_CUSTOM" value="4" enum="TreeCellMode">
</constant>
- <constant name="ALIGN_LEFT" value="0" enum="TextAlign">
- Align text to the left. See [code]set_text_align()[/code].
- </constant>
- <constant name="ALIGN_CENTER" value="1" enum="TextAlign">
- Center text. See [code]set_text_align()[/code].
- </constant>
- <constant name="ALIGN_RIGHT" value="2" enum="TextAlign">
- Align text to the right. See [code]set_text_align()[/code].
- </constant>
</constants>
</class>
diff --git a/doc/classes/VScrollBar.xml b/doc/classes/VScrollBar.xml
index 0cf06576f6..09df3411d8 100644
--- a/doc/classes/VScrollBar.xml
+++ b/doc/classes/VScrollBar.xml
@@ -9,8 +9,8 @@
<tutorials>
</tutorials>
<members>
- <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" override="true" default="0" />
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="1" />
+ <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="1" />
</members>
<theme_items>
<theme_item name="decrement" data_type="icon" type="Texture2D">
@@ -22,15 +22,6 @@
<theme_item name="decrement_pressed" data_type="icon" type="Texture2D">
Displayed when the decrement button is being pressed.
</theme_item>
- <theme_item name="grabber" data_type="style" type="StyleBox">
- Used as texture for the grabber, the draggable element representing current scroll.
- </theme_item>
- <theme_item name="grabber_highlight" data_type="style" type="StyleBox">
- Used when the mouse hovers over the grabber.
- </theme_item>
- <theme_item name="grabber_pressed" data_type="style" type="StyleBox">
- Used when the grabber is being dragged.
- </theme_item>
<theme_item name="increment" data_type="icon" type="Texture2D">
Icon used as a button to scroll the [ScrollBar] down. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
@@ -40,6 +31,15 @@
<theme_item name="increment_pressed" data_type="icon" type="Texture2D">
Displayed when the increment button is being pressed.
</theme_item>
+ <theme_item name="grabber" data_type="style" type="StyleBox">
+ Used as texture for the grabber, the draggable element representing current scroll.
+ </theme_item>
+ <theme_item name="grabber_highlight" data_type="style" type="StyleBox">
+ Used when the mouse hovers over the grabber.
+ </theme_item>
+ <theme_item name="grabber_pressed" data_type="style" type="StyleBox">
+ Used when the grabber is being dragged.
+ </theme_item>
<theme_item name="scroll" data_type="style" type="StyleBox">
Used as background of this [ScrollBar].
</theme_item>
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index 286674a9b4..c1fea97ddc 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -10,29 +10,29 @@
<tutorials>
</tutorials>
<members>
- <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" override="true" default="0" />
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="1" />
+ <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="1" />
</members>
<theme_items>
<theme_item name="grabber" data_type="icon" type="Texture2D">
The texture for the grabber (the draggable element).
</theme_item>
- <theme_item name="grabber_area" data_type="style" type="StyleBox">
- The background of the area below the grabber.
- </theme_item>
- <theme_item name="grabber_area_highlight" data_type="style" type="StyleBox">
- </theme_item>
<theme_item name="grabber_disabled" data_type="icon" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
<theme_item name="grabber_highlight" data_type="icon" type="Texture2D">
The texture for the grabber when it's focused.
</theme_item>
- <theme_item name="slider" data_type="style" type="StyleBox">
- The background for the whole slider. Determines the width of the [code]grabber_area[/code].
- </theme_item>
<theme_item name="tick" data_type="icon" type="Texture2D">
The texture for the ticks, visible when [member Slider.tick_count] is greater than 0.
</theme_item>
+ <theme_item name="grabber_area" data_type="style" type="StyleBox">
+ The background of the area below the grabber.
+ </theme_item>
+ <theme_item name="grabber_area_highlight" data_type="style" type="StyleBox">
+ </theme_item>
+ <theme_item name="slider" data_type="style" type="StyleBox">
+ The background for the whole slider. Determines the width of the [code]grabber_area[/code].
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/VSplitContainer.xml b/doc/classes/VSplitContainer.xml
index 323ce1fe80..6316068e9d 100644
--- a/doc/classes/VSplitContainer.xml
+++ b/doc/classes/VSplitContainer.xml
@@ -12,13 +12,13 @@
<theme_item name="autohide" data_type="constant" type="int" default="1">
Boolean value. If 1 ([code]true[/code]), the grabber will hide automatically when it isn't under the cursor. If 0 ([code]false[/code]), it's always visible.
</theme_item>
- <theme_item name="bg" data_type="style" type="StyleBox">
+ <theme_item name="separation" data_type="constant" type="int" default="12">
+ The space between sides of the container.
</theme_item>
<theme_item name="grabber" data_type="icon" type="Texture2D">
The icon used for the grabber drawn in the middle area.
</theme_item>
- <theme_item name="separation" data_type="constant" type="int" default="12">
- The space between sides of the container.
+ <theme_item name="bg" data_type="style" type="StyleBox">
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 595af6222c..f3c2d743b6 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -125,16 +125,16 @@
</method>
<method name="direction_to" qualifiers="const">
<return type="Vector2" />
- <argument index="0" name="b" type="Vector2" />
+ <argument index="0" name="to" type="Vector2" />
<description>
- Returns the normalized vector pointing from this vector to [code]b[/code]. This is equivalent to using [code](b - a).normalized()[/code].
+ Returns the normalized vector pointing from this vector to [code]to[/code]. This is equivalent to using [code](b - a).normalized()[/code].
</description>
</method>
<method name="distance_squared_to" qualifiers="const">
<return type="float" />
<argument index="0" name="to" type="Vector2" />
<description>
- Returns the squared distance between this vector and [code]b[/code].
+ Returns the squared distance between this vector and [code]to[/code].
This method runs faster than [method distance_to], so prefer it if you need to compare vectors or need the squared distance for some formula.
</description>
</method>
@@ -214,12 +214,24 @@
Returns the vector with a maximum length by limiting its length to [code]length[/code].
</description>
</method>
+ <method name="max_axis_index" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
+ </description>
+ </method>
+ <method name="min_axis_index" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Y].
+ </description>
+ </method>
<method name="move_toward" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="to" type="Vector2" />
<argument index="1" name="delta" type="float" />
<description>
- Moves the vector toward [code]to[/code] by the fixed [code]delta[/code] amount.
+ Moves the vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
</description>
</method>
<method name="normalized" qualifiers="const">
@@ -315,10 +327,10 @@
</members>
<constants>
<constant name="AXIS_X" value="0">
- Enumerated value for the X axis.
+ Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Y" value="1">
- Enumerated value for the Y axis.
+ Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector2(0, 0)">
Zero vector, a vector with all components set to [code]0[/code].
@@ -358,19 +370,19 @@
</operator>
<operator name="operator *">
<return type="Vector2" />
- <argument index="0" name="right" type="Vector2" />
+ <argument index="0" name="right" type="Transform2D" />
<description>
- Multiplies each component of the [Vector2] by the components of the given [Vector2].
- [codeblock]
- print(Vector2(10, 20) * Vector2(3, 4)) # Prints "(30, 80)"
- [/codeblock]
+ Inversely transforms (multiplies) the [Vector2] by the given [Transform2D] transformation matrix.
</description>
</operator>
<operator name="operator *">
<return type="Vector2" />
- <argument index="0" name="right" type="Transform2D" />
+ <argument index="0" name="right" type="Vector2" />
<description>
- Inversely transforms (multiplies) the [Vector2] by the given [Transform2D] transformation matrix.
+ Multiplies each component of the [Vector2] by the components of the given [Vector2].
+ [codeblock]
+ print(Vector2(10, 20) * Vector2(3, 4)) # Prints "(30, 80)"
+ [/codeblock]
</description>
</operator>
<operator name="operator *">
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index 62362409a5..a9334d924f 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -64,6 +64,18 @@
Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component.
</description>
</method>
+ <method name="max_axis_index" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
+ </description>
+ </method>
+ <method name="min_axis_index" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Y].
+ </description>
+ </method>
<method name="sign" qualifiers="const">
<return type="Vector2i" />
<description>
@@ -81,10 +93,10 @@
</members>
<constants>
<constant name="AXIS_X" value="0">
- Enumerated value for the X axis.
+ Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Y" value="1">
- Enumerated value for the Y axis.
+ Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector2i(0, 0)">
Zero vector, a vector with all components set to [code]0[/code].
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 62d467c505..da5e4f4f43 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -86,7 +86,7 @@
<return type="Vector3" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the cross product of this vector and [code]b[/code].
+ Returns the cross product of this vector and [code]with[/code].
</description>
</method>
<method name="cubic_interpolate" qualifiers="const">
@@ -101,31 +101,31 @@
</method>
<method name="direction_to" qualifiers="const">
<return type="Vector3" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the normalized vector pointing from this vector to [code]b[/code]. This is equivalent to using [code](b - a).normalized()[/code].
+ Returns the normalized vector pointing from this vector to [code]to[/code]. This is equivalent to using [code](b - a).normalized()[/code].
</description>
</method>
<method name="distance_squared_to" qualifiers="const">
<return type="float" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the squared distance between this vector and [code]b[/code].
+ Returns the squared distance between this vector and [code]to[/code].
This method runs faster than [method distance_to], so prefer it if you need to compare vectors or need the squared distance for some formula.
</description>
</method>
<method name="distance_to" qualifiers="const">
<return type="float" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the distance between this vector and [code]b[/code].
+ Returns the distance between this vector and [code]to[/code].
</description>
</method>
<method name="dot" qualifiers="const">
<return type="float" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the dot product of this vector and [code]b[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player.
+ Returns the dot product of this vector and [code]with[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player.
The dot product will be [code]0[/code] for a straight angle (90 degrees), greater than 0 for angles narrower than 90 degrees and lower than 0 for angles wider than 90 degrees.
When using unit (normalized) vectors, the result will always be between [code]-1.0[/code] (180 degree angle) when the vectors are facing opposite directions, and [code]1.0[/code] (0 degree angle) when the vectors are aligned.
[b]Note:[/b] [code]a.dot(b)[/code] is equivalent to [code]b.dot(a)[/code].
@@ -184,16 +184,16 @@
Returns the vector with a maximum length by limiting its length to [code]length[/code].
</description>
</method>
- <method name="max_axis" qualifiers="const">
+ <method name="max_axis_index" qualifiers="const">
<return type="int" />
<description>
- Returns the axis of the vector's largest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
+ Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
</description>
</method>
- <method name="min_axis" qualifiers="const">
+ <method name="min_axis_index" qualifiers="const">
<return type="int" />
<description>
- Returns the axis of the vector's smallest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Z].
+ Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Z].
</description>
</method>
<method name="move_toward" qualifiers="const">
@@ -201,7 +201,7 @@
<argument index="0" name="to" type="Vector3" />
<argument index="1" name="delta" type="float" />
<description>
- Moves this vector toward [code]to[/code] by the fixed [code]delta[/code] amount.
+ Moves this vector toward [code]to[/code] by the fixed [code]delta[/code] amount. Will not go past the final value.
</description>
</method>
<method name="normalized" qualifiers="const">
@@ -225,7 +225,7 @@
<return type="Basis" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the outer product with [code]b[/code].
+ Returns the outer product with [code]with[/code].
</description>
</method>
<method name="posmod" qualifiers="const">
@@ -321,13 +321,13 @@
</members>
<constants>
<constant name="AXIS_X" value="0">
- Enumerated value for the X axis. Returned by [method max_axis] and [method min_axis].
+ Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Y" value="1">
- Enumerated value for the Y axis. Returned by [method max_axis] and [method min_axis].
+ Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Z" value="2">
- Enumerated value for the Z axis. Returned by [method max_axis] and [method min_axis].
+ Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector3(0, 0, 0)">
Zero vector, a vector with all components set to [code]0[/code].
@@ -373,16 +373,6 @@
</operator>
<operator name="operator *">
<return type="Vector3" />
- <argument index="0" name="right" type="Vector3" />
- <description>
- Multiplies each component of the [Vector3] by the components of the given [Vector3].
- [codeblock]
- print(Vector3(10, 20, 30) * Vector3(3, 4, 5)) # Prints "(30, 80, 150)"
- [/codeblock]
- </description>
- </operator>
- <operator name="operator *">
- <return type="Vector3" />
<argument index="0" name="right" type="Basis" />
<description>
Inversely transforms (multiplies) the [Vector3] by the given [Basis] matrix.
@@ -404,6 +394,16 @@
</operator>
<operator name="operator *">
<return type="Vector3" />
+ <argument index="0" name="right" type="Vector3" />
+ <description>
+ Multiplies each component of the [Vector3] by the components of the given [Vector3].
+ [codeblock]
+ print(Vector3(10, 20, 30) * Vector3(3, 4, 5)) # Prints "(30, 80, 150)"
+ [/codeblock]
+ </description>
+ </operator>
+ <operator name="operator *">
+ <return type="Vector3" />
<argument index="0" name="right" type="float" />
<description>
Multiplies each component of the [Vector3] by the given [float].
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index 17febdea83..9b952292b6 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -58,16 +58,16 @@
Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component.
</description>
</method>
- <method name="max_axis" qualifiers="const">
+ <method name="max_axis_index" qualifiers="const">
<return type="int" />
<description>
- Returns the axis of the vector's largest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
+ Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X].
</description>
</method>
- <method name="min_axis" qualifiers="const">
+ <method name="min_axis_index" qualifiers="const">
<return type="int" />
<description>
- Returns the axis of the vector's smallest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Z].
+ Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_Z].
</description>
</method>
<method name="sign" qualifiers="const">
@@ -90,13 +90,13 @@
</members>
<constants>
<constant name="AXIS_X" value="0">
- Enumerated value for the X axis.
+ Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Y" value="1">
- Enumerated value for the Y axis.
+ Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="AXIS_Z" value="2">
- Enumerated value for the Z axis.
+ Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index].
</constant>
<constant name="ZERO" value="Vector3i(0, 0, 0)">
Zero vector, a vector with all components set to [code]0[/code].
diff --git a/doc/classes/VehicleBody3D.xml b/doc/classes/VehicleBody3D.xml
index 9315f6e6ad..9960eeedc2 100644
--- a/doc/classes/VehicleBody3D.xml
+++ b/doc/classes/VehicleBody3D.xml
@@ -20,7 +20,7 @@
[b]Note:[/b] The simulation does not take the effect of gears into account, you will need to add logic for this if you wish to simulate gears.
A negative value will result in the vehicle reversing.
</member>
- <member name="mass" type="float" setter="set_mass" getter="get_mass" override="true" default="40.0" />
+ <member name="mass" type="float" setter="set_mass" getter="get_mass" overrides="RigidDynamicBody3D" default="40.0" />
<member name="steering" type="float" setter="set_steering" getter="get_steering" default="0.0">
The steering angle for the vehicle. Setting this to a non-zero value will result in the vehicle turning when it's moving. Wheels that have [member VehicleWheel3D.use_as_steering] set to [code]true[/code] will automatically be rotated.
</member>
diff --git a/doc/classes/VideoStream.xml b/doc/classes/VideoStream.xml
index 39fefa8d95..5978e73ac5 100644
--- a/doc/classes/VideoStream.xml
+++ b/doc/classes/VideoStream.xml
@@ -4,7 +4,7 @@
Base resource for video streams.
</brief_description>
<description>
- Base resource type for all video streams. Classes that derive from [VideoStream] can all be used as resource types to play back videos in [VideoPlayer].
+ Base resource type for all video streams. Classes that derive from [VideoStream] can all be used as resource types to play back videos in [VideoStreamPlayer].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoStreamPlayer.xml
index c8590988f5..3aa9a8a295 100644
--- a/doc/classes/VideoPlayer.xml
+++ b/doc/classes/VideoStreamPlayer.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VideoPlayer" inherits="Control" version="4.0">
+<class name="VideoStreamPlayer" inherits="Control" version="4.0">
<brief_description>
Control for playing video streams.
</brief_description>
<description>
Control node for playing video streams using [VideoStream] resources.
Supported video formats are [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]) and any format exposed via a GDNative plugin using [VideoStreamGDNative].
- [b]Note:[/b] Due to a bug, VideoPlayer does not support localization remapping yet.
+ [b]Note:[/b] Due to a bug, VideoStreamPlayer does not support localization remapping yet.
[b]Warning:[/b] On HTML5, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations.
</description>
<tutorials>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 0418f29808..4a3f99696d 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -25,13 +25,13 @@
<method name="find_world_2d" qualifiers="const">
<return type="World2D" />
<description>
- Returns the 2D world of the viewport.
+ Returns the first valid [World2D] for this viewport, searching the [member world_2d] property of itself and any Viewport ancestor.
</description>
</method>
<method name="find_world_3d" qualifiers="const">
<return type="World3D" />
<description>
- Returns the 3D world of the viewport, or if none the world of the parent viewport.
+ Returns the first valid [World3D] for this viewport, searching the [member world_3d] property of itself and any Viewport ancestor.
</description>
</method>
<method name="get_camera_2d" qualifiers="const">
diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml
index c0cf3b3c7b..de32413fdd 100644
--- a/doc/classes/ViewportTexture.xml
+++ b/doc/classes/ViewportTexture.xml
@@ -14,7 +14,7 @@
<link title="3D Viewport Scaling Demo">https://godotengine.org/asset-library/asset/586</link>
</tutorials>
<members>
- <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" override="true" default="true" />
+ <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="true" />
<member name="viewport_path" type="NodePath" setter="set_viewport_path_in_scene" getter="get_viewport_path_in_scene" default="NodePath(&quot;&quot;)">
The path to the [Viewport] node to display. This is relative to the scene root, not to the node which uses the texture.
</member>
diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml
index d2782efa96..316529a347 100644
--- a/doc/classes/VisualShaderNodeIntFunc.xml
+++ b/doc/classes/VisualShaderNodeIntFunc.xml
@@ -23,7 +23,10 @@
<constant name="FUNC_SIGN" value="2" enum="Function">
Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language.
</constant>
- <constant name="FUNC_MAX" value="3" enum="Function">
+ <constant name="FUNC_BITWISE_NOT" value="3" enum="Function">
+ Returns the result of bitwise [code]NOT[/code] operation on the integer. Translates to [code]~a[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="FUNC_MAX" value="4" enum="Function">
Represents the size of the [enum Function] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeIntOp.xml b/doc/classes/VisualShaderNodeIntOp.xml
index e5fcafca81..c685592fd0 100644
--- a/doc/classes/VisualShaderNodeIntOp.xml
+++ b/doc/classes/VisualShaderNodeIntOp.xml
@@ -35,7 +35,22 @@
<constant name="OP_MIN" value="6" enum="Operator">
Returns the lesser of two numbers. Translates to [code]max(a, b)[/code] in the Godot Shader Language.
</constant>
- <constant name="OP_ENUM_SIZE" value="7" enum="Operator">
+ <constant name="OP_BITWISE_AND" value="7" enum="Operator">
+ Returns the result of bitwise [code]AND[/code] operation on the integer. Translates to [code]a &amp; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_OR" value="8" enum="Operator">
+ Returns the result of bitwise [code]OR[/code] operation for two integers. Translates to [code]a | b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_XOR" value="9" enum="Operator">
+ Returns the result of bitwise [code]XOR[/code] operation for two integers. Translates to [code]a ^ b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_LEFT_SHIFT" value="10" enum="Operator">
+ Returns the result of bitwise left shift operation on the integer. Translates to [code]a &lt;&lt; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_RIGHT_SHIFT" value="11" enum="Operator">
+ Returns the result of bitwise right shift operation on the integer. Translates to [code]a &gt;&gt; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_ENUM_SIZE" value="12" enum="Operator">
Represents the size of the [enum Operator] enum.
</constant>
</constants>
diff --git a/doc/classes/VoxelGIData.xml b/doc/classes/VoxelGIData.xml
index f0bd2a0601..36907c88ba 100644
--- a/doc/classes/VoxelGIData.xml
+++ b/doc/classes/VoxelGIData.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VoxelGIData" inherits="Resource" version="4.0">
<brief_description>
+ Contains baked voxel global illumination data for use in a [VoxelGI] node.
</brief_description>
<description>
+ [VoxelGIData] contains baked voxel global illumination for use in a [VoxelGI] node. [VoxelGIData] also offers several properties to adjust the final appearance of the global illumination. These properties can be adjusted at run-time without having to bake the [VoxelGI] node again.
+ [b]Note:[/b] To prevent text-based scene files ([code].tscn[/code]) from growing too much and becoming slow to load and save, always save [VoxelGIData] to an external binary resource file ([code].res[/code]) instead of embedding it within the scene. This can be done by clicking the dropdown arrow next to the [VoxelGIData] resource, choosing [b]Edit[/b], clicking the floppy disk icon at the top of the inspector then choosing [b]Save As...[/b].
</description>
<tutorials>
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
@@ -23,6 +26,8 @@
<method name="get_bounds" qualifiers="const">
<return type="AABB" />
<description>
+ Returns the bounds of the baked voxel data as an [AABB], which should match [member VoxelGI.extents] after being baked (which only contains the size as a [Vector3]).
+ [b]Note:[/b] If the extents were modified without baking the VoxelGI data, then the value of [method get_bounds] and [member VoxelGI.extents] will not match.
</description>
</method>
<method name="get_data_cells" qualifiers="const">
@@ -53,18 +58,25 @@
</methods>
<members>
<member name="bias" type="float" setter="set_bias" getter="get_bias" default="1.5">
+ The normal bias to use for indirect lighting and reflections. Higher values reduce self-reflections visible in non-rough materials, at the cost of more visible light leaking and flatter-looking indirect lighting. To prioritize hiding self-reflections over lighting quality, set [member bias] to [code]0.0[/code] and [member normal_bias] to a value between [code]1.0[/code] and [code]2.0[/code].
</member>
<member name="dynamic_range" type="float" setter="set_dynamic_range" getter="get_dynamic_range" default="4.0">
+ The dynamic range to use ([code]1.0[/code] represents a low dynamic range scene brightness). Higher values can be used to provide brighter indirect lighting, at the cost of more visible color banding in dark areas (both in indirect lighting and reflections). To avoid color banding, it's recommended to use the lowest value that does not result in visible light clipping.
</member>
<member name="energy" type="float" setter="set_energy" getter="get_energy" default="1.0">
+ The energy of the indirect lighting and reflections produced by the [VoxelGI] node. Higher values result in brighter indirect lighting. If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness.
</member>
<member name="interior" type="bool" setter="set_interior" getter="is_interior" default="false">
+ If [code]true[/code], [Environment] lighting is ignored by the [VoxelGI] node. If [code]false[/code], [Environment] lighting is taken into account by the [VoxelGI] node. [Environment] lighting updates in real-time, which means it can be changed without having to bake the [VoxelGI] node again.
</member>
<member name="normal_bias" type="float" setter="set_normal_bias" getter="get_normal_bias" default="0.0">
+ The normal bias to use for indirect lighting and reflections. Higher values reduce self-reflections visible in non-rough materials, at the cost of more visible light leaking and flatter-looking indirect lighting. See also [member bias]. To prioritize hiding self-reflections over lighting quality, set [member bias] to [code]0.0[/code] and [member normal_bias] to a value between [code]1.0[/code] and [code]2.0[/code].
</member>
<member name="propagation" type="float" setter="set_propagation" getter="get_propagation" default="0.7">
+ If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness.
</member>
<member name="use_two_bounces" type="bool" setter="set_use_two_bounces" getter="is_using_two_bounces" default="false">
+ If [code]true[/code], performs two bounces of indirect lighting instead of one. This makes indirect lighting look more natural and brighter at a small performance cost. The second bounce is also visible in reflections. If the scene appears too bright after enabling [member use_two_bounces], adjust [member propagation] and [member energy].
</member>
</members>
</class>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 3fee1feae8..c7ca6a20be 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -437,34 +437,34 @@
</constant>
</constants>
<theme_items>
- <theme_item name="close" data_type="icon" type="Texture2D">
+ <theme_item name="title_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
</theme_item>
- <theme_item name="close_h_ofs" data_type="constant" type="int" default="18">
+ <theme_item name="title_outline_modulate" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
+ The color of the title outline.
</theme_item>
- <theme_item name="close_pressed" data_type="icon" type="Texture2D">
+ <theme_item name="close_h_ofs" data_type="constant" type="int" default="18">
</theme_item>
<theme_item name="close_v_ofs" data_type="constant" type="int" default="18">
</theme_item>
- <theme_item name="embedded_border" data_type="style" type="StyleBox">
- </theme_item>
<theme_item name="resize_margin" data_type="constant" type="int" default="4">
</theme_item>
<theme_item name="scaleborder_size" data_type="constant" type="int" default="4">
</theme_item>
- <theme_item name="title_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
+ <theme_item name="title_height" data_type="constant" type="int" default="20">
+ </theme_item>
+ <theme_item name="title_outline_size" data_type="constant" type="int" default="0">
+ The size of the title outline.
</theme_item>
<theme_item name="title_font" data_type="font" type="Font">
</theme_item>
<theme_item name="title_font_size" data_type="font_size" type="int">
The size of the title font.
</theme_item>
- <theme_item name="title_height" data_type="constant" type="int" default="20">
+ <theme_item name="close" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="title_outline_modulate" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
- The color of the title outline.
+ <theme_item name="close_pressed" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="title_outline_size" data_type="constant" type="int" default="0">
- The size of the title outline.
+ <theme_item name="embedded_border" data_type="style" type="StyleBox">
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/float.xml b/doc/classes/float.xml
index c96360e6ba..9effe9d5bf 100644
--- a/doc/classes/float.xml
+++ b/doc/classes/float.xml
@@ -62,10 +62,13 @@
</description>
</operator>
<operator name="operator *">
- <return type="float" />
- <argument index="0" name="right" type="float" />
+ <return type="Color" />
+ <argument index="0" name="right" type="Color" />
<description>
- Multiplies two [float]s.
+ Multiplies each component of the [Color] by the given [float].
+ [codeblock]
+ print(1.5 * Color(0.5, 0.5, 0.5)) # Color(0.75, 0.75, 0.75)
+ [/codeblock]
</description>
</operator>
<operator name="operator *">
@@ -113,13 +116,10 @@
</description>
</operator>
<operator name="operator *">
- <return type="Color" />
- <argument index="0" name="right" type="Color" />
+ <return type="float" />
+ <argument index="0" name="right" type="float" />
<description>
- Multiplies each component of the [Color] by the given [float].
- [codeblock]
- print(1.5 * Color(0.5, 0.5, 0.5)) # Color(0.75, 0.75, 0.75)
- [/codeblock]
+ Multiplies two [float]s.
</description>
</operator>
<operator name="operator *">
diff --git a/doc/classes/int.xml b/doc/classes/int.xml
index bb36d83741..d212fe42bf 100644
--- a/doc/classes/int.xml
+++ b/doc/classes/int.xml
@@ -132,20 +132,6 @@
</description>
</operator>
<operator name="operator *">
- <return type="int" />
- <argument index="0" name="right" type="int" />
- <description>
- Multiplies two [int]s.
- </description>
- </operator>
- <operator name="operator *">
- <return type="float" />
- <argument index="0" name="right" type="float" />
- <description>
- Multiplies an [int] and a [float]. The result is a [float].
- </description>
- </operator>
- <operator name="operator *">
<return type="Vector2" />
<argument index="0" name="right" type="Vector2" />
<description>
@@ -176,6 +162,20 @@
Multiplies each component of the [Vector3i] by the given [int].
</description>
</operator>
+ <operator name="operator *">
+ <return type="float" />
+ <argument index="0" name="right" type="float" />
+ <description>
+ Multiplies an [int] and a [float]. The result is a [float].
+ </description>
+ </operator>
+ <operator name="operator *">
+ <return type="int" />
+ <argument index="0" name="right" type="int" />
+ <description>
+ Multiplies two [int]s.
+ </description>
+ </operator>
<operator name="operator +">
<return type="float" />
<argument index="0" name="right" type="float" />
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index b5e5cf8fa7..1523194a85 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -40,15 +40,15 @@ class TypeName:
class PropertyDef:
def __init__(
- self, name, type_name, setter, getter, text, default_value, overridden
- ): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str], Optional[bool]) -> None
+ self, name, type_name, setter, getter, text, default_value, overrides
+ ): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str], Optional[str]) -> None
self.name = name
self.type_name = type_name
self.setter = setter
self.getter = getter
self.text = text
self.default_value = default_value
- self.overridden = overridden
+ self.overrides = overrides
class ParameterDef:
@@ -162,10 +162,10 @@ class State:
default_value = property.get("default") or None
if default_value is not None:
default_value = "``{}``".format(default_value)
- overridden = property.get("override") or False
+ overrides = property.get("overrides") or None
property_def = PropertyDef(
- property_name, type_name, setter, getter, property.text, default_value, overridden
+ property_name, type_name, setter, getter, property.text, default_value, overrides
)
class_def.properties[property_name] = property_def
@@ -520,8 +520,9 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
for property_def in class_def.properties.values():
type_rst = property_def.type_name.to_rst(state)
default = property_def.default_value
- if default is not None and property_def.overridden:
- ml.append((type_rst, property_def.name, default + " *(parent override)*"))
+ if default is not None and property_def.overrides:
+ ref = ":ref:`{1}<class_{1}_property_{0}>`".format(property_def.name, property_def.overrides)
+ ml.append((type_rst, property_def.name, default + " (overrides " + ref + ")"))
else:
ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name)
ml.append((type_rst, ref, default))
@@ -624,12 +625,12 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write("\n\n")
# Property descriptions
- if any(not p.overridden for p in class_def.properties.values()) > 0:
+ if any(not p.overrides for p in class_def.properties.values()) > 0:
f.write(make_heading("Property Descriptions", "-"))
index = 0
for property_def in class_def.properties.values():
- if property_def.overridden:
+ if property_def.overrides:
continue
if index != 0:
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 4759a2b0d0..f19b4a0ce2 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1555,7 +1555,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->uniforms.clear();
- if (p_shader->code == String()) {
+ if (p_shader->code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index f9443e11db..c76d80b0a1 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -758,6 +758,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += a + " - " + n + " * (" + a + " / " + n + "))";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
+
default: {
if (p_use_scope) {
code += "(";
@@ -857,7 +861,13 @@ ShaderLanguage::DataType ShaderCompilerGLES3::_get_variable_type(const StringNam
Error ShaderCompilerGLES3::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
ShaderLanguage::VaryingFunctionNames var_names;
- Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), var_names, ShaderTypes::get_singleton()->get_types(), _get_variable_type);
+ ShaderLanguage::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_variable_type;
+
+ Error err = parser.compile(p_code, info);
// Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
if (err != OK) {
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 7d93d50ceb..2f26acf628 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -791,10 +791,10 @@ void ShaderGLES3::use_material(void *p_material) {
Transform2D tr = V->get();
GLfloat matrix[4] = {
/* build a 16x16 matrix */
- tr.elements[0][0],
- tr.elements[0][1],
- tr.elements[1][0],
- tr.elements[1][1],
+ (GLfloat)tr.elements[0][0],
+ (GLfloat)tr.elements[0][1],
+ (GLfloat)tr.elements[1][0],
+ (GLfloat)tr.elements[1][1],
};
glUniformMatrix2fv(location, 1, GL_FALSE, matrix);
@@ -804,15 +804,15 @@ void ShaderGLES3::use_material(void *p_material) {
Basis val = V->get();
GLfloat mat[9] = {
- val.elements[0][0],
- val.elements[1][0],
- val.elements[2][0],
- val.elements[0][1],
- val.elements[1][1],
- val.elements[2][1],
- val.elements[0][2],
- val.elements[1][2],
- val.elements[2][2],
+ (GLfloat)val.elements[0][0],
+ (GLfloat)val.elements[1][0],
+ (GLfloat)val.elements[2][0],
+ (GLfloat)val.elements[0][1],
+ (GLfloat)val.elements[1][1],
+ (GLfloat)val.elements[2][1],
+ (GLfloat)val.elements[0][2],
+ (GLfloat)val.elements[1][2],
+ (GLfloat)val.elements[2][2],
};
glUniformMatrix3fv(location, 1, GL_FALSE, mat);
@@ -822,22 +822,22 @@ void ShaderGLES3::use_material(void *p_material) {
case ShaderLanguage::TYPE_MAT4: {
Transform2D tr = V->get();
GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.elements[0][0],
- tr.elements[0][1],
- 0,
- 0,
- tr.elements[1][0],
- tr.elements[1][1],
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- tr.elements[2][0],
- tr.elements[2][1],
- 0,
- 1
+ (GLfloat)tr.elements[0][0],
+ (GLfloat)tr.elements[0][1],
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)tr.elements[1][0],
+ (GLfloat)tr.elements[1][1],
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)1,
+ (GLfloat)0,
+ (GLfloat)tr.elements[2][0],
+ (GLfloat)tr.elements[2][1],
+ (GLfloat)0,
+ (GLfloat)1
};
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 1754b47c85..be993b88e5 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -342,7 +342,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
}
String base = _get_root_path();
- if (base != String() && !try_dir.begins_with(base)) {
+ if (!base.is_empty() && !try_dir.begins_with(base)) {
ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG);
String new_dir;
new_dir.parse_utf8(real_current_dir_name);
@@ -360,7 +360,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
String DirAccessUnix::get_current_dir(bool p_include_drive) {
String base = _get_root_path();
- if (base != "") {
+ if (!base.is_empty()) {
String bd = current_dir.replace_first(base, "");
if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index f07c654bd6..75d115df9c 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -160,7 +160,7 @@ void FileAccessUnix::close() {
close_notification_func(path, flags);
}
- if (save_path != "") {
+ if (!save_path.is_empty()) {
int rename_error = rename((save_path + ".tmp").utf8().get_data(), save_path.utf8().get_data());
if (rename_error && close_fail_notify) {
@@ -307,7 +307,8 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
if (!err) {
return flags.st_mtime;
} else {
- ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + p_file + ".");
+ print_verbose("Failed to get modified time for: " + p_file + "");
+ return 0;
};
}
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 1ebc8cca5e..f0c679b54e 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -460,11 +460,11 @@ int OS_Unix::get_processor_count() const {
String OS_Unix::get_user_data_dir() const {
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
- if (appname != "") {
+ if (!appname.is_empty()) {
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
if (use_custom_dir) {
String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
- if (custom_dir == "") {
+ if (custom_dir.is_empty()) {
custom_dir = appname;
}
return get_data_path().plus_file(custom_dir);
@@ -486,7 +486,7 @@ String OS_Unix::get_executable_path() const {
if (len > 0) {
b.parse_utf8(buf, len);
}
- if (b == "") {
+ if (b.is_empty()) {
WARN_PRINT("Couldn't get executable path from /proc/self/exe, using argv[0]");
return OS::get_executable_path();
}
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index cbc870d385..67ee6ac856 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -102,7 +102,7 @@ public:
class UnixTerminalLogger : public StdLogger {
public:
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR);
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override;
virtual ~UnixTerminalLogger();
};
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 952ee50074..928ea73409 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -2520,7 +2520,7 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co
image_memory_barrier.subresourceRange.baseArrayLayer = p_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
if (texture->used_in_frame != frames_drawn) {
@@ -4249,7 +4249,7 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) {
}
for (int j = 0; j < shader->sets[i].uniform_info.size(); j++) {
const UniformInfo &ui = shader->sets[i].uniform_info[j];
- if (ret != String()) {
+ if (!ret.is_empty()) {
ret += "\n";
}
ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + shader_uniform_names[ui.type] + " Length: " + itos(ui.length);
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 3e98e36d14..aa8d7977f7 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -133,7 +133,7 @@ Error DirAccessWindows::change_dir(String p_dir) {
bool worked = (SetCurrentDirectoryW((LPCWSTR)(p_dir.utf16().get_data())) != 0);
String base = _get_root_path();
- if (base != "") {
+ if (!base.is_empty()) {
GetCurrentDirectoryW(2048, real_current_dir_name);
String new_dir = String::utf16((const char16_t *)real_current_dir_name).replace("\\", "/");
if (!new_dir.begins_with(base)) {
@@ -184,7 +184,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
String DirAccessWindows::get_current_dir(bool p_include_drive) {
String base = _get_root_path();
- if (base != "") {
+ if (!base.is_empty()) {
String bd = current_dir.replace("\\", "/").replace_first(base, "");
if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
@@ -196,7 +196,7 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) {
if (p_include_drive) {
return current_dir;
} else {
- if (_get_root_string() == "") {
+ if (_get_root_string().is_empty()) {
int p = current_dir.find(":");
if (p != -1) {
return current_dir.substr(p + 1);
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 035c44a28c..2c7b5b9be9 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -99,7 +99,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
HANDLE f = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d);
if (f != INVALID_HANDLE_VALUE) {
String fname = String::utf16((const char16_t *)(d.cFileName));
- if (fname != String()) {
+ if (!fname.is_empty()) {
String base_file = path.get_file();
if (base_file != fname && base_file.findn(fname) == 0) {
WARN_PRINT("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
@@ -142,7 +142,7 @@ void FileAccessWindows::close() {
fclose(f);
f = nullptr;
- if (save_path != "") {
+ if (!save_path.is_empty()) {
bool rename_error = true;
int attempts = 4;
while (rename_error && attempts) {
@@ -335,7 +335,8 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
if (rv == 0) {
return st.st_mtime;
} else {
- ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + file + ".");
+ print_verbose("Failed to get modified time for: " + p_file + "");
+ return 0;
}
}
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index dc0c62fbc9..a8d3bfcc90 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -612,7 +612,7 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
add_child(main_vbox);
tab_container = memnew(TabContainer);
- tab_container->set_tab_align(TabContainer::TabAlign::ALIGN_LEFT);
+ tab_container->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tab_container->set_use_hidden_tabs_for_min_size(true);
tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected));
@@ -622,7 +622,7 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
VBoxContainer *vb = memnew(VBoxContainer);
vb->set_name(TTR("Listen for Input"));
event_as_text = memnew(Label);
- event_as_text->set_align(Label::ALIGN_CENTER);
+ event_as_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
vb->add_child(event_as_text);
// Mouse button detection rect (Mouse button event outside this ColorRect will be ignored)
mouse_detection_rect = memnew(ColorRect);
@@ -761,7 +761,7 @@ void ActionMapEditor::_add_action_pressed() {
}
void ActionMapEditor::_add_action(const String &p_name) {
- if (p_name == "" || !_is_action_name_valid(p_name)) {
+ if (p_name.is_empty() || !_is_action_name_valid(p_name)) {
show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
return;
}
@@ -785,7 +785,7 @@ void ActionMapEditor::_action_edited() {
return;
}
- if (new_name == "" || !_is_action_name_valid(new_name)) {
+ if (new_name.is_empty() || !_is_action_name_valid(new_name)) {
ti->set_text(0, old_name);
show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
return;
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index f7f88ad0d5..9682fb07d2 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -381,7 +381,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
draw_line(Point2(limit, i), Point2(right_limit, i), lc, Math::round(EDSCALE));
Color c = color;
c.a *= 0.5;
- draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::snapped((iv + 1) * scale, step))), HALIGN_LEFT, -1, font_size, c);
+ draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::snapped((iv + 1) * scale, step))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, c);
}
first = false;
@@ -452,8 +452,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
ep.point_rect.size = bezier_icon->get_size();
if (selection.has(i)) {
draw_texture(selected_icon, ep.point_rect.position);
- draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.001))), HALIGN_LEFT, -1, font_size, accent);
- draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::snapped(value, 0.001))), HALIGN_LEFT, -1, font_size, accent);
+ draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
+ draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::snapped(value, 0.001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
} else {
draw_texture(bezier_icon, ep.point_rect.position);
}
@@ -663,7 +663,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
menu_insert_key = mb->get_position();
if (menu_insert_key.x >= timeline->get_name_limit() && menu_insert_key.x <= get_size().width - timeline->get_buttons_width()) {
- Vector2 popup_pos = get_global_transform().xform(mb->get_position());
+ Vector2 popup_pos = get_screen_position() + mb->get_position();
menu->clear();
menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 6fce55f8e3..e7251662b7 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -39,6 +39,7 @@
#include "editor_scale.h"
#include "scene/animation/animation_player.h"
#include "scene/main/window.h"
+#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
class AnimationTrackKeyEdit : public Object {
@@ -649,7 +650,7 @@ public:
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &E : anims) {
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
@@ -658,7 +659,7 @@ public:
}
}
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
animations += "[stop]";
@@ -1331,7 +1332,7 @@ public:
List<StringName> anims;
ap->get_animation_list(&anims);
for (List<StringName>::Element *G = anims.front(); G; G = G->next()) {
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
@@ -1340,7 +1341,7 @@ public:
}
}
- if (animations != String()) {
+ if (!animations.is_empty()) {
animations += ",";
}
animations += "[stop]";
@@ -1621,7 +1622,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
if (frame != prev_frame && i >= prev_frame_ofs) {
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
- draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
+ draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
prev_frame_ofs = i + font->get_string_size(itos(frame), font_size).x + 5 * EDSCALE;
}
}
@@ -1639,7 +1640,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
if ((sc / step) != (prev_sc / step) || (prev_sc < 0 && sc >= 0)) {
int scd = sc < 0 ? prev_sc : sc;
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
- draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HALIGN_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
+ draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
}
}
}
@@ -2028,7 +2029,7 @@ void AnimationTrackEdit::_notification(int p_what) {
Vector2 string_pos = Point2(ofs, (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size));
string_pos = string_pos.floor();
- draw_string(font, string_pos, text, HALIGN_LEFT, limit - ofs - hsep, font_size, text_color);
+ draw_string(font, string_pos, text, HORIZONTAL_ALIGNMENT_LEFT, limit - ofs - hsep, font_size, text_color);
draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE));
}
@@ -2339,7 +2340,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
int limit = MAX(0, p_clip_right - p_x - icon_to_draw->get_width());
if (limit > 0) {
- draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), text, HALIGN_LEFT, limit, font_size, color);
+ draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), text, HORIZONTAL_ALIGNMENT_LEFT, limit, font_size, color);
}
}
@@ -2664,7 +2665,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
if (stream.is_valid()) {
if (stream->get_path().is_resource_file()) {
stream_name = stream->get_path().get_file();
- } else if (stream->get_name() != "") {
+ } else if (!stream->get_name().is_empty()) {
stream_name = stream->get_name();
} else {
stream_name = stream->get_class();
@@ -2872,13 +2873,18 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
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);
+
+ 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_separator();
menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Key(s)"), MENU_KEY_DELETE);
}
menu->set_as_minsize();
- Vector2 popup_pos = get_screen_transform().xform(get_local_mouse_position());
- menu->set_position(popup_pos);
+ menu->set_position(get_screen_position() + get_local_mouse_position());
menu->popup();
insert_at_pos = offset + timeline->get_value();
@@ -3061,6 +3067,9 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
} break;
case MENU_KEY_DUPLICATE: {
emit_signal(SNAME("duplicate_request"));
+ } break;
+ case MENU_KEY_ADD_RESET: {
+ emit_signal(SNAME("create_reset_request"));
} break;
case MENU_KEY_DELETE: {
@@ -3123,6 +3132,7 @@ void AnimationTrackEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("move_selection_cancel"));
ADD_SIGNAL(MethodInfo("duplicate_request"));
+ ADD_SIGNAL(MethodInfo("create_reset_request"));
ADD_SIGNAL(MethodInfo("duplicate_transpose_request"));
ADD_SIGNAL(MethodInfo("delete_request"));
}
@@ -3224,7 +3234,7 @@ void AnimationTrackEditGroup::_notification(int p_what) {
int ofs = 0;
draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2));
ofs += separation + icon->get_width();
- draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HALIGN_LEFT, timeline->get_name_limit() - ofs, font_size, color);
+ draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HORIZONTAL_ALIGNMENT_LEFT, timeline->get_name_limit() - ofs, font_size, color);
int px = (-timeline->get_value() + timeline->get_play_position()) * timeline->get_zoom_scale() + timeline->get_name_limit();
@@ -3240,7 +3250,7 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co
node_name = p_name;
node = p_node;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Size2 AnimationTrackEditGroup::get_minimum_size() const {
@@ -3505,7 +3515,7 @@ void AnimationTrackEditor::make_insert_queue() {
void AnimationTrackEditor::commit_insert_queue() {
bool reset_allowed = true;
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
- if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
+ if (player->has_animation(SceneStringNames::get_singleton()->RESET) && player->get_animation(SceneStringNames::get_singleton()->RESET) == animation) {
// Avoid messing with the reset animation itself.
reset_allowed = false;
} else {
@@ -3647,7 +3657,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
// Let's build a node path.
String path = root->get_path_to(p_node);
- if (p_sub != "") {
+ if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3687,7 +3697,7 @@ bool AnimationTrackEditor::has_track(Node3D *p_node, const String &p_sub, const
// Let's build a node path.
String path = root->get_path_to(p_node);
- if (p_sub != "") {
+ if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3752,7 +3762,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
for (int i = 1; i < history->get_path_size(); i++) {
String prop = history->get_path_property(i);
- ERR_FAIL_COND(prop == "");
+ ERR_FAIL_COND(prop.is_empty());
path += ":" + prop;
}
@@ -3852,7 +3862,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
for (int i = 1; i < history->get_path_size(); i++) {
String prop = history->get_path_property(i);
- ERR_FAIL_COND(prop == "");
+ ERR_FAIL_COND(prop.is_empty());
path += ":" + prop;
}
@@ -3925,15 +3935,15 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
- if (player->has_animation("RESET")) {
- return player->get_animation("RESET");
+ if (player->has_animation(SceneStringNames::get_singleton()->RESET)) {
+ return player->get_animation(SceneStringNames::get_singleton()->RESET);
} else {
Ref<Animation> reset_anim;
reset_anim.instantiate();
reset_anim->set_length(ANIM_MIN_LENGTH);
- undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
+ undo_redo->add_do_method(player, "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim);
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
- undo_redo->add_undo_method(player, "remove_animation", "RESET");
+ undo_redo->add_undo_method(player, "remove_animation", SceneStringNames::get_singleton()->RESET);
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
return reset_anim;
}
@@ -4388,6 +4398,7 @@ void AnimationTrackEditor::_update_tracks() {
track_edit->connect("duplicate_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED);
track_edit->connect("duplicate_transpose_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED);
+ track_edit->connect("create_reset_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_ADD_RESET_KEY), CONNECT_DEFERRED);
track_edit->connect("delete_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_DELETE_SELECTION), CONNECT_DEFERRED);
}
}
@@ -5720,6 +5731,55 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
_anim_duplicate_keys(true);
} break;
+ case EDIT_ADD_RESET_KEY: {
+ undo_redo->create_action(TTR("Anim Add RESET Keys"));
+ Ref<Animation> reset = _create_and_get_reset_animation();
+ int reset_tracks = reset->get_track_count();
+ Set<int> tracks_added;
+
+ for (const KeyValue<SelectedKey, KeyInfo> &E : selection) {
+ const SelectedKey &sk = E.key;
+
+ // Only add one key per track.
+ if (tracks_added.has(sk.track)) {
+ continue;
+ }
+ tracks_added.insert(sk.track);
+
+ int dst_track = -1;
+
+ const NodePath &path = animation->track_get_path(sk.track);
+ for (int i = 0; i < reset->get_track_count(); i++) {
+ if (reset->track_get_path(i) == path) {
+ dst_track = i;
+ break;
+ }
+ }
+
+ int existing_idx = -1;
+ if (dst_track == -1) {
+ // If adding multiple tracks, make sure that correct track is referenced.
+ dst_track = reset_tracks;
+ reset_tracks++;
+
+ undo_redo->add_do_method(reset.ptr(), "add_track", animation->track_get_type(sk.track));
+ undo_redo->add_do_method(reset.ptr(), "track_set_path", dst_track, path);
+ undo_redo->add_undo_method(reset.ptr(), "remove_track", dst_track);
+ } else {
+ existing_idx = reset->track_find_key(dst_track, 0, true);
+ }
+
+ undo_redo->add_do_method(reset.ptr(), "track_insert_key", dst_track, 0, animation->track_get_key_value(sk.track, sk.key), animation->track_get_key_transition(sk.track, sk.key));
+ undo_redo->add_undo_method(reset.ptr(), "track_remove_key_at_time", dst_track, 0);
+
+ if (existing_idx != -1) {
+ undo_redo->add_undo_method(reset.ptr(), "track_insert_key", dst_track, 0, reset->track_get_key_value(dst_track, existing_idx), reset->track_get_key_transition(dst_track, existing_idx));
+ }
+ }
+
+ undo_redo->commit_action();
+
+ } break;
case EDIT_DELETE_SELECTION: {
if (bezier_edit->is_visible()) {
bezier_edit->delete_selection();
@@ -5961,7 +6021,7 @@ void AnimationTrackEditor::_pick_track_select_recursive(TreeItem *p_item, const
NodePath np = p_item->get_metadata(0);
Node *node = get_node(np);
- if (p_filter != String() && ((String)node->get_name()).findn(p_filter) != -1) {
+ if (!p_filter.is_empty() && ((String)node->get_name()).findn(p_filter) != -1) {
p_select_candidates.push_back(node);
}
@@ -6012,8 +6072,8 @@ AnimationTrackEditor::AnimationTrackEditor() {
info_message = memnew(Label);
info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations."));
- info_message->set_valign(Label::VALIGN_CENTER);
- info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
@@ -6057,8 +6117,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
track_vbox = memnew(VBoxContainer);
scroll->add_child(track_vbox);
track_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
- scroll->set_enable_h_scroll(false);
- scroll->set_enable_v_scroll(true);
+ scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
track_vbox->add_theme_constant_override("separation", 0);
HBoxContainer *bottom_hb = memnew(HBoxContainer);
@@ -6144,6 +6203,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_SELECTION);
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_TRANSPOSED);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/add_reset_value", TTR("Add RESET Value(s)")));
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/delete_selection", TTR("Delete Selection"), Key::KEY_DELETE), EDIT_DELETE_SELECTION);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 2bdc1d4107..5ebfd26322 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -140,6 +140,7 @@ class AnimationTrackEdit : public Control {
MENU_LOOP_CLAMP,
MENU_KEY_INSERT,
MENU_KEY_DUPLICATE,
+ MENU_KEY_ADD_RESET,
MENU_KEY_DELETE
};
AnimationTimelineEdit *timeline;
@@ -500,6 +501,7 @@ public:
EDIT_SCALE_CONFIRM,
EDIT_DUPLICATE_SELECTION,
EDIT_DUPLICATE_TRANSPOSED,
+ EDIT_ADD_RESET_KEY,
EDIT_DELETE_SELECTION,
EDIT_GOTO_NEXT_STEP,
EDIT_GOTO_PREV_STEP,
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index dd3e08b299..3c117f28a8 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -699,7 +699,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
int limit = to_x - from_x - 4;
if (limit > 0) {
- draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HALIGN_LEFT, -1, font_size, color);
+ draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color);
}
if (p_selected) {
@@ -1272,7 +1272,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
int limit = to_x - from_x - 4;
if (limit > 0) {
- draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HALIGN_LEFT, -1, font_size, color);
+ draw_string(font, Point2(from_x + 2, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), anim, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color);
}
if (p_selected) {
diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h
index 9cf47fd51a..8b83235b35 100644
--- a/editor/audio_stream_preview.h
+++ b/editor/audio_stream_preview.h
@@ -66,14 +66,13 @@ class AudioStreamPreviewGenerator : public Node {
Thread *thread = nullptr;
// Needed for the bookkeeping of the Map
- Preview &operator=(const Preview &p_rhs) {
+ void operator=(const Preview &p_rhs) {
preview = p_rhs.preview;
base_stream = p_rhs.base_stream;
playback = p_rhs.playback;
generating.set_to(generating.is_set());
id = p_rhs.id;
thread = p_rhs.thread;
- return *this;
}
Preview(const Preview &p_rhs) {
preview = p_rhs.preview;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index bfcd2dd4ca..c024c909a3 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -624,7 +624,7 @@ FindReplaceBar::FindReplaceBar() {
vbc_lineedit = memnew(VBoxContainer);
add_child(vbc_lineedit);
- vbc_lineedit->set_alignment(ALIGN_CENTER);
+ vbc_lineedit->set_alignment(BoxContainer::ALIGNMENT_CENTER);
vbc_lineedit->set_h_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *vbc_button = memnew(VBoxContainer);
add_child(vbc_button);
@@ -633,10 +633,10 @@ FindReplaceBar::FindReplaceBar() {
HBoxContainer *hbc_button_search = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_search);
- hbc_button_search->set_alignment(ALIGN_END);
+ hbc_button_search->set_alignment(BoxContainer::ALIGNMENT_END);
hbc_button_replace = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_replace);
- hbc_button_replace->set_alignment(ALIGN_END);
+ hbc_button_replace->set_alignment(BoxContainer::ALIGNMENT_END);
HBoxContainer *hbc_option_search = memnew(HBoxContainer);
vbc_option->add_child(hbc_option_search);
@@ -1314,10 +1314,10 @@ void CodeTextEditor::delete_lines() {
int count = Math::abs(to_line - from_line) + 1;
text_editor->set_caret_line(from_line, false);
+ text_editor->deselect();
for (int i = 0; i < count; i++) {
_delete_line(from_line);
}
- text_editor->deselect();
} else {
_delete_line(text_editor->get_caret_line());
}
@@ -1534,7 +1534,7 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
void CodeTextEditor::set_error(const String &p_error) {
error->set_text(p_error);
- if (p_error != "") {
+ if (!p_error.is_empty()) {
error->set_default_cursor_shape(CURSOR_POINTING_HAND);
} else {
error->set_default_cursor_shape(CURSOR_ARROW);
@@ -1547,7 +1547,7 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) {
}
void CodeTextEditor::goto_error() {
- if (error->get_text() != "") {
+ if (!error->get_text().is_empty()) {
text_editor->unfold_line(error_line);
text_editor->set_caret_line(error_line);
text_editor->set_caret_column(error_column);
@@ -1854,7 +1854,7 @@ CodeTextEditor::CodeTextEditor() {
ScrollContainer *scroll = memnew(ScrollContainer);
scroll->set_h_size_flags(SIZE_EXPAND_FILL);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- scroll->set_enable_v_scroll(false);
+ scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
status_bar->add_child(scroll);
error = memnew(Label);
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index d00fdd0ce7..4945414237 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -111,7 +111,7 @@ public:
void ConnectDialog::ok_pressed() {
String method_name = dst_method->get_text();
- if (method_name == "") {
+ if (method_name.is_empty()) {
error->set_text(TTR("Method in target node must be specified."));
error->popup_centered();
return;
@@ -234,7 +234,7 @@ void ConnectDialog::_add_bind() {
*/
void ConnectDialog::_remove_bind() {
String st = bind_editor->get_selected_path();
- if (st == "") {
+ if (st.is_empty()) {
return;
}
int idx = st.get_slice("/", 1).to_int() - 1;
@@ -838,13 +838,15 @@ void ConnectionsDock::_rmb_pressed(Vector2 position) {
return;
}
- Vector2 global_position = tree->get_global_position() + position;
+ Vector2 screen_position = tree->get_screen_position() + position;
if (_is_item_signal(*item)) {
- signal_menu->set_position(global_position);
+ signal_menu->set_position(screen_position);
+ signal_menu->reset_size();
signal_menu->popup();
} else {
- slot_menu->set_position(global_position);
+ slot_menu->set_position(screen_position);
+ slot_menu->reset_size();
slot_menu->popup();
}
}
@@ -967,7 +969,7 @@ void ConnectionsDock::update_tree() {
} else if (pi.type != Variant::NIL) {
tname = Variant::get_type_name(pi.type);
}
- signaldesc += (pi.name == "" ? String("arg " + itos(i)) : pi.name) + ": " + tname;
+ signaldesc += (pi.name.is_empty() ? String("arg " + itos(i)) : pi.name) + ": " + tname;
argnames.push_back(pi.name + ":" + tname);
}
}
@@ -999,7 +1001,7 @@ void ConnectionsDock::update_tree() {
if (!found) {
DocTools *dd = EditorHelp::get_doc_data();
Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(base);
- while (F && descr == String()) {
+ while (F && descr.is_empty()) {
for (int i = 0; i < F->get().signals.size(); i++) {
if (F->get().signals[i].name == signal_name.operator String()) {
descr = DTR(F->get().signals[i].description);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index dec4f50f03..6bf14df8a1 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -173,7 +173,7 @@ void CreateDialog::_update_search() {
_configure_search_option_item(root, base_type, ClassDB::class_exists(base_type));
const String search_text = search_box->get_text();
- bool empty_search = search_text == "";
+ bool empty_search = search_text.is_empty();
// Filter all candidate results.
Vector<String> candidates;
@@ -244,7 +244,7 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
}
- if (search_box->get_text() != "") {
+ if (!search_box->get_text().is_empty()) {
r_item->set_collapsed(false);
} else {
// Don't collapse the root node or an abstract node on the first tree level.
@@ -322,7 +322,7 @@ void CreateDialog::_cleanup() {
void CreateDialog::_confirmed() {
String selected_item = get_selected_type();
- if (selected_item == String()) {
+ if (selected_item.is_empty()) {
return;
}
@@ -339,8 +339,10 @@ void CreateDialog::_confirmed() {
memdelete(f);
}
- emit_signal(SNAME("create"));
+ // To prevent, emitting an error from the transient window (shader dialog for example) hide this dialog before emitting the "create" signal.
hide();
+
+ emit_signal(SNAME("create"));
_cleanup();
}
@@ -640,7 +642,7 @@ void CreateDialog::_load_favorites_and_history() {
while (!f->eof_reached()) {
String l = f->get_line().strip_edges();
- if (l != String()) {
+ if (!l.is_empty()) {
favorite_list.push_back(l);
}
}
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
index 2e0e6cb7c8..36fbf8adf1 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
@@ -192,10 +192,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::VECTOR2I: {
int id = variable_id++;
Vector2 vec = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y;
x.name = "x";
y.name = "y";
- x.type = y.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
x.value = rtos(vec.x);
y.value = rtos(vec.y);
@@ -209,12 +211,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::RECT2I: {
int id = variable_id++;
Rect2 rect = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y, w, h;
x.name = "x";
y.name = "y";
w.name = "w";
h.name = "h";
- x.type = y.type = w.type = h.type = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
+ w.type = type_scalar;
+ h.type = type_scalar;
x.value = rtos(rect.position.x);
y.value = rtos(rect.position.y);
w.value = rtos(rect.size.x);
@@ -232,11 +238,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::VECTOR3I: {
int id = variable_id++;
Vector3 vec = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y, z;
x.name = "x";
y.name = "y";
z.name = "z";
- x.type = y.type = z.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
+ z.type = type_scalar;
x.value = rtos(vec.x);
y.value = rtos(vec.y);
z.value = rtos(vec.z);
@@ -251,11 +260,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::TRANSFORM2D: {
int id = variable_id++;
Transform2D transform = p_var;
+ const String type_vec2 = Variant::get_type_name(Variant::VECTOR2);
DAP::Variable x, y, origin;
x.name = "x";
y.name = "y";
origin.name = "origin";
- x.type = y.type = origin.type = Variant::get_type_name(Variant::VECTOR2);
+ x.type = type_vec2;
+ y.type = type_vec2;
+ origin.type = type_vec2;
x.value = transform.elements[0];
y.value = transform.elements[1];
origin.value = transform.elements[2];
@@ -291,12 +303,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::QUATERNION: {
int id = variable_id++;
Quaternion quat = p_var;
+ const String type_float = Variant::get_type_name(Variant::FLOAT);
DAP::Variable x, y, z, w;
x.name = "x";
y.name = "y";
z.name = "z";
w.name = "w";
- x.type = y.type = z.type = w.type = Variant::get_type_name(Variant::FLOAT);
+ x.type = type_float;
+ y.type = type_float;
+ z.type = type_float;
+ w.type = type_float;
x.value = rtos(quat.x);
y.value = rtos(quat.y);
z.value = rtos(quat.z);
@@ -313,10 +329,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::AABB: {
int id = variable_id++;
AABB aabb = p_var;
+ const String type_vec3 = Variant::get_type_name(Variant::VECTOR3);
DAP::Variable position, size;
position.name = "position";
size.name = "size";
- position.type = size.type = Variant::get_type_name(Variant::VECTOR3);
+ position.type = type_vec3;
+ size.type = type_vec3;
position.value = aabb.position;
size.value = aabb.size;
position.variablesReference = parse_variant(aabb.position);
@@ -331,11 +349,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::BASIS: {
int id = variable_id++;
Basis basis = p_var;
+ const String type_vec2 = Variant::get_type_name(Variant::VECTOR2);
DAP::Variable x, y, z;
x.name = "x";
y.name = "y";
z.name = "z";
- x.type = y.type = z.type = Variant::get_type_name(Variant::VECTOR2);
+ x.type = type_vec2;
+ y.type = type_vec2;
+ z.type = type_vec2;
x.value = basis.elements[0];
y.value = basis.elements[1];
z.value = basis.elements[2];
@@ -372,12 +393,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::COLOR: {
int id = variable_id++;
Color color = p_var;
+ const String type_float = Variant::get_type_name(Variant::FLOAT);
DAP::Variable r, g, b, a;
r.name = "r";
g.name = "g";
b.name = "b";
a.name = "a";
- r.type = g.type = b.type = a.type = Variant::get_type_name(Variant::FLOAT);
+ r.type = type_float;
+ g.type = type_float;
+ b.type = type_float;
+ a.type = type_float;
r.value = rtos(color.r);
g.value = rtos(color.g);
b.value = rtos(color.b);
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index e53f66e72e..9346b8f1af 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -55,9 +55,14 @@ bool EditorDebuggerRemoteObject::_get(const StringName &p_name, Variant &r_ret)
}
void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->clear(); //sorry, no want category
- for (const PropertyInfo &E : prop_list) {
- p_list->push_back(E);
+ p_list->clear(); // Sorry, no want category.
+ for (const PropertyInfo &prop : prop_list) {
+ if (prop.name == "script") {
+ // Skip the script property, it's always added by the non-virtual method.
+ continue;
+ }
+
+ p_list->push_back(prop);
}
}
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 391839d639..8ea028a7de 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -59,7 +59,7 @@ EditorDebuggerNode::EditorDebuggerNode() {
add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT));
tabs = memnew(TabContainer);
- tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabs->set_tabs_visible(false);
tabs->connect("tab_changed", callable_mp(this, &EditorDebuggerNode::_debugger_changed));
add_child(tabs);
@@ -183,6 +183,11 @@ ScriptEditorDebugger *EditorDebuggerNode::get_default_debugger() const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(0));
}
+String EditorDebuggerNode::get_server_uri() const {
+ ERR_FAIL_COND_V(server.is_null(), "");
+ return server->get_uri();
+}
+
Error EditorDebuggerNode::start(const String &p_uri) {
stop();
ERR_FAIL_COND_V(p_uri.find("://") < 0, ERR_INVALID_PARAMETER);
diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h
index 4d9e846834..135122db68 100644
--- a/editor/debugger/editor_debugger_node.h
+++ b/editor/debugger/editor_debugger_node.h
@@ -188,8 +188,9 @@ public:
void set_camera_override(CameraOverride p_override);
CameraOverride get_camera_override();
- Error start(const String &p_uri = "tcp://");
+ String get_server_uri() const;
+ Error start(const String &p_uri = "tcp://");
void stop();
void add_debugger_plugin(const Ref<Script> &p_script);
diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp
index 8c3833af50..34904d55aa 100644
--- a/editor/debugger/editor_debugger_server.cpp
+++ b/editor/debugger/editor_debugger_server.cpp
@@ -41,15 +41,18 @@
class EditorDebuggerServerTCP : public EditorDebuggerServer {
private:
Ref<TCPServer> server;
+ String endpoint;
public:
static EditorDebuggerServer *create(const String &p_protocol);
- virtual void poll() {}
- virtual Error start(const String &p_uri);
- virtual void stop();
- virtual bool is_active() const;
- virtual bool is_connection_available() const;
- virtual Ref<RemoteDebuggerPeer> take_connection();
+
+ virtual void poll() override {}
+ virtual String get_uri() const override;
+ virtual Error start(const String &p_uri) override;
+ virtual void stop() override;
+ virtual bool is_active() const override;
+ virtual bool is_connection_available() const override;
+ virtual Ref<RemoteDebuggerPeer> take_connection() override;
EditorDebuggerServerTCP();
};
@@ -63,21 +66,42 @@ EditorDebuggerServerTCP::EditorDebuggerServerTCP() {
server.instantiate();
}
+String EditorDebuggerServerTCP::get_uri() const {
+ return endpoint;
+}
+
Error EditorDebuggerServerTCP::start(const String &p_uri) {
- int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
+ // Default host and port
String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host");
+ int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
+
+ // Optionally override
if (!p_uri.is_empty() && p_uri != "tcp://") {
String scheme, path;
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
}
- const Error err = server->listen(bind_port, bind_host);
- if (err != OK) {
- EditorNode::get_log()->add_message(String("Error listening on port ") + itos(bind_port), EditorLog::MSG_TYPE_ERROR);
- return err;
+
+ // Try listening on ports
+ const int max_attempts = 5;
+ for (int attempt = 1;; ++attempt) {
+ const Error err = server->listen(bind_port, bind_host);
+ if (err == OK) {
+ break;
+ }
+ if (attempt >= max_attempts) {
+ EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR);
+ return err;
+ }
+ int last_port = bind_port++;
+ EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING);
}
- return err;
+
+ // Endpoint that the client should connect to
+ endpoint = vformat("tcp://%s:%d", bind_host, bind_port);
+
+ return OK;
}
void EditorDebuggerServerTCP::stop() {
diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h
index 844d1a9e5a..6a4ca895d1 100644
--- a/editor/debugger/editor_debugger_server.h
+++ b/editor/debugger/editor_debugger_server.h
@@ -47,8 +47,10 @@ public:
static void register_protocol_handler(const String &p_protocol, CreateServerFunc p_func);
static EditorDebuggerServer *create(const String &p_protocol);
+
+ virtual String get_uri() const = 0;
virtual void poll() = 0;
- virtual Error start(const String &p_uri = "") = 0;
+ virtual Error start(const String &p_uri) = 0;
virtual void stop() = 0;
virtual bool is_active() const = 0;
virtual bool is_connection_available() const = 0;
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index 1feab98948..be369aa0ca 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -107,7 +107,7 @@ void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position) {
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->set_position(get_screen_transform().xform(get_local_mouse_position()));
+ item_menu->set_position(get_screen_position() + get_local_mouse_position());
item_menu->popup();
}
diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp
index d4385630be..8b1f0085d5 100644
--- a/editor/debugger/editor_network_profiler.cpp
+++ b/editor/debugger/editor_network_profiler.cpp
@@ -60,7 +60,7 @@ void EditorNetworkProfiler::_update_frame() {
TreeItem *node = counters_display->create_item(root);
for (int j = 0; j < counters_display->get_columns(); ++j) {
- node->set_text_align(j, j > 0 ? TreeItem::ALIGN_RIGHT : TreeItem::ALIGN_LEFT);
+ node->set_text_alignment(j, j > 0 ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT);
}
node->set_text(0, E.value.node_path);
@@ -149,7 +149,7 @@ EditorNetworkProfiler::EditorNetworkProfiler() {
incoming_bandwidth_text = memnew(LineEdit);
incoming_bandwidth_text->set_editable(false);
incoming_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE);
- incoming_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ incoming_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
hb->add_child(incoming_bandwidth_text);
Control *down_up_spacer = memnew(Control);
@@ -163,7 +163,7 @@ EditorNetworkProfiler::EditorNetworkProfiler() {
outgoing_bandwidth_text = memnew(LineEdit);
outgoing_bandwidth_text->set_editable(false);
outgoing_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE);
- outgoing_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ outgoing_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
hb->add_child(outgoing_bandwidth_text);
// Set initial texts in the incoming/outgoing bandwidth labels
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index 952f46e9a5..6106f1755d 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -132,14 +132,14 @@ void EditorPerformanceProfiler::_monitor_draw() {
rect.size -= graph_style_box->get_minimum_size();
Color draw_color = get_theme_color(SNAME("accent_color"), SNAME("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), HALIGN_LEFT, rect.size.x, font_size, draw_color);
+ 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);
draw_color.a = 0.9f;
float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), font_size).width;
if (value_position < 0) {
value_position = 0;
}
- monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent(font_size)), current.item->get_text(1), HALIGN_LEFT, rect.size.x, font_size, draw_color);
+ monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent(font_size)), current.item->get_text(1), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color);
rect.position.y += graph_font->get_height(font_size);
rect.size.height -= graph_font->get_height(font_size);
@@ -152,12 +152,12 @@ void EditorPerformanceProfiler::_monitor_draw() {
Color horizontal_line_color;
horizontal_line_color.set_hsv(draw_color.get_h(), draw_color.get_s() * 0.5f, draw_color.get_v() * 0.5f, 0.3f);
monitor_draw->draw_line(rect.position, rect.position + Vector2(rect.size.width, 0), horizontal_line_color, Math::round(EDSCALE));
- monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent(font_size)), _create_label(current.max, current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color);
+ monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent(font_size)), _create_label(current.max, current.type), HORIZONTAL_ALIGNMENT_LEFT, rect.size.width, font_size, horizontal_line_color);
for (int j = 0; j < line_count; j++) {
Vector2 y_offset = Vector2(0, rect.size.height * (1.0f - float(j) / float(line_count)));
monitor_draw->draw_line(rect.position + y_offset, rect.position + Vector2(rect.size.width, 0) + y_offset, horizontal_line_color, Math::round(EDSCALE));
- monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent(font_size)) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color);
+ monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent(font_size)) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), HORIZONTAL_ALIGNMENT_LEFT, rect.size.width, font_size, horizontal_line_color);
}
}
@@ -191,7 +191,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
if (text_top_left_position.y < 0) {
text_top_left_position.y = h2 + MARKER_MARGIN;
}
- monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent(font_size)), label, HALIGN_LEFT, rect.size.x, font_size, line_color);
+ monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent(font_size)), label, HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, line_color);
}
prev = h2;
e = e->next();
@@ -378,8 +378,8 @@ EditorPerformanceProfiler::EditorPerformanceProfiler() {
info_message = memnew(Label);
info_message->set_text(TTR("Pick one or more items from the list to display the graph."));
- info_message->set_valign(Label::VALIGN_CENTER);
- info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index d08ae1de8a..2bdacb51b8 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -355,7 +355,7 @@ void EditorProfiler::_update_frame() {
item->set_metadata(0, it.signature);
item->set_metadata(1, it.script);
item->set_metadata(2, it.line);
- item->set_text_align(2, TreeItem::ALIGN_RIGHT);
+ item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_RIGHT);
item->set_tooltip(0, it.name + "\n" + it.script + ":" + itos(it.line));
float time = dtime == DISPLAY_SELF_TIME ? it.self : it.total;
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index 4739458f8e..a4e4ed4020 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -462,7 +462,7 @@ void EditorVisualProfiler::_graph_tex_draw() {
graph->draw_line(Vector2(0, frame_y), Vector2(half_width, frame_y), Color(1, 1, 1, 0.3));
String limit_str = String::num(graph_limit, 2);
- graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6));
+ graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.6));
}
if (graph_height_gpu > 0) {
@@ -473,11 +473,11 @@ void EditorVisualProfiler::_graph_tex_draw() {
graph->draw_line(Vector2(half_width, frame_y), Vector2(graph->get_size().x, frame_y), Color(1, 1, 1, 0.3));
String limit_str = String::num(graph_limit, 2);
- graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6));
+ graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.6));
}
- graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8));
- graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8));
+ graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.8));
+ graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.8));
/*
if (hover_metric != -1 && frame_metrics[hover_metric].valid) {
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index b18c225f23..4f7dc78017 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -79,7 +79,7 @@ void ScriptEditorDebugger::_put_msg(String p_message, Array p_data) {
void ScriptEditorDebugger::debug_copy() {
String msg = reason->get_text();
- if (msg == "") {
+ if (msg.is_empty()) {
return;
}
DisplayServer::get_singleton()->clipboard_set(msg);
@@ -312,7 +312,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
if (is_move_to_foreground()) {
DisplayServer::get_singleton()->window_move_to_foreground();
}
- if (error != "") {
+ if (!error.is_empty()) {
tabs->set_current_tab(0);
}
profiler->set_enabled(false);
@@ -499,7 +499,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
error->set_icon(0, get_theme_icon(oe.warning ? "Warning" : "Error", "EditorIcons"));
error->set_text(0, time);
- error->set_text_align(0, TreeItem::ALIGN_LEFT);
+ error->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
const Color color = get_theme_color(oe.warning ? SNAME("warning_color") : SNAME("error_color"), SNAME("Editor"));
error->set_custom_color(0, color);
@@ -524,7 +524,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
TreeItem *cpp_cond = error_tree->create_item(error);
cpp_cond->set_text(0, "<" + TTR("C++ Error") + ">");
cpp_cond->set_text(1, oe.error);
- cpp_cond->set_text_align(0, TreeItem::ALIGN_LEFT);
+ cpp_cond->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
tooltip += TTR("C++ Error:") + " " + oe.error + "\n";
if (source_is_project_file) {
cpp_cond->set_metadata(0, source_meta);
@@ -542,7 +542,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
TreeItem *cpp_source = error_tree->create_item(error);
cpp_source->set_text(0, "<" + (source_is_project_file ? TTR("Source") : TTR("C++ Source")) + ">");
cpp_source->set_text(1, source_txt);
- cpp_source->set_text_align(0, TreeItem::ALIGN_LEFT);
+ cpp_source->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
tooltip += (source_is_project_file ? TTR("Source:") : TTR("C++ Source:")) + " " + source_txt + "\n";
// Set metadata to highlight error line in scripts.
@@ -565,7 +565,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
if (i == 0) {
stack_trace->set_text(0, "<" + TTR("Stack Trace") + ">");
- stack_trace->set_text_align(0, TreeItem::ALIGN_LEFT);
+ stack_trace->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
error->set_metadata(0, meta);
tooltip += TTR("Stack Trace:") + "\n";
}
@@ -1083,7 +1083,7 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
Resource *res = Object::cast_to<Resource>(p_base);
- if (res && res->get_path() != String()) {
+ if (res && !res->get_path().is_empty()) {
String respath = res->get_path();
int pathid = _get_res_path_cache(respath);
@@ -1113,7 +1113,7 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
if (p_value.is_ref()) {
Ref<Resource> res = p_value;
- if (res.is_valid() && res->get_path() != String()) {
+ if (res.is_valid() && !res->get_path().is_empty()) {
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1133,13 +1133,13 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
Resource *res = Object::cast_to<Resource>(p_base);
- if (res && res->get_path() != String()) {
+ if (res && !res->get_path().is_empty()) {
String respath = res->get_path();
int pathid = _get_res_path_cache(respath);
if (p_value.is_ref()) {
Ref<Resource> res2 = p_value;
- if (res2.is_valid() && res2->get_path() != String()) {
+ if (res2.is_valid() && !res2->get_path().is_empty()) {
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1428,7 +1428,7 @@ void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) {
}
if (item_menu->get_item_count() > 0) {
- item_menu->set_position(error_tree->get_global_position() + p_pos);
+ item_menu->set_position(error_tree->get_screen_position() + p_pos);
item_menu->popup();
}
}
@@ -1574,7 +1574,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
editor = p_editor;
tabs = memnew(TabContainer);
- tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabs->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles")));
tabs->connect("tab_changed", callable_mp(this, &ScriptEditorDebugger::_tab_changed));
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index f18284638f..1cc8cc01ce 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -75,7 +75,7 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String
String path = efsd->get_file_path(i);
for (KeyValue<String, String> &E : candidates[file]) {
- if (E.value == String()) {
+ if (E.value.is_empty()) {
E.value = path;
continue;
}
@@ -135,7 +135,7 @@ void DependencyEditor::_fix_all() {
for (KeyValue<String, Map<String, String>> &E : candidates) {
for (const KeyValue<String, String> &F : E.value) {
- if (F.value != String()) {
+ if (!F.value.is_empty()) {
remaps[F.key] = F.value;
}
}
@@ -275,7 +275,8 @@ void DependencyEditorOwners::_list_rmb_select(int p_item, const Vector2 &p_pos)
file_options->add_item(TTR("Open"), FILE_OPEN);
}
- file_options->set_position(owners->get_global_position() + p_pos);
+ file_options->set_position(owners->get_screen_position() + p_pos);
+ file_options->reset_size();
file_options->popup();
}
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 5ce57e936a..8191b343f7 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -252,17 +252,17 @@ void DocTools::remove_from(const DocTools &p_data) {
}
void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) {
- ERR_FAIL_COND(p_class_doc.name == "");
+ ERR_FAIL_COND(p_class_doc.name.is_empty());
class_list[p_class_doc.name] = p_class_doc;
}
void DocTools::remove_doc(const String &p_class_name) {
- ERR_FAIL_COND(p_class_name == "" || !class_list.has(p_class_name));
+ ERR_FAIL_COND(p_class_name.is_empty() || !class_list.has(p_class_name));
class_list.erase(p_class_name);
}
bool DocTools::has_doc(const String &p_class_name) {
- if (p_class_name == "") {
+ if (p_class_name.is_empty()) {
return false;
}
return class_list.has(p_class_name);
@@ -341,11 +341,17 @@ void DocTools::generate(bool p_basic_types) {
}
DocData::PropertyDoc prop;
-
prop.name = E.name;
-
prop.overridden = inherited;
+ if (inherited) {
+ String parent = ClassDB::get_parent_class(c.name);
+ while (!ClassDB::has_property(parent, prop.name, true)) {
+ parent = ClassDB::get_parent_class(parent);
+ }
+ prop.overrides = parent;
+ }
+
bool default_value_valid = false;
Variant default_value;
@@ -431,7 +437,7 @@ void DocTools::generate(bool p_basic_types) {
method_list.sort();
for (const MethodInfo &E : method_list) {
- if (E.name == "" || (E.name[0] == '_' && !(E.flags & METHOD_FLAG_VIRTUAL))) {
+ if (E.name.is_empty() || (E.name[0] == '_' && !(E.flags & METHOD_FLAG_VIRTUAL))) {
continue; //hidden, don't count
}
@@ -453,21 +459,21 @@ void DocTools::generate(bool p_basic_types) {
}
if (E.flags & METHOD_FLAG_CONST) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "const";
}
if (E.flags & METHOD_FLAG_VARARG) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "vararg";
}
if (E.flags & METHOD_FLAG_STATIC) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "static";
@@ -603,6 +609,8 @@ void DocTools::generate(bool p_basic_types) {
tid.data_type = "style";
c.theme_properties.push_back(tid);
}
+
+ c.theme_properties.sort();
}
classes.pop_front();
@@ -728,21 +736,21 @@ void DocTools::generate(bool p_basic_types) {
DocData::return_doc_from_retinfo(method, mi.return_val);
if (mi.flags & METHOD_FLAG_VARARG) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "vararg";
}
if (mi.flags & METHOD_FLAG_CONST) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "const";
}
if (mi.flags & METHOD_FLAG_STATIC) {
- if (method.qualifiers != "") {
+ if (!method.qualifiers.is_empty()) {
method.qualifiers += " ";
}
method.qualifiers += "static";
@@ -877,7 +885,7 @@ void DocTools::generate(bool p_basic_types) {
md.name = mi.name;
if (mi.flags & METHOD_FLAG_VARARG) {
- if (md.qualifiers != "") {
+ if (!md.qualifiers.is_empty()) {
md.qualifiers += " ";
}
md.qualifiers += "vararg";
@@ -997,7 +1005,7 @@ Error DocTools::load_classes(const String &p_dir) {
da->list_dir_begin();
String path;
path = da->get_next();
- while (path != String()) {
+ while (!path.is_empty()) {
if (!da->current_is_dir() && path.ends_with("xml")) {
Ref<XMLParser> parser = memnew(XMLParser);
Error err2 = parser->open(p_dir.plus_file(path));
@@ -1027,7 +1035,7 @@ Error DocTools::erase_classes(const String &p_dir) {
da->list_dir_begin();
String path;
path = da->get_next();
- while (path != String()) {
+ while (!path.is_empty()) {
if (!da->current_is_dir() && path.ends_with("xml")) {
to_erase.push_back(path);
}
@@ -1228,7 +1236,7 @@ Error DocTools::_load(Ref<XMLParser> parser) {
}
static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) {
- if (p_string == "") {
+ if (p_string.is_empty()) {
return;
}
String tab;
@@ -1246,15 +1254,15 @@ static void _write_method_doc(FileAccess *f, const String &p_name, Vector<DocDat
const DocData::MethodDoc &m = p_method_docs[i];
String qualifiers;
- if (m.qualifiers != "") {
+ if (!m.qualifiers.is_empty()) {
qualifiers += " qualifiers=\"" + m.qualifiers.xml_escape() + "\"";
}
_write_string(f, 2, "<" + p_name + " name=\"" + m.name.xml_escape() + "\"" + qualifiers + ">");
- if (m.return_type != "") {
+ if (!m.return_type.is_empty()) {
String enum_text;
- if (m.return_enum != String()) {
+ if (!m.return_enum.is_empty()) {
enum_text = " enum=\"" + m.return_enum + "\"";
}
_write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + " />");
@@ -1269,11 +1277,11 @@ static void _write_method_doc(FileAccess *f, const String &p_name, Vector<DocDat
const DocData::ArgumentDoc &a = m.arguments[j];
String enum_text;
- if (a.enumeration != String()) {
+ if (!a.enumeration.is_empty()) {
enum_text = " enum=\"" + a.enumeration + "\"";
}
- if (a.default_value != "") {
+ if (!a.default_value.is_empty()) {
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + " default=\"" + a.default_value.xml_escape(true) + "\" />");
} else {
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + " />");
@@ -1311,7 +1319,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
String header = "<class name=\"" + c.name + "\"";
- if (c.inherits != "") {
+ if (!c.inherits.is_empty()) {
header += " inherits=\"" + c.inherits + "\"";
}
header += String(" version=\"") + VERSION_BRANCH + "\"";
@@ -1345,17 +1353,17 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
for (int i = 0; i < c.properties.size(); i++) {
String additional_attributes;
- if (c.properties[i].enumeration != String()) {
+ if (!c.properties[i].enumeration.is_empty()) {
additional_attributes += " enum=\"" + c.properties[i].enumeration + "\"";
}
- if (c.properties[i].default_value != String()) {
+ if (!c.properties[i].default_value.is_empty()) {
additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\"";
}
const DocData::PropertyDoc &p = c.properties[i];
if (c.properties[i].overridden) {
- _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + " />");
+ _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" overrides=\"" + p.overrides + "\"" + additional_attributes + " />");
} else {
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + additional_attributes + ">");
_write_string(f, 3, p.description.strip_edges().xml_escape());
@@ -1372,13 +1380,13 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
for (int i = 0; i < c.constants.size(); i++) {
const DocData::ConstantDoc &k = c.constants[i];
if (k.is_value_valid) {
- if (k.enumeration != String()) {
+ if (!k.enumeration.is_empty()) {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
} else {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">");
}
} else {
- if (k.enumeration != String()) {
+ if (!k.enumeration.is_empty()) {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"platform-dependent\" enum=\"" + k.enumeration + "\">");
} else {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"platform-dependent\">");
@@ -1398,7 +1406,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
for (int i = 0; i < c.theme_properties.size(); i++) {
const DocData::ThemeItemDoc &ti = c.theme_properties[i];
- if (ti.default_value != "") {
+ if (!ti.default_value.is_empty()) {
_write_string(f, 2, "<theme_item name=\"" + ti.name + "\" data_type=\"" + ti.data_type + "\" type=\"" + ti.type + "\" default=\"" + ti.default_value.xml_escape(true) + "\">");
} else {
_write_string(f, 2, "<theme_item name=\"" + ti.name + "\" data_type=\"" + ti.data_type + "\" type=\"" + ti.type + "\">");
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 414264e697..2de92f5184 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -125,7 +125,7 @@ EditorAbout::EditorAbout() {
vbc->connect("theme_changed", callable_mp(this, &EditorAbout::_theme_changed));
HBoxContainer *hbc = memnew(HBoxContainer);
hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- hbc->set_alignment(BoxContainer::ALIGN_CENTER);
+ hbc->set_alignment(BoxContainer::ALIGNMENT_CENTER);
hbc->add_theme_constant_override("separation", 30 * EDSCALE);
add_child(vbc);
vbc->add_child(hbc);
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 8dd3045887..6c64c53837 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -88,7 +88,7 @@ void EditorAssetInstaller::_item_edited() {
String path = item->get_metadata(0);
updating = true;
- if (path == String() || item == tree->get_root()) { //a dir or root
+ if (path.is_empty() || item == tree->get_root()) { //a dir or root
_update_subitems(item, item->is_checked(0), true);
}
@@ -212,7 +212,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
depth--;
}
- if (skip || path == String()) {
+ if (skip || path.is_empty()) {
continue;
}
@@ -307,7 +307,7 @@ void EditorAssetInstaller::ok_pressed() {
if (status_map.has(name) && status_map[name]->is_checked(0)) {
String path = status_map[name]->get_metadata(0);
- if (path == String()) { // a dir
+ if (path.is_empty()) { // a dir
String dirpath;
TreeItem *t = status_map[name];
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index dd9f10a23b..81a1f26818 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -487,7 +487,8 @@ void EditorAudioBus::_effect_edited() {
if (effect->get_metadata(0) == Variant()) {
Rect2 area = effects->get_item_rect(effect);
- effect_options->set_position(effects->get_global_position() + area.position + Vector2(0, area.size.y));
+ effect_options->set_position(effects->get_screen_position() + area.position + Vector2(0, area.size.y));
+ effect_options->reset_size();
effect_options->popup();
//add effect
} else {
@@ -535,8 +536,8 @@ void EditorAudioBus::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
- Vector2 pos = mb->get_position();
- bus_popup->set_position(get_global_position() + pos);
+ bus_popup->set_position(get_screen_position() + mb->get_position());
+ bus_popup->reset_size();
bus_popup->popup();
}
}
@@ -737,7 +738,8 @@ void EditorAudioBus::_effect_rmb(const Vector2 &p_pos) {
return;
}
- delete_effect_popup->set_position(get_global_mouse_position());
+ delete_effect_popup->set_position(get_screen_position() + get_local_mouse_position());
+ delete_effect_popup->reset_size();
delete_effect_popup->popup();
}
@@ -1296,8 +1298,7 @@ EditorAudioBuses::EditorAudioBuses() {
bus_scroll = memnew(ScrollContainer);
bus_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- bus_scroll->set_enable_h_scroll(true);
- bus_scroll->set_enable_v_scroll(false);
+ bus_scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
add_child(bus_scroll);
bus_hb = memnew(HBoxContainer);
bus_hb->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1421,7 +1422,7 @@ void EditorAudioMeterNotches::_draw_audio_notches() {
Vector2((line_length + label_space) * EDSCALE,
(1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + (font_height / 4) + top_padding),
String::num(Math::abs(n.db_value)) + "dB",
- HALIGN_LEFT, -1, font_size,
+ HORIZONTAL_ALIGNMENT_LEFT, -1, font_size,
notch_color);
}
}
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index e1aaa060c6..eb54bb3efb 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -230,11 +230,10 @@ private:
render_db_value = n.render_db_value;
}
- _FORCE_INLINE_ AudioNotch &operator=(const EditorAudioMeterNotches::AudioNotch &n) {
+ _FORCE_INLINE_ void operator=(const EditorAudioMeterNotches::AudioNotch &n) {
relative_position = n.relative_position;
db_value = n.db_value;
render_db_value = n.render_db_value;
- return *this;
}
_FORCE_INLINE_ AudioNotch() {}
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 25e76c2262..418d7d58ef 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -340,22 +340,22 @@ void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
}
void EditorAutoloadSettings::_autoload_text_submitted(const String p_name) {
- if (autoload_add_path->get_text() != "" && _autoload_name_is_valid(p_name, nullptr)) {
+ if (!autoload_add_path->get_text().is_empty() && _autoload_name_is_valid(p_name, nullptr)) {
_autoload_add();
}
}
void EditorAutoloadSettings::_autoload_path_text_changed(const String p_path) {
add_autoload->set_disabled(
- p_path == "" || !_autoload_name_is_valid(autoload_add_name->get_text(), nullptr));
+ p_path.is_empty() || !_autoload_name_is_valid(autoload_add_name->get_text(), nullptr));
}
void EditorAutoloadSettings::_autoload_text_changed(const String p_name) {
String error_string;
bool is_name_valid = _autoload_name_is_valid(p_name, &error_string);
- add_autoload->set_disabled(autoload_add_path->get_text() == "" || !is_name_valid);
+ add_autoload->set_disabled(autoload_add_path->get_text().is_empty() || !is_name_valid);
error_message->set_text(error_string);
- error_message->set_visible(autoload_add_name->get_text() != "" && !is_name_valid);
+ error_message->set_visible(!autoload_add_name->get_text().is_empty() && !is_name_valid);
}
Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
@@ -838,7 +838,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
error_message = memnew(Label);
error_message->hide();
- error_message->set_align(Label::Align::ALIGN_RIGHT);
+ 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")));
add_child(error_message);
diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp
index 52e55de84c..6bc23c352a 100644
--- a/editor/editor_command_palette.cpp
+++ b/editor/editor_command_palette.cpp
@@ -128,7 +128,7 @@ void EditorCommandPalette::_update_command_search(const String &search_text) {
String shortcut_text = entries[i].shortcut_text == "None" ? "" : entries[i].shortcut_text;
ti->set_text(0, entries[i].display_name);
ti->set_metadata(0, entries[i].key_name);
- ti->set_text_align(1, TreeItem::TextAlign::ALIGN_RIGHT);
+ ti->set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT);
ti->set_text(1, shortcut_text);
Color c = Color(1, 1, 1, 0.5);
ti->set_custom_color(1, c);
@@ -164,7 +164,7 @@ void EditorCommandPalette::_sbox_input(const Ref<InputEvent> &p_ie) {
void EditorCommandPalette::_confirmed() {
TreeItem *selected_option = search_options->get_selected();
String command_key = selected_option != nullptr ? selected_option->get_metadata(0) : "";
- if (command_key != "") {
+ if (!command_key.is_empty()) {
hide();
execute_command(command_key);
}
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index a163b468e6..390a2998d6 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -100,7 +100,7 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
history.resize(current + 1); //clip history to next
}
- if (p_property != "" && has_prev) {
+ if (!p_property.is_empty() && has_prev) {
//add a sub property
History &pr = history.write[current];
h = pr;
@@ -566,7 +566,7 @@ void EditorData::remove_scene(int p_idx) {
current_edited_scene--;
}
- if (edited_scene[p_idx].path != String()) {
+ if (!edited_scene[p_idx].path.is_empty()) {
ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(edited_scene[p_idx].path);
}
@@ -583,7 +583,7 @@ bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String>
if (p_node == p_root) {
ss = p_node->get_scene_inherited_state();
- } else if (p_node->get_scene_file_path() != String()) {
+ } else if (!p_node->get_scene_file_path().is_empty()) {
ss = p_node->get_scene_instance_state();
}
@@ -647,7 +647,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
memdelete(edited_scene[p_idx].root);
edited_scene.write[p_idx].root = new_scene;
- if (new_scene->get_scene_file_path() != "") {
+ if (!new_scene->get_scene_file_path().is_empty()) {
edited_scene.write[p_idx].path = new_scene->get_scene_file_path();
}
edited_scene.write[p_idx].selection = new_selection;
@@ -682,14 +682,14 @@ void EditorData::set_edited_scene_root(Node *p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
edited_scene.write[current_edited_scene].root = p_root;
if (p_root) {
- if (p_root->get_scene_file_path() != "") {
+ if (!p_root->get_scene_file_path().is_empty()) {
edited_scene.write[current_edited_scene].path = p_root->get_scene_file_path();
} else {
p_root->set_scene_file_path(edited_scene[current_edited_scene].path);
}
}
- if (edited_scene[current_edited_scene].path != "") {
+ if (!edited_scene[current_edited_scene].path.is_empty()) {
edited_scene.write[current_edited_scene].file_modified_time = FileAccess::get_modified_time(edited_scene[current_edited_scene].path);
}
}
@@ -764,7 +764,7 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
Ref<Script> s = edited_scene[p_idx].root->get_script();
if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) {
Node *n = edited_scene[p_idx].root->get_child(0);
- while (!s.is_valid() && n && n->get_scene_file_path() == String()) {
+ while (!s.is_valid() && n && n->get_scene_file_path().is_empty()) {
s = n->get_script();
n = n->get_parent();
}
@@ -777,7 +777,7 @@ String EditorData::get_scene_title(int p_idx, bool p_always_strip_extension) con
if (!edited_scene[p_idx].root) {
return TTR("[empty]");
}
- if (edited_scene[p_idx].root->get_scene_file_path() == "") {
+ if (edited_scene[p_idx].root->get_scene_file_path().is_empty()) {
return TTR("[unsaved]");
}
@@ -818,7 +818,7 @@ String EditorData::get_scene_path(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
if (edited_scene[p_idx].root) {
- if (edited_scene[p_idx].root->get_scene_file_path() == "") {
+ if (edited_scene[p_idx].root->get_scene_file_path().is_empty()) {
edited_scene[p_idx].root->set_scene_file_path(edited_scene[p_idx].path);
} else {
return edited_scene[p_idx].root->get_scene_file_path();
@@ -893,8 +893,13 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
if (!ScriptServer::is_global_class(p_class)) {
return false;
}
- String base = script_class_get_base(p_class);
+
Ref<Script> script = script_class_load_script(p_class);
+ if (script.is_null()) {
+ return false;
+ }
+
+ String base = script_class_get_base(p_class);
Ref<Script> base_script = script->get_base_script();
while (p_inherits != base) {
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index f91dedf25d..61b655098f 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -49,7 +49,7 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p
if (!p_item->get_parent()) {
p_item->set_text(0, "res://");
} else {
- if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) {
+ if (!opened_paths.has(path) && (p_select_path.is_empty() || !p_select_path.begins_with(path))) {
p_item->set_collapsed(true);
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 03d91ebcba..95affb09b6 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -264,7 +264,7 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password");
r_flags.push_back("--remote-fs");
r_flags.push_back(host + ":" + itos(port));
- if (passwd != "") {
+ if (!passwd.is_empty()) {
r_flags.push_back("--remote-fs-password");
r_flags.push_back(passwd);
}
@@ -488,8 +488,8 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
String cur_dir_no_prefix = cur_dir.replace("res://", "");
Vector<String> dirs;
- String f;
- while ((f = da->get_next()) != "") {
+ String f = da->get_next();
+ while (!f.is_empty()) {
if (da->current_is_dir()) {
dirs.push_back(f);
} else {
@@ -506,6 +506,7 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
}
}
}
+ f = da->get_next();
}
da->list_dir_end();
@@ -527,7 +528,7 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
}
void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &p_filter, bool exclude) {
- if (p_filter == "") {
+ if (p_filter.is_empty()) {
return;
}
Vector<String> split = p_filter.split(",");
@@ -682,12 +683,12 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
result.features_pv.push_back(E);
}
- if (p_preset->get_custom_features() != String()) {
+ if (!p_preset->get_custom_features().is_empty()) {
Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
for (int i = 0; i < tmp_custom_list.size(); i++) {
String f = tmp_custom_list[i].strip_edges();
- if (f != String()) {
+ if (!f.is_empty()) {
result.features.insert(f);
result.features_pv.push_back(f);
}
@@ -993,12 +994,12 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> custom_list;
- if (p_preset->get_custom_features() != String()) {
+ if (!p_preset->get_custom_features().is_empty()) {
Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
for (int i = 0; i < tmp_custom_list.size(); i++) {
String f = tmp_custom_list[i].strip_edges();
- if (f != String()) {
+ if (!f.is_empty()) {
custom_list.push_back(f);
}
}
@@ -1032,14 +1033,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
// Store icon and splash images directly, they need to bypass the import system and be loaded as images
String icon = ProjectSettings::get_singleton()->get("application/config/icon");
String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
- if (icon != String() && FileAccess::exists(icon)) {
+ if (!icon.is_empty() && FileAccess::exists(icon)) {
Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
err = p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key);
if (err != OK) {
return err;
}
}
- if (splash != String() && FileAccess::exists(splash) && icon != splash) {
+ if (!splash.is_empty() && FileAccess::exists(splash) && icon != splash) {
Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
err = p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key);
if (err != OK) {
@@ -1358,7 +1359,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password");
r_flags.push_back("--remote-fs");
r_flags.push_back(host + ":" + itos(port));
- if (passwd != "") {
+ if (!passwd.is_empty()) {
r_flags.push_back("--remote-fs-password");
r_flags.push_back(passwd);
}
@@ -1854,7 +1855,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
template_path = template_path.strip_edges();
- if (template_path == String()) {
+ if (template_path.is_empty()) {
if (p_preset->get("binary_format/64_bits")) {
if (p_debug) {
template_path = find_export_template(debug_file_64);
@@ -1870,7 +1871,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
}
}
- if (template_path != String() && !FileAccess::exists(template_path)) {
+ if (!template_path.is_empty() && !FileAccess::exists(template_path)) {
EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index 2222a5e5d3..2ca91043e1 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -310,7 +310,7 @@ EditorFeatureProfile::EditorFeatureProfile() {}
void EditorFeatureProfileManager::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
current_profile = EDITOR_GET("_default_feature_profile");
- if (current_profile != String()) {
+ if (!current_profile.is_empty()) {
current.instantiate();
Error err = current->load_from_file(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(current_profile + ".profile"));
if (err != OK) {
@@ -334,7 +334,7 @@ String EditorFeatureProfileManager::_get_selected_profile() {
void EditorFeatureProfileManager::_update_profile_list(const String &p_select_profile) {
String selected_profile;
- if (p_select_profile == String()) { //default, keep
+ if (p_select_profile.is_empty()) { //default, keep
if (profile_list->get_selected() >= 0) {
selected_profile = profile_list->get_item_metadata(profile_list->get_selected());
if (!FileAccess::exists(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(selected_profile + ".profile"))) {
@@ -352,7 +352,7 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr
d->list_dir_begin();
while (true) {
String f = d->get_next();
- if (f == String()) {
+ if (f.is_empty()) {
break;
}
@@ -371,7 +371,7 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr
for (int i = 0; i < profiles.size(); i++) {
String name = profiles[i];
- if (i == 0 && selected_profile == String()) {
+ if (i == 0 && selected_profile.is_empty()) {
selected_profile = name;
}
@@ -386,15 +386,15 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr
}
}
- class_list_vbc->set_visible(selected_profile != String());
- property_list_vbc->set_visible(selected_profile != String());
- no_profile_selected_help->set_visible(selected_profile == String());
- profile_actions[PROFILE_CLEAR]->set_disabled(current_profile == String());
- profile_actions[PROFILE_ERASE]->set_disabled(selected_profile == String());
- profile_actions[PROFILE_EXPORT]->set_disabled(selected_profile == String());
- profile_actions[PROFILE_SET]->set_disabled(selected_profile == String());
+ class_list_vbc->set_visible(!selected_profile.is_empty());
+ property_list_vbc->set_visible(!selected_profile.is_empty());
+ no_profile_selected_help->set_visible(selected_profile.is_empty());
+ profile_actions[PROFILE_CLEAR]->set_disabled(current_profile.is_empty());
+ profile_actions[PROFILE_ERASE]->set_disabled(selected_profile.is_empty());
+ profile_actions[PROFILE_EXPORT]->set_disabled(selected_profile.is_empty());
+ profile_actions[PROFILE_SET]->set_disabled(selected_profile.is_empty());
- current_profile_name->set_text(current_profile != String() ? current_profile : TTR("(none)"));
+ current_profile_name->set_text(!current_profile.is_empty() ? current_profile : TTR("(none)"));
_update_selected_profile();
}
@@ -412,7 +412,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
} break;
case PROFILE_SET: {
String selected = _get_selected_profile();
- ERR_FAIL_COND(selected == String());
+ ERR_FAIL_COND(selected.is_empty());
if (selected == current_profile) {
return; // Nothing to do here.
}
@@ -438,7 +438,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
} break;
case PROFILE_ERASE: {
String selected = _get_selected_profile();
- ERR_FAIL_COND(selected == String());
+ ERR_FAIL_COND(selected.is_empty());
erase_profile_dialog->set_text(vformat(TTR("Remove currently selected profile, '%s'? Cannot be undone."), selected));
erase_profile_dialog->popup_centered(Size2(240, 60) * EDSCALE);
@@ -448,7 +448,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
void EditorFeatureProfileManager::_erase_selected_profile() {
String selected = _get_selected_profile();
- ERR_FAIL_COND(selected == String());
+ ERR_FAIL_COND(selected.is_empty());
DirAccessRef da = DirAccess::open(EditorSettings::get_singleton()->get_feature_profiles_dir());
ERR_FAIL_COND_MSG(!da, "Cannot open directory '" + EditorSettings::get_singleton()->get_feature_profiles_dir() + "'.");
@@ -718,7 +718,7 @@ void EditorFeatureProfileManager::_update_selected_profile() {
class_list->clear();
String profile = _get_selected_profile();
- if (profile == String()) { //nothing selected, nothing edited
+ if (profile.is_empty()) { //nothing selected, nothing edited
property_list->clear();
edited.unref();
return;
@@ -822,7 +822,7 @@ void EditorFeatureProfileManager::_export_profile(const String &p_path) {
void EditorFeatureProfileManager::_save_and_update() {
String edited_path = _get_selected_profile();
- ERR_FAIL_COND(edited_path == String());
+ ERR_FAIL_COND(edited_path.is_empty());
ERR_FAIL_COND(edited.is_null());
edited->save_to_file(EditorSettings::get_singleton()->get_feature_profiles_dir().plus_file(edited_path + ".profile"));
@@ -948,7 +948,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
Ref<StyleBoxEmpty> sb = memnew(StyleBoxEmpty);
sb->set_default_margin(SIDE_TOP, 20 * EDSCALE);
no_profile_selected_help->add_theme_style_override("normal", sb);
- no_profile_selected_help->set_align(Label::ALIGN_CENTER);
+ no_profile_selected_help->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
no_profile_selected_help->set_v_size_flags(Control::SIZE_EXPAND_FILL);
h_split->add_child(no_profile_selected_help);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index bea5c99c1a..a35458d284 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -274,7 +274,7 @@ void EditorFileDialog::_post_popup() {
file_box->set_visible(true);
}
- if (is_visible() && get_current_file() != "") {
+ if (is_visible() && !get_current_file().is_empty()) {
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
}
@@ -608,7 +608,8 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p
}
if (item_menu->get_item_count() > 0) {
- item_menu->set_position(item_list->get_global_position() + p_pos);
+ item_menu->set_position(item_list->get_screen_position() + p_pos);
+ item_menu->reset_size();
item_menu->popup();
}
}
@@ -629,7 +630,8 @@ void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
item_menu->add_separator();
item_menu->add_icon_item(item_list->get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
- item_menu->set_position(item_list->get_global_position() + p_pos);
+ item_menu->set_position(item_list->get_screen_position() + p_pos);
+ item_menu->reset_size();
item_menu->popup();
}
@@ -761,10 +763,11 @@ void EditorFileDialog::update_file_list() {
List<String> files;
List<String> dirs;
- String item;
+ String item = dir_access->get_next();
- while ((item = dir_access->get_next()) != "") {
+ while (!item.is_empty()) {
if (item == "." || item == "..") {
+ item = dir_access->get_next();
continue;
}
@@ -775,6 +778,7 @@ void EditorFileDialog::update_file_list() {
dirs.push_back(item);
}
}
+ item = dir_access->get_next();
}
dirs.sort_custom<NaturalNoCaseComparator>();
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 4f02a82fb5..d515b58e37 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -241,7 +241,7 @@ void EditorFileSystem::_scan_filesystem() {
first = false;
continue;
}
- if (l == String()) {
+ if (l.is_empty()) {
continue;
}
@@ -295,7 +295,7 @@ void EditorFileSystem::_scan_filesystem() {
{
FileAccessRef f2 = FileAccess::open(update_cache, FileAccess::READ);
String l = f2->get_line().strip_edges();
- while (l != String()) {
+ while (!l.is_empty()) {
file_cache.erase(l); //erase cache for this, so it gets updated
l = f2->get_line().strip_edges();
}
@@ -405,7 +405,7 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
return false; //parse error, try reimport manually (Avoid reimport loop on broken file)
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
if (assign.begins_with("path")) {
to_check.push_back(value);
} else if (assign == "files") {
@@ -476,7 +476,7 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
memdelete(md5s);
return false; // parse error
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
if (!p_only_imported_files) {
if (assign == "source_md5") {
source_md5 = value;
@@ -497,11 +497,11 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
//check source md5 matching
if (!p_only_imported_files) {
- if (source_file != String() && source_file != p_path) {
+ if (!source_file.is_empty() && source_file != p_path) {
return true; //file was moved, reimport
}
- if (source_md5 == String()) {
+ if (source_md5.is_empty()) {
return true; //lacks md5, so just reimport
}
@@ -510,7 +510,7 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
return true;
}
- if (dest_files.size() && dest_md5 != String()) {
+ if (dest_files.size() && !dest_md5.is_empty()) {
md5 = FileAccess::get_multiple_md5(dest_files);
if (md5 != dest_md5) {
return true;
@@ -710,7 +710,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
da->list_dir_begin();
while (true) {
String f = da->get_next();
- if (f == "") {
+ if (f.is_empty()) {
break;
}
@@ -820,7 +820,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
scan_actions.push_back(ia);
}
- if (fc->type == String()) {
+ if (fc->type.is_empty()) {
fi->type = ResourceLoader::get_resource_type(path);
fi->import_group_file = ResourceLoader::get_import_group_file(path);
//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
@@ -932,7 +932,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
da->list_dir_begin();
while (true) {
String f = da->get_next();
- if (f == "") {
+ if (f.is_empty()) {
break;
}
@@ -1246,7 +1246,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
p_file->store_line("::" + p_dir->get_path() + "::" + String::num(p_dir->modified_time));
for (int i = 0; i < p_dir->files.size(); i++) {
- if (p_dir->files[i]->import_group_file != String()) {
+ if (!p_dir->files[i]->import_group_file.is_empty()) {
group_file_cache.insert(p_dir->files[i]->import_group_file);
}
String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->uid) + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
@@ -1386,7 +1386,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
f = f.substr(6, f.length());
f = f.replace("\\", "/");
- if (f == String()) {
+ if (f.is_empty()) {
return filesystem;
}
@@ -1465,7 +1465,7 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) {
int filecount = p_dir->files.size();
const EditorFileSystemDirectory::FileInfo *const *files = p_dir->files.ptr();
for (int i = 0; i < filecount; i++) {
- if (files[i]->script_class_name == String()) {
+ if (files[i]->script_class_name.is_empty()) {
continue;
}
@@ -1545,7 +1545,7 @@ void EditorFileSystem::update_file(const String &p_file) {
}
String type = ResourceLoader::get_resource_type(p_file);
- if (type == "" && textfile_extensions.has(p_file.get_extension())) {
+ if (type.is_empty() && textfile_extensions.has(p_file.get_extension())) {
type = "TextFile";
}
ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_file);
@@ -1616,9 +1616,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
ERR_CONTINUE(err != OK);
ERR_CONTINUE(!config->has_section_key("remap", "importer"));
String file_importer_name = config->get_value("remap", "importer");
- ERR_CONTINUE(file_importer_name == String());
+ ERR_CONTINUE(file_importer_name.is_empty());
- if (importer_name != String() && importer_name != file_importer_name) {
+ if (!importer_name.is_empty() && importer_name != file_importer_name) {
EditorNode::get_singleton()->show_warning(vformat(TTR("There are multiple importers for different types pointing to file %s, import aborted"), p_group_file));
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
@@ -1656,7 +1656,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
return OK; // (do nothing)
}
- ERR_FAIL_COND_V(importer_name == String(), ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(importer_name.is_empty(), ERR_UNCONFIGURED);
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
@@ -1677,7 +1677,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
if (version > 0) {
f->store_line("importer_version=" + itos(version));
}
- if (importer->get_resource_type() != "") {
+ if (!importer->get_resource_type().is_empty()) {
f->store_line("type=\"" + importer->get_resource_type() + "\"");
}
@@ -1759,7 +1759,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
if (ResourceCache::has(file)) {
Resource *r = ResourceCache::get(file);
- if (r->get_import_path() != String()) {
+ if (!r->get_import_path().is_empty()) {
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(file);
r->set_import_path(dst_path);
r->set_import_last_modified_time(0);
@@ -1783,7 +1783,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
Map<StringName, Variant> params;
String importer_name; //empty by default though
- if (p_custom_importer != String()) {
+ if (!p_custom_importer.is_empty()) {
importer_name = p_custom_importer;
}
if (p_custom_options != nullptr) {
@@ -1808,7 +1808,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
}
if (cf->has_section("remap")) {
- if (p_custom_importer == String()) {
+ if (p_custom_importer.is_empty()) {
importer_name = cf->get_value("remap", "importer");
}
@@ -1834,7 +1834,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
Ref<ResourceImporter> importer;
bool load_default = false;
//find the importer
- if (importer_name != "") {
+ if (!importer_name.is_empty()) {
importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
}
@@ -1894,7 +1894,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
if (version > 0) {
f->store_line("importer_version=" + itos(version));
}
- if (importer->get_resource_type() != "") {
+ if (!importer->get_resource_type().is_empty()) {
f->store_line("type=\"" + importer->get_resource_type() + "\"");
}
@@ -1907,7 +1907,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
Vector<String> dest_paths;
if (err == OK) {
- if (importer->get_save_extension() == "") {
+ if (importer->get_save_extension().is_empty()) {
//no path
} else if (import_variants.size()) {
//import with variants
@@ -2003,7 +2003,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const Map<StringName
if (ResourceCache::has(p_file)) {
Resource *r = ResourceCache::get(p_file);
- if (r->get_import_path() != String()) {
+ if (!r->get_import_path().is_empty()) {
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file);
r->set_import_path(dst_path);
r->set_import_last_modified_time(0);
@@ -2062,7 +2062,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
groups_to_reimport.insert(file);
//groups do not belong to grups
group_file = String();
- } else if (group_file != String()) {
+ } else if (!group_file.is_empty()) {
//it's a group file, add group to import and skip this file
groups_to_reimport.insert(group_file);
} else {
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
index 29e3236ac2..b8341ee406 100644
--- a/editor/editor_folding.cpp
+++ b/editor/editor_folding.cpp
@@ -113,7 +113,7 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p
if (E.usage & PROPERTY_USAGE_EDITOR) {
if (E.type == Variant::OBJECT) {
RES res = p_node->get(E.name);
- if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+ if (res.is_valid() && !resources.has(res) && !res->get_path().is_empty() && !res->get_path().is_resource_file()) {
Vector<String> res_unfolds = _get_unfolds(res.ptr());
resource_folds.push_back(res->get_path());
resource_folds.push_back(res_unfolds);
@@ -243,8 +243,8 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
//can unfold
if (E.usage & PROPERTY_USAGE_EDITOR) {
- if (group != "") { //group
- if (group_base == String() || E.name.begins_with(group_base)) {
+ if (!group.is_empty()) { //group
+ if (group_base.is_empty() || E.name.begins_with(group_base)) {
bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E.name);
if (can_revert) {
unfold_group.insert(group);
@@ -262,11 +262,7 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
if (E.type == Variant::OBJECT) {
RES res = p_object->get(E.name);
- print_line("res: " + String(E.name) + " valid " + itos(res.is_valid()));
- if (res.is_valid()) {
- print_line("path " + res->get_path());
- }
- if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+ if (res.is_valid() && !resources.has(res) && !res->get_path().is_empty() && !res->get_path().is_resource_file()) {
resources.insert(res);
_do_object_unfolds(res.ptr(), resources);
}
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index a644e3e991..c65bfa6472 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -78,7 +78,7 @@
} \
{ \
Dictionary variations; \
- if (m_variations != String()) { \
+ if (!m_variations.is_empty()) { \
Vector<String> variation_tags = m_variations.split(","); \
for (int i = 0; i < variation_tags.size(); i++) { \
Vector<String> tokens = variation_tags[i].split("="); \
@@ -104,7 +104,7 @@
} \
{ \
Dictionary variations; \
- if (m_variations != String()) { \
+ if (!m_variations.is_empty()) { \
Vector<String> variation_tags = m_variations.split(","); \
for (int i = 0; i < variation_tags.size(); i++) { \
Vector<String> tokens = variation_tags[i].split("="); \
@@ -130,7 +130,7 @@
} \
{ \
Dictionary variations; \
- if (m_variations != String()) { \
+ if (!m_variations.is_empty()) { \
Vector<String> variation_tags = m_variations.split(","); \
for (int i = 0; i < variation_tags.size(); i++) { \
Vector<String> tokens = variation_tags[i].split("="); \
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index f520877256..fc1e7ef389 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -235,10 +235,9 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
if (p_overview) {
class_desc->push_cell();
- class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
+ class_desc->push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
} else {
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
}
_add_type(p_method.return_type, p_method.return_enum);
@@ -251,7 +250,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
class_desc->add_text(" ");
}
- if (p_overview && p_method.description != "") {
+ if (p_overview && !p_method.description.is_empty()) {
class_desc->push_meta("@method " + p_method.name);
}
@@ -259,7 +258,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
_add_text(p_method.name);
class_desc->pop();
- if (p_overview && p_method.description != "") {
+ if (p_overview && !p_method.description.is_empty()) {
class_desc->pop(); //meta
}
@@ -276,7 +275,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
_add_text(p_method.arguments[j].name);
class_desc->add_text(": ");
_add_type(p_method.arguments[j].type, p_method.arguments[j].enumeration);
- if (p_method.arguments[j].default_value != "") {
+ if (!p_method.arguments[j].default_value.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
@@ -302,7 +301,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
class_desc->push_color(symbol_color);
class_desc->add_text(")");
class_desc->pop();
- if (p_method.qualifiers != "") {
+ if (!p_method.qualifiers.is_empty()) {
class_desc->push_color(qualifier_color);
class_desc->add_text(" ");
_add_text(p_method.qualifiers);
@@ -314,6 +313,11 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
}
}
+void EditorHelp::_add_bulletpoint() {
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ class_desc->add_text(String(prefix));
+}
+
Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (!doc->class_list.has(p_class)) {
return ERR_DOES_NOT_EXIST;
@@ -371,7 +375,7 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods,
if (i < m.size() - 1 && new_prefix == m[i + 1].name.substr(0, 3) && new_prefix != group_prefix) {
is_new_group = i > 0;
group_prefix = new_prefix;
- } else if (group_prefix != "" && new_prefix != group_prefix) {
+ } else if (!group_prefix.is_empty() && new_prefix != group_prefix) {
is_new_group = true;
group_prefix = "";
}
@@ -383,7 +387,7 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods,
class_desc->pop(); //cell
}
- if (m[i].description != "" || m[i].errors_returned.size() > 0) {
+ if (!m[i].description.is_empty() || m[i].errors_returned.size() > 0) {
r_method_descrpitons = true;
}
@@ -517,19 +521,19 @@ void EditorHelp::_update_doc() {
// Inheritance tree
// Ascendents
- if (cd.inherits != "") {
+ if (!cd.inherits.is_empty()) {
class_desc->push_color(title_color);
class_desc->push_font(doc_font);
class_desc->add_text(TTR("Inherits:") + " ");
String inherits = cd.inherits;
- while (inherits != "") {
+ while (!inherits.is_empty()) {
_add_type(inherits);
inherits = doc->class_list[inherits].inherits;
- if (inherits != "") {
+ if (!inherits.is_empty()) {
class_desc->add_text(" < ");
}
}
@@ -573,7 +577,7 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
// Brief description
- if (cd.brief_description != "") {
+ if (!cd.brief_description.is_empty()) {
class_desc->push_color(text_color);
class_desc->push_font(doc_bold_font);
class_desc->push_indent(1);
@@ -587,7 +591,7 @@ void EditorHelp::_update_doc() {
}
// Class description
- if (cd.description != "") {
+ if (!cd.description.is_empty()) {
section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_line_count() - 2));
description_line = class_desc->get_line_count() - 2;
class_desc->push_color(title_color);
@@ -669,7 +673,7 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
class_desc->push_font(doc_code_font);
class_desc->push_indent(1);
- class_desc->push_table(2);
+ class_desc->push_table(4);
class_desc->set_table_column_expand(1, true);
for (int i = 0; i < cd.properties.size(); i++) {
@@ -679,26 +683,27 @@ void EditorHelp::_update_doc() {
}
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
+ // Property type.
class_desc->push_cell();
- class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
+ class_desc->push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
class_desc->push_font(doc_code_font);
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
class_desc->pop();
class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // cell
bool describe = false;
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].setter.is_empty()) {
skip_methods.insert(cd.properties[i].setter);
describe = true;
}
- if (cd.properties[i].getter != "") {
+ if (!cd.properties[i].getter.is_empty()) {
skip_methods.insert(cd.properties[i].getter);
describe = true;
}
- if (cd.properties[i].description != "") {
+ if (!cd.properties[i].description.is_empty()) {
describe = true;
}
@@ -706,6 +711,7 @@ void EditorHelp::_update_doc() {
describe = false;
}
+ // Property name.
class_desc->push_cell();
class_desc->push_font(doc_code_font);
class_desc->push_color(headline_color);
@@ -721,30 +727,55 @@ void EditorHelp::_update_doc() {
property_descr = true;
}
- if (cd.properties[i].default_value != "") {
+ class_desc->pop();
+ class_desc->pop();
+ class_desc->pop(); // cell
+
+ // Property value.
+ class_desc->push_cell();
+ class_desc->push_font(doc_code_font);
+
+ if (!cd.properties[i].default_value.is_empty()) {
class_desc->push_color(symbol_color);
- class_desc->add_text(cd.properties[i].overridden ? " [" + TTR("override:") + " " : " [" + TTR("default:") + " ");
+ if (cd.properties[i].overridden) {
+ class_desc->add_text(" [");
+ class_desc->push_meta("@member " + cd.properties[i].overrides + "." + cd.properties[i].name);
+ _add_text(vformat(TTR("overrides %s:"), cd.properties[i].overrides));
+ class_desc->pop();
+ class_desc->add_text(" ");
+ } else {
+ class_desc->add_text(" [" + TTR("default:") + " ");
+ }
class_desc->pop();
+
class_desc->push_color(value_color);
_add_text(_fix_constant(cd.properties[i].default_value));
class_desc->pop();
+
class_desc->push_color(symbol_color);
class_desc->add_text("]");
class_desc->pop();
}
- if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) {
+ class_desc->pop();
+ class_desc->pop(); // cell
+
+ // Property setters and getters.
+ class_desc->push_cell();
+ class_desc->push_font(doc_code_font);
+
+ if (cd.is_script_doc && (!cd.properties[i].setter.is_empty() || !cd.properties[i].getter.is_empty())) {
class_desc->push_color(symbol_color);
class_desc->add_text(" [" + TTR("property:") + " ");
class_desc->pop(); // color
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].setter.is_empty()) {
class_desc->push_color(value_color);
class_desc->add_text("setter");
class_desc->pop(); // color
}
- if (cd.properties[i].getter != "") {
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].getter.is_empty()) {
+ if (!cd.properties[i].setter.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(", ");
class_desc->pop(); // color
@@ -760,12 +791,10 @@ void EditorHelp::_update_doc() {
}
class_desc->pop();
- class_desc->pop();
-
- class_desc->pop();
+ class_desc->pop(); // cell
}
- class_desc->pop(); //table
+ class_desc->pop(); // table
class_desc->pop();
class_desc->pop(); // font
class_desc->add_newline();
@@ -837,28 +866,55 @@ void EditorHelp::_update_doc() {
class_desc->pop();
class_desc->pop();
+ class_desc->add_newline();
+ class_desc->add_newline();
+
class_desc->push_indent(1);
- class_desc->push_table(2);
- class_desc->set_table_column_expand(1, true);
+
+ String theme_data_type;
+ Map<String, String> data_type_names;
+ data_type_names["color"] = TTR("Colors");
+ data_type_names["constant"] = TTR("Constants");
+ data_type_names["font"] = TTR("Fonts");
+ data_type_names["font_size"] = TTR("Font Sizes");
+ data_type_names["icon"] = TTR("Icons");
+ data_type_names["style"] = TTR("Styles");
for (int i = 0; i < cd.theme_properties.size(); i++) {
theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
- class_desc->push_cell();
- class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
+ if (theme_data_type != cd.theme_properties[i].data_type) {
+ theme_data_type = cd.theme_properties[i].data_type;
+
+ class_desc->push_color(title_color);
+ class_desc->push_font(doc_title_font);
+ if (data_type_names.has(theme_data_type)) {
+ class_desc->add_text(data_type_names[theme_data_type]);
+ } else {
+ class_desc->add_text("");
+ }
+ class_desc->pop();
+ class_desc->pop();
+
+ class_desc->add_newline();
+ class_desc->add_newline();
+ }
+
+ // Theme item header.
class_desc->push_font(doc_code_font);
+ _add_bulletpoint();
+
+ // Theme item object type.
_add_type(cd.theme_properties[i].type);
- class_desc->pop();
- class_desc->pop();
- class_desc->pop();
- class_desc->push_cell();
- class_desc->push_font(doc_code_font);
+ // Theme item name.
class_desc->push_color(headline_color);
+ class_desc->add_text(" ");
_add_text(cd.theme_properties[i].name);
class_desc->pop();
- if (cd.theme_properties[i].default_value != "") {
+ // Theme item default value.
+ if (!cd.theme_properties[i].default_value.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(" [" + TTR("default:") + " ");
class_desc->pop();
@@ -870,23 +926,25 @@ void EditorHelp::_update_doc() {
class_desc->pop();
}
- class_desc->pop();
+ class_desc->pop(); // monofont
- if (cd.theme_properties[i].description != "") {
+ // Theme item description.
+ if (!cd.theme_properties[i].description.is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
- class_desc->add_text(U" – ");
+ class_desc->push_indent(1);
_add_text(DTR(cd.theme_properties[i].description));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // indent
+ class_desc->pop(); // color
+ class_desc->pop(); // font
}
- class_desc->pop(); // cell
+
+ class_desc->add_newline();
+ class_desc->add_newline();
}
- class_desc->pop(); // table
class_desc->pop();
class_desc->add_newline();
- class_desc->add_newline();
}
// Signals
@@ -909,10 +967,10 @@ void EditorHelp::_update_doc() {
for (int i = 0; i < cd.signals.size(); i++) {
signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
+
class_desc->push_font(doc_code_font); // monofont
class_desc->push_color(headline_color);
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
_add_text(cd.signals[i].name);
class_desc->pop();
class_desc->push_color(symbol_color);
@@ -927,7 +985,7 @@ void EditorHelp::_update_doc() {
_add_text(cd.signals[i].arguments[j].name);
class_desc->add_text(": ");
_add_type(cd.signals[i].arguments[j].type);
- if (cd.signals[i].arguments[j].default_value != "") {
+ if (!cd.signals[i].arguments[j].default_value.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
@@ -941,7 +999,7 @@ void EditorHelp::_update_doc() {
class_desc->add_text(")");
class_desc->pop();
class_desc->pop(); // end monofont
- if (cd.signals[i].description != "") {
+ if (!cd.signals[i].description.is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
class_desc->push_indent(1);
@@ -1043,8 +1101,7 @@ void EditorHelp::_update_doc() {
class_desc->push_font(doc_code_font);
class_desc->push_color(headline_color);
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
_add_text(enum_list[i].name);
class_desc->pop();
class_desc->push_color(symbol_color);
@@ -1054,10 +1111,12 @@ void EditorHelp::_update_doc() {
_add_text(_fix_constant(enum_list[i].value));
class_desc->pop();
class_desc->pop();
- if (enum_list[i].description != "") {
+
+ class_desc->add_newline();
+
+ if (!enum_list[i].description.strip_edges().is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
- class_desc->add_text(U" – ");
_add_text(DTR(enum_list[i].description));
class_desc->pop();
class_desc->pop();
@@ -1103,13 +1162,11 @@ void EditorHelp::_update_doc() {
Vector<float> color = stripped.split_floats(",");
if (color.size() >= 3) {
class_desc->push_color(Color(color[0], color[1], color[2]));
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
class_desc->pop();
}
} else {
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
}
class_desc->push_color(headline_color);
@@ -1123,10 +1180,12 @@ void EditorHelp::_update_doc() {
class_desc->pop();
class_desc->pop();
- if (constants[i].description != "") {
+
+ class_desc->add_newline();
+
+ if (!constants[i].description.is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
- class_desc->add_text(U" – ");
_add_text(DTR(constants[i].description));
class_desc->pop();
class_desc->pop();
@@ -1167,8 +1226,7 @@ void EditorHelp::_update_doc() {
class_desc->push_cell();
class_desc->push_font(doc_code_font);
- static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
- class_desc->add_text(String(prefix));
+ _add_bulletpoint();
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
class_desc->add_text(" ");
@@ -1181,7 +1239,7 @@ void EditorHelp::_update_doc() {
_add_text(cd.properties[i].name);
class_desc->pop(); // color
- if (cd.properties[i].default_value != "") {
+ if (!cd.properties[i].default_value.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(" [" + TTR("default:") + " ");
class_desc->pop(); // color
@@ -1195,18 +1253,18 @@ void EditorHelp::_update_doc() {
class_desc->pop(); // color
}
- if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) {
+ if (cd.is_script_doc && (!cd.properties[i].setter.is_empty() || !cd.properties[i].getter.is_empty())) {
class_desc->push_color(symbol_color);
class_desc->add_text(" [" + TTR("property:") + " ");
class_desc->pop(); // color
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].setter.is_empty()) {
class_desc->push_color(value_color);
class_desc->add_text("setter");
class_desc->pop(); // color
}
- if (cd.properties[i].getter != "") {
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].getter.is_empty()) {
+ if (!cd.properties[i].setter.is_empty()) {
class_desc->push_color(symbol_color);
class_desc->add_text(", ");
class_desc->pop(); // color
@@ -1231,7 +1289,7 @@ void EditorHelp::_update_doc() {
method_map[methods[j].name] = methods[j];
}
- if (cd.properties[i].setter != "") {
+ if (!cd.properties[i].setter.is_empty()) {
class_desc->push_cell();
class_desc->pop(); // cell
@@ -1255,7 +1313,7 @@ void EditorHelp::_update_doc() {
method_line[cd.properties[i].setter] = property_line[cd.properties[i].name];
}
- if (cd.properties[i].getter != "") {
+ if (!cd.properties[i].getter.is_empty()) {
class_desc->push_cell();
class_desc->pop(); // cell
@@ -1588,7 +1646,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.push_front(tag);
} else if (tag == "center") {
//align to center
- p_rt->push_paragraph(RichTextLabel::ALIGN_CENTER, Control::TEXT_DIRECTION_AUTO, "");
+ p_rt->push_paragraph(HORIZONTAL_ALIGNMENT_CENTER, Control::TEXT_DIRECTION_AUTO, "");
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "br") {
diff --git a/editor/editor_help.h b/editor/editor_help.h
index c0f3f66505..393e4a940a 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -145,6 +145,8 @@ class EditorHelp : public VBoxContainer {
void _add_type(const String &p_type, const String &p_enum = String());
void _add_method(const DocData::MethodDoc &p_method, bool p_overview = true);
+ void _add_bulletpoint();
+
void _class_list_select(const String &p_select);
void _class_desc_select(const String &p_select);
void _class_desc_input(const Ref<InputEvent> &p_input);
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 578e21861e..bf7280dfd0 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -161,7 +161,7 @@ void EditorHelpSearch::popup_dialog(const String &p_term) {
popup_centered_ratio(0.5F);
}
- if (p_term == "") {
+ if (p_term.is_empty()) {
search_box->clear();
} else {
if (old_term == p_term) {
@@ -331,7 +331,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
// Match class name.
if (search_flags & SEARCH_CLASSES) {
- match.name = term == "" || _match_string(term, class_doc.name);
+ match.name = term.is_empty() || _match_string(term, class_doc.name);
}
// Match members if the term is long enough.
@@ -513,7 +513,7 @@ TreeItem *EditorHelpSearch::Runner::_create_class_hierarchy(const ClassMatch &p_
// Ensure parent nodes are created first.
TreeItem *parent = root_item;
- if (p_match.doc->inherits != "") {
+ if (!p_match.doc->inherits.is_empty()) {
if (class_items.has(p_match.doc->inherits)) {
parent = class_items[p_match.doc->inherits];
} else {
@@ -558,7 +558,7 @@ TreeItem *EditorHelpSearch::Runner::_create_method_item(TreeItem *p_parent, cons
for (int i = 0; i < p_doc->arguments.size(); i++) {
const DocData::ArgumentDoc &arg = p_doc->arguments[i];
tooltip += arg.type + " " + arg.name;
- if (arg.default_value != "") {
+ if (!arg.default_value.is_empty()) {
tooltip += " = " + arg.default_value;
}
if (i < p_doc->arguments.size() - 1) {
@@ -574,7 +574,7 @@ TreeItem *EditorHelpSearch::Runner::_create_signal_item(TreeItem *p_parent, cons
for (int i = 0; i < p_doc->arguments.size(); i++) {
const DocData::ArgumentDoc &arg = p_doc->arguments[i];
tooltip += arg.type + " " + arg.name;
- if (arg.default_value != "") {
+ if (!arg.default_value.is_empty()) {
tooltip += " = " + arg.default_value;
}
if (i < p_doc->arguments.size() - 1) {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index e1fae47057..14185ce2a4 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -310,7 +310,7 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"));
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, font_size, rtl ? HALIGN_RIGHT : HALIGN_LEFT, text_limit - total_icon_w).x;
+ int text_w = font->get_string_size(label, font_size, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w).x;
int y = (size.height - pinned_icon->get_height()) / 2;
if (rtl) {
draw_texture(pinned_icon, Vector2(size.width - ofs - text_w - total_icon_w, y), color);
@@ -322,9 +322,9 @@ void EditorProperty::_notification(int p_what) {
int v_ofs = (size.height - font->get_height(font_size)) / 2;
if (rtl) {
- draw_string(font, Point2(size.width - ofs - text_limit, v_ofs + font->get_ascent(font_size)), label, HALIGN_RIGHT, text_limit, font_size, color);
+ draw_string(font, Point2(size.width - ofs - text_limit, v_ofs + font->get_ascent(font_size)), label, HORIZONTAL_ALIGNMENT_RIGHT, text_limit, font_size, color);
} else {
- draw_string(font, Point2(ofs, v_ofs + font->get_ascent(font_size)), label, HALIGN_LEFT, text_limit, font_size, color);
+ draw_string(font, Point2(ofs, v_ofs + font->get_ascent(font_size)), label, HORIZONTAL_ALIGNMENT_LEFT, text_limit, font_size, color);
}
if (keying) {
@@ -1077,7 +1077,7 @@ void EditorInspectorCategory::_notification(int p_what) {
}
Color color = get_theme_color(SNAME("font_color"), SNAME("Tree"));
- draw_string(font, Point2(ofs, font->get_ascent(font_size) + (get_size().height - font->get_height(font_size)) / 2).floor(), label, HALIGN_LEFT, get_size().width, font_size, color);
+ draw_string(font, Point2(ofs, font->get_ascent(font_size) + (get_size().height - font->get_height(font_size)) / 2).floor(), label, HORIZONTAL_ALIGNMENT_LEFT, get_size().width, font_size, color);
}
}
@@ -1144,7 +1144,7 @@ void EditorInspectorSection::_test_unfold() {
void EditorInspectorSection::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
} break;
case NOTIFICATION_SORT_CHILDREN: {
if (!vbox_added) {
@@ -1230,7 +1230,7 @@ void EditorInspectorSection::_notification(int p_what) {
const int arrow_width = arrow.is_valid() ? arrow->get_width() : 0;
Color color = get_theme_color(SNAME("font_color"));
float text_width = get_size().width - Math::round(arrow_width + arrow_margin * EDSCALE);
- draw_string(font, Point2(rtl ? 0 : Math::round(arrow_width + arrow_margin * EDSCALE), font->get_ascent(font_size) + (header_height - font->get_height(font_size)) / 2).floor(), label, rtl ? HALIGN_RIGHT : HALIGN_LEFT, text_width, font_size, color);
+ draw_string(font, Point2(rtl ? 0 : Math::round(arrow_width + arrow_margin * EDSCALE), font->get_ascent(font_size) + (header_height - font->get_height(font_size)) / 2).floor(), label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_width, font_size, color);
if (arrow.is_valid()) {
if (rtl) {
@@ -1555,7 +1555,7 @@ void EditorInspectorArray::_panel_gui_input(Ref<InputEvent> p_event, int p_index
popup_array_index_pressed = begin_array_index + p_index;
rmb_popup->set_item_disabled(OPTION_MOVE_UP, popup_array_index_pressed == 0);
rmb_popup->set_item_disabled(OPTION_MOVE_DOWN, popup_array_index_pressed == count - 1);
- rmb_popup->set_position(mb->get_global_position());
+ rmb_popup->set_position(get_screen_position() + mb->get_position());
rmb_popup->reset_size();
rmb_popup->popup();
}
@@ -1995,7 +1995,7 @@ void EditorInspectorArray::_notification(int p_what) {
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")));
- minimum_size_changed();
+ update_minimum_size();
} break;
case NOTIFICATION_DRAG_BEGIN: {
Dictionary dict = get_viewport()->gui_get_drag_data();
@@ -2083,13 +2083,13 @@ EditorInspectorArray::EditorInspectorArray() {
add_button = memnew(Button);
add_button->set_text(TTR("Add Element"));
- add_button->set_text_align(Button::ALIGN_CENTER);
+ add_button->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
add_button->connect("pressed", callable_mp(this, &EditorInspectorArray::_add_button_pressed));
vbox->add_child(add_button);
hbox_pagination = memnew(HBoxContainer);
hbox_pagination->set_h_size_flags(SIZE_EXPAND_FILL);
- hbox_pagination->set_alignment(HBoxContainer::ALIGN_CENTER);
+ hbox_pagination->set_alignment(BoxContainer::ALIGNMENT_CENTER);
vbox->add_child(hbox_pagination);
first_page_button = memnew(Button);
@@ -2194,10 +2194,7 @@ void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &
for (int i = idx; i < inspector_plugin_count - 1; i++) {
inspector_plugins[i] = inspector_plugins[i + 1];
}
-
- if (idx == inspector_plugin_count - 1) {
- inspector_plugins[idx] = Ref<EditorInspectorPlugin>();
- }
+ inspector_plugins[inspector_plugin_count - 1] = Ref<EditorInspectorPlugin>();
inspector_plugin_count--;
}
@@ -2242,7 +2239,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->property_usage = 0;
}
- if (F.label != String()) {
+ if (!F.label.is_empty()) {
ep->set_label(F.label);
}
@@ -2441,7 +2438,7 @@ void EditorInspector::update_tree() {
}
}
if (category->icon.is_null()) {
- if (type != String()) { // Can happen for built-in scripts.
+ if (!type.is_empty()) { // Can happen for built-in scripts.
category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object");
}
}
@@ -2462,7 +2459,7 @@ void EditorInspector::update_tree() {
class_descr_cache[type2] = descr;
}
- category->set_tooltip(p.name + "::" + (class_descr_cache[type2] == "" ? "" : class_descr_cache[type2]));
+ category->set_tooltip(p.name + "::" + (class_descr_cache[type2].is_empty() ? "" : class_descr_cache[type2]));
}
// Add editors at the start of a category.
@@ -2532,7 +2529,7 @@ void EditorInspector::update_tree() {
}
} else {
// Check if we exit or not a subgroup. If there is a prefix, remove it from the property label string.
- if (subgroup != "" && subgroup_base != "") {
+ if (!subgroup.is_empty() && !subgroup_base.is_empty()) {
if (path.begins_with(subgroup_base)) {
path = path.trim_prefix(subgroup_base);
} else if (subgroup_base.begins_with(path)) {
@@ -2543,7 +2540,7 @@ void EditorInspector::update_tree() {
}
// Check if we exit or not a group. If there is a prefix, remove it from the property label string.
- if (group != "" && group_base != "" && subgroup == "") {
+ if (!group.is_empty() && !group_base.is_empty() && subgroup.is_empty()) {
if (path.begins_with(group_base)) {
path = path.trim_prefix(group_base);
} else if (group_base.begins_with(path)) {
@@ -2555,10 +2552,10 @@ void EditorInspector::update_tree() {
}
// Add the group and subgroup to the path.
- if (subgroup != "") {
+ if (!subgroup.is_empty()) {
path = subgroup + "/" + path;
}
- if (group != "") {
+ if (!group.is_empty()) {
path = group + "/" + path;
}
}
@@ -2587,7 +2584,7 @@ void EditorInspector::update_tree() {
}
// Ignore properties that do not fit the filter.
- if (use_filter && filter != "") {
+ if (use_filter && !filter.is_empty()) {
if (!filter.is_subsequence_ofi(path) && !filter.is_subsequence_ofi(property_label_string) && property_prefix.to_lower().find(filter.to_lower()) == -1) {
continue;
}
@@ -2710,7 +2707,7 @@ void EditorInspector::update_tree() {
// Get the class name.
StringName classname = object->get_class_name();
- if (object_class != String()) {
+ if (!object_class.is_empty()) {
classname = object_class;
}
@@ -2732,7 +2729,7 @@ void EditorInspector::update_tree() {
// Build the property description String and add it to the cache.
DocTools *dd = EditorHelp::get_doc_data();
Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(classname);
- while (F && descr == String()) {
+ while (F && descr.is_empty()) {
for (int i = 0; i < F->get().properties.size(); i++) {
if (F->get().properties[i].name == propname.operator String()) {
descr = DTR(F->get().properties[i].description);
@@ -2784,7 +2781,7 @@ void EditorInspector::update_tree() {
//and set label?
}
- if (F.label != String()) {
+ if (!F.label.is_empty()) {
ep->set_label(F.label);
} else {
// Use the existing one.
@@ -2823,7 +2820,7 @@ void EditorInspector::update_tree() {
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED);
- if (doc_hint != String()) {
+ if (!doc_hint.is_empty()) {
ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
} else {
ep->set_tooltip(property_prefix + p.name);
@@ -3053,7 +3050,7 @@ void EditorInspector::_edit_request_change(Object *p_object, const String &p_pro
return;
}
- if (p_property == String()) {
+ if (p_property.is_empty()) {
update_tree_pending = true;
} else {
pending.insert(p_property);
@@ -3543,8 +3540,7 @@ EditorInspector::EditorInspector() {
main_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
main_vbox->add_theme_constant_override("separation", 0);
add_child(main_vbox);
- set_enable_h_scroll(false);
- set_enable_v_scroll(true);
+ set_horizontal_scroll_mode(SCROLL_MODE_DISABLED);
wide_editors = false;
show_categories = false;
diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp
index 4cdeeb2396..7c8965d6f4 100644
--- a/editor/editor_layouts_dialog.cpp
+++ b/editor/editor_layouts_dialog.cpp
@@ -74,7 +74,7 @@ void EditorLayoutsDialog::ok_pressed() {
for (int i = 0; i < selected_items.size(); ++i) {
emit_signal(SNAME("name_confirmed"), layout_names->get_item_text(selected_items[i]));
}
- } else if (name->is_visible() && name->get_text() != "") {
+ } else if (name->is_visible() && !name->get_text().is_empty()) {
emit_signal(SNAME("name_confirmed"), name->get_text());
}
}
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 5ace9ae03e..7bd98b0f0b 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -162,11 +162,11 @@ void EditorLog::_clear_request() {
void EditorLog::_copy_request() {
String text = log->get_selected_text();
- if (text == "") {
+ if (text.is_empty()) {
text = log->get_text();
}
- if (text != "") {
+ if (!text.is_empty()) {
DisplayServer::get_singleton()->clipboard_set(text);
}
}
@@ -237,7 +237,7 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
// Only add the message to the log if it passes the filters.
bool filter_active = type_filter_map[p_message.type]->is_active();
String search_text = search_box->get_text();
- bool search_match = search_text == String() || p_message.text.findn(search_text) > -1;
+ bool search_match = search_text.is_empty() || p_message.text.findn(search_text) > -1;
if (!filter_active || !search_match) {
return;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6aaf0b063f..00a776ba4d 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -858,7 +858,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) {
continue;
}
- if (res->get_import_path() != String()) {
+ if (!res->get_import_path().is_empty()) {
// this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback
continue;
}
@@ -886,7 +886,7 @@ void EditorNode::_fs_changed() {
// FIXME: Move this to a cleaner location, it's hacky to do this is _fs_changed.
String export_error;
- if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) {
+ if (!export_defer.preset.is_empty() && !EditorFileSystem::get_singleton()->is_scanning()) {
String preset_name = export_defer.preset;
// Ensures export_project does not loop infinitely, because notifications may
// come during the export.
@@ -1006,7 +1006,7 @@ void EditorNode::_sources_changed(bool p_exist) {
_load_docks();
- if (defer_load_scene != "") {
+ if (!defer_load_scene.is_empty()) {
load_scene(defer_load_scene);
defer_load_scene = "";
}
@@ -1242,7 +1242,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
preferred.move_to_front(tres_element);
}
- if (p_at_path != String()) {
+ if (!p_at_path.is_empty()) {
file->set_current_dir(p_at_path);
if (p_resource->get_path().is_resource_file()) {
file->set_current_file(p_resource->get_path().get_file());
@@ -1254,7 +1254,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
file->set_current_file(String());
}
}
- } else if (p_resource->get_path() != "") {
+ } else if (!p_resource->get_path().is_empty()) {
file->set_current_path(p_resource->get_path());
if (extensions.size()) {
String ext = p_resource->get_path().get_extension().to_lower();
@@ -1676,7 +1676,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
return;
}
- if (scene->get_scene_file_path() != String() && _validate_scene_recursive(scene->get_scene_file_path(), scene)) {
+ if (!scene->get_scene_file_path().is_empty() && _validate_scene_recursive(scene->get_scene_file_path(), scene)) {
show_accept(TTR("This scene can't be saved because there is a cyclic instancing inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK"));
return;
}
@@ -1780,7 +1780,7 @@ void EditorNode::restart_editor() {
args.push_back("--path");
args.push_back(ProjectSettings::get_singleton()->get_resource_path());
args.push_back("-e");
- if (to_reopen != String()) {
+ if (!to_reopen.is_empty()) {
args.push_back(to_reopen);
}
@@ -1792,13 +1792,13 @@ void EditorNode::_save_all_scenes() {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene) {
- if (scene->get_scene_file_path() != "" && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) {
+ if (!scene->get_scene_file_path().is_empty() && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) {
if (i != editor_data.get_edited_scene()) {
_save_scene(scene->get_scene_file_path(), i);
} else {
_save_scene_with_preview(scene->get_scene_file_path());
}
- } else if (scene->get_scene_file_path() != "") {
+ } else if (!scene->get_scene_file_path().is_empty()) {
all_saved = false;
}
}
@@ -1818,7 +1818,7 @@ void EditorNode::_mark_unsaved_scenes() {
}
String path = node->get_scene_file_path();
- if (!(path == String() || FileAccess::exists(path))) {
+ if (!(path.is_empty() || FileAccess::exists(path))) {
if (i == editor_data.get_edited_scene()) {
set_current_version(-1);
} else {
@@ -2080,7 +2080,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
if (id != editor_history.get_current()) {
if (p_inspector_only) {
editor_history.add_object_inspector_only(id);
- } else if (p_property == "") {
+ } else if (p_property.is_empty()) {
editor_history.add_object(id);
} else {
editor_history.add_object(id, p_property);
@@ -2193,7 +2193,7 @@ void EditorNode::_edit_current() {
inspector_dock->update(nullptr);
}
- if (get_edited_scene() && get_edited_scene()->get_scene_file_path() != String()) {
+ if (get_edited_scene() && !get_edited_scene()->get_scene_file_path().is_empty()) {
String source_scene = get_edited_scene()->get_scene_file_path();
if (FileAccess::exists(source_scene + ".import")) {
editable_warning = TTR("This scene was imported, so changes to it won't be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
@@ -2315,10 +2315,8 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons")));
String run_filename;
- String args;
- bool skip_breakpoints;
- if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) {
+ if (p_current || (editor_data.get_edited_scene_root() && !p_custom.is_empty() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) {
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
@@ -2326,7 +2324,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
return;
}
- if (scene->get_scene_file_path() == "") {
+ if (scene->get_scene_file_path().is_empty()) {
current_option = -1;
_menu_option(FILE_SAVE_AS_SCENE);
// Set the option to save and run so when the dialog is accepted, the scene runs.
@@ -2336,11 +2334,11 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
}
run_filename = scene->get_scene_file_path();
- } else if (p_custom != "") {
+ } else if (!p_custom.is_empty()) {
run_filename = p_custom;
}
- if (run_filename == "") {
+ if (run_filename.is_empty()) {
// evidently, run the scene
if (!ensure_main_scene(false)) {
return;
@@ -2351,7 +2349,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (unsaved_cache) {
Node *scene = editor_data.get_edited_scene_root();
- if (scene && scene->get_scene_file_path() != "") { // Only autosave if there is a scene and if it has a path.
+ if (scene && !scene->get_scene_file_path().is_empty()) { // Only autosave if there is a scene and if it has a path.
_save_scene_with_preview(scene->get_scene_file_path());
}
}
@@ -2371,17 +2369,11 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
make_bottom_panel_item_visible(log);
}
- List<String> breakpoints;
- editor_data.get_editor_breakpoints(&breakpoints);
-
- args = ProjectSettings::get_singleton()->get("editor/run/main_run_args");
- skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints();
-
EditorDebuggerNode::get_singleton()->start();
- Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints);
+ Error error = editor_run.run(run_filename);
if (error != OK) {
EditorDebuggerNode::get_singleton()->stop();
- show_accept(TTR("Could not start subprocess!"), TTR("OK"));
+ show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));
return;
}
@@ -2389,7 +2381,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (p_current) {
play_scene_button->set_pressed(true);
play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
- } else if (p_custom != "") {
+ } else if (!p_custom.is_empty()) {
run_custom_filename = p_custom;
play_custom_scene_button->set_pressed(true);
play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
@@ -2509,7 +2501,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (scene_root) {
String scene_filename = scene_root->get_scene_file_path();
save_confirmation->get_ok_button()->set_text(TTR("Save & Close"));
- save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene"));
+ save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
save_confirmation->popup_centered();
break;
}
@@ -2527,7 +2519,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_SAVE_SCENE: {
int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing;
Node *scene = editor_data.get_edited_scene_root(scene_idx);
- if (scene && scene->get_scene_file_path() != "") {
+ if (scene && !scene->get_scene_file_path().is_empty()) {
if (DirAccess::exists(scene->get_scene_file_path().get_base_dir())) {
if (scene_idx != editor_data.get_edited_scene()) {
_save_scene_with_preview(scene->get_scene_file_path(), scene_idx);
@@ -2583,7 +2575,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
- if (scene->get_scene_file_path() != "") {
+ if (!scene->get_scene_file_path().is_empty()) {
String path = scene->get_scene_file_path();
file->set_current_path(path);
if (extensions.size()) {
@@ -2657,7 +2649,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!editor_data.get_undo_redo().undo()) {
log->add_message(TTR("Nothing to undo."), EditorLog::MSG_TYPE_EDITOR);
- } else if (action != "") {
+ } else if (!action.is_empty()) {
log->add_message(vformat(TTR("Undo: %s"), action), EditorLog::MSG_TYPE_EDITOR);
}
}
@@ -2684,7 +2676,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
String filename = scene->get_scene_file_path();
- if (filename == String()) {
+ if (filename.is_empty()) {
show_warning(TTR("Can't reload a scene that was never saved."));
break;
}
@@ -2754,7 +2746,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_SHOW_IN_FILESYSTEM: {
String path = editor_data.get_scene_path(editor_data.get_edited_scene());
- if (path != String()) {
+ if (!path.is_empty()) {
filesystem_dock->navigate_to_path(path);
}
} break;
@@ -3019,7 +3011,7 @@ void EditorNode::_discard_changes(const String &p_str) {
Node *scene = editor_data.get_edited_scene_root(tab_closing);
if (scene != nullptr) {
String scene_filename = scene->get_scene_file_path();
- if (scene_filename != "") {
+ if (!scene_filename.is_empty()) {
previous_scenes.push_back(scene_filename);
}
}
@@ -3146,7 +3138,7 @@ void EditorNode::_editor_select(int p_which) {
}
void EditorNode::select_editor_by_name(const String &p_name) {
- ERR_FAIL_COND(p_name == "");
+ ERR_FAIL_COND(p_name.is_empty());
for (int i = 0; i < main_editor_buttons.size(); i++) {
if (main_editor_buttons[i]->get_text() == p_name) {
@@ -4244,7 +4236,6 @@ void EditorNode::_dock_make_float() {
Size2 dock_size = dock->get_size() + borders * 2; // remember size
Point2 dock_screen_pos = dock->get_global_position() + get_tree()->get_root()->get_position() - borders;
- print_line("dock pos: " + dock->get_global_position() + " window pos: " + get_tree()->get_root()->get_position());
int dock_index = dock->get_index();
dock_slot[dock_popup_selected]->remove_child(dock);
@@ -4500,13 +4491,13 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p
String names;
for (int j = 0; j < dock_slot[i]->get_tab_count(); j++) {
String name = dock_slot[i]->get_tab_control(j)->get_name();
- if (names != "") {
+ if (!names.is_empty()) {
names += ",";
}
names += name;
}
- if (names != "") {
+ if (!names.is_empty()) {
p_layout->set_value(p_section, "dock_" + itos(i + 1), names);
}
}
@@ -4531,7 +4522,7 @@ void EditorNode::_save_open_scenes_to_config(Ref<ConfigFile> p_layout, const Str
Array scenes;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
String path = editor_data.get_scene_path(i);
- if (path == "") {
+ if (path.is_empty()) {
continue;
}
scenes.push_back(path);
@@ -4798,7 +4789,7 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
pick_main_scene->set_meta("from_native", p_from_native); // whether from play button or native run
String main_scene = GLOBAL_DEF("application/run/main_scene", "");
- if (main_scene == "") {
+ if (main_scene.is_empty()) {
current_option = -1;
pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
pick_main_scene->popup_centered();
@@ -4861,7 +4852,7 @@ bool EditorNode::is_run_playing() const {
String EditorNode::get_run_playing_scene() const {
String run_filename = editor_run.get_running_scene();
- if (run_filename == "" && is_run_playing()) {
+ if (run_filename.is_empty() && is_run_playing()) {
run_filename = GLOBAL_DEF("application/run/main_scene", ""); // Must be the main scene then.
}
@@ -4987,7 +4978,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) {
: editor_data.get_scene_version(p_tab) != 0;
if (unsaved) {
save_confirmation->get_ok_button()->set_text(TTR("Save & Close"));
- save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_scene_file_path() != "" ? scene->get_scene_file_path() : "unsaved scene"));
+ save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene->get_scene_file_path().is_empty() ? scene->get_scene_file_path() : "unsaved scene"));
save_confirmation->popup_centered();
} else {
_discard_changes();
@@ -5007,7 +4998,7 @@ void EditorNode::_scene_tab_hovered(int p_tab) {
tab_preview_panel->hide();
} else {
String path = editor_data.get_scene_path(p_tab);
- if (path != String()) {
+ if (!path.is_empty()) {
EditorResourcePreview::get_singleton()->queue_resource_preview(path, this, "_thumbnail_done", p_tab);
}
}
@@ -5060,7 +5051,8 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), FILE_CLOSE_RIGHT);
scene_tabs_context_menu->add_item(TTR("Close All Tabs"), FILE_CLOSE_ALL);
}
- scene_tabs_context_menu->set_position(mb->get_global_position());
+ scene_tabs_context_menu->set_position(scene_tabs->get_screen_position() + mb->get_position());
+ scene_tabs_context_menu->reset_size();
scene_tabs_context_menu->popup();
}
if (mb->get_button_index() == MouseButton::WHEEL_UP && mb->is_pressed()) {
@@ -5315,7 +5307,7 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
drag_control->add_child(drag_preview);
if (p_res->get_path().is_resource_file()) {
label->set_text(p_res->get_path().get_file());
- } else if (p_res->get_name() != "") {
+ } else if (!p_res->get_name().is_empty()) {
label->set_text(p_res->get_name());
} else {
label->set_text(p_res->get_class());
@@ -5454,7 +5446,7 @@ void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, Str
sub_dir->list_dir_begin();
String next_file = sub_dir->get_next();
- while (next_file != "") {
+ while (!next_file.is_empty()) {
if (next_file == "." || next_file == "..") {
next_file = sub_dir->get_next();
continue;
@@ -6158,7 +6150,7 @@ EditorNode::EditorNode() {
Label *dock_label = memnew(Label);
dock_label->set_text(TTR("Dock Position"));
dock_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- dock_label->set_align(Label::ALIGN_CENTER);
+ dock_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
dock_hb->add_child(dock_label);
dock_tab_move_right = memnew(Button);
@@ -6198,7 +6190,7 @@ EditorNode::EditorNode() {
dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
dock_slot[i]->set_popup(dock_select_popup);
dock_slot[i]->connect("pre_popup_pressed", callable_mp(this, &EditorNode::_dock_pre_popup), varray(i));
- dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
+ dock_slot[i]->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
dock_slot[i]->set_drag_to_rearrange_enabled(true);
dock_slot[i]->set_tabs_rearrange_group(1);
dock_slot[i]->connect("tab_changed", callable_mp(this, &EditorNode::_dock_tab_changed));
@@ -6238,7 +6230,7 @@ EditorNode::EditorNode() {
scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles")));
scene_tabs->set_select_with_rmb(true);
scene_tabs->add_tab("unsaved");
- scene_tabs->set_tab_align(TabBar::ALIGN_LEFT);
+ scene_tabs->set_tab_alignment(TabBar::ALIGNMENT_LEFT);
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
scene_tabs->set_drag_to_rearrange_enabled(true);
@@ -7018,7 +7010,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(PhysicalBone3DEditorPlugin(this)));
add_editor_plugin(memnew(MeshEditorPlugin(this)));
add_editor_plugin(memnew(MaterialEditorPlugin(this)));
- add_editor_plugin(memnew(GPUParticlesCollisionSDFEditorPlugin(this)));
+ add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin(this)));
add_editor_plugin(memnew(InputEventEditorPlugin(this)));
add_editor_plugin(memnew(SubViewportPreviewEditorPlugin(this)));
add_editor_plugin(memnew(TextControlEditorPlugin(this)));
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index f3b3eedccc..b6797825b0 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -130,14 +130,14 @@ void EditorPath::update_path() {
name = r->get_name();
}
- if (name == "") {
+ if (name.is_empty()) {
name = r->get_class();
}
} else if (obj->is_class("EditorDebuggerRemoteObject")) {
name = obj->call("get_title");
} else if (Object::cast_to<Node>(obj)) {
name = Object::cast_to<Node>(obj)->get_name();
- } else if (Object::cast_to<Resource>(obj) && Object::cast_to<Resource>(obj)->get_name() != "") {
+ } else if (Object::cast_to<Resource>(obj) && !Object::cast_to<Resource>(obj)->get_name().is_empty()) {
name = Object::cast_to<Resource>(obj)->get_name();
} else {
name = obj->get_class();
@@ -211,7 +211,7 @@ EditorPath::EditorPath(EditorHistory *p_history) {
current_object_label = memnew(Label);
current_object_label->set_clip_text(true);
- current_object_label->set_align(Label::ALIGN_LEFT);
+ current_object_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
current_object_label->set_h_size_flags(SIZE_EXPAND_FILL);
main_hb->add_child(current_object_label);
diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp
index 5b48cc2638..e747cdc29e 100644
--- a/editor/editor_paths.cpp
+++ b/editor/editor_paths.cpp
@@ -131,7 +131,7 @@ EditorPaths::EditorPaths() {
}
}
- paths_valid = (data_path != "" && config_path != "" && cache_path != "");
+ paths_valid = (!data_path.is_empty() && !config_path.is_empty() && !cache_path.is_empty());
ERR_FAIL_COND_MSG(!paths_valid, "Editor data, config, or cache paths are invalid.");
// Validate or create each dir and its relevant subdirectories.
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 61c01993ae..9682a847ca 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -166,6 +166,10 @@ void EditorInterface::edit_node(Node *p_node) {
EditorNode::get_singleton()->edit_node(p_node);
}
+void EditorInterface::edit_script(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus) {
+ ScriptEditor::get_singleton()->edit(p_script, p_line, p_col, p_grab_focus);
+}
+
void EditorInterface::open_scene_from_path(const String &scene_path) {
if (EditorNode::get_singleton()->is_changing_scene()) {
return;
@@ -291,7 +295,7 @@ Error EditorInterface::save_scene() {
if (!get_edited_scene_root()) {
return ERR_CANT_CREATE;
}
- if (get_edited_scene_root()->get_scene_file_path() == String()) {
+ if (get_edited_scene_root()->get_scene_file_path().is_empty()) {
return ERR_CANT_CREATE;
}
@@ -326,6 +330,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource);
ClassDB::bind_method(D_METHOD("edit_node", "node"), &EditorInterface::edit_node);
+ ClassDB::bind_method(D_METHOD("edit_script", "script", "line", "column", "grab_focus"), &EditorInterface::edit_script, DEFVAL(-1), DEFVAL(0), DEFVAL(true));
ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path);
ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path);
ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 278059f8c4..a49e1bf229 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -74,6 +74,7 @@ public:
Control *get_editor_main_control();
void edit_resource(const Ref<Resource> &p_resource);
void edit_node(Node *p_node);
+ void edit_script(const Ref<Script> &p_script, int p_line = -1, int p_col = 0, bool p_grab_focus = true);
void open_scene_from_path(const String &scene_path);
void reload_scene_from_path(const String &scene_path);
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index aa313f0c50..6aeede78b6 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -165,7 +165,7 @@ Vector<String> EditorPluginSettings::_get_plugins(const String &p_dir) {
Vector<String> plugins;
da->list_dir_begin();
- for (String path = da->get_next(); path != String(); path = da->get_next()) {
+ for (String path = da->get_next(); !path.is_empty(); path = da->get_next()) {
if (path[0] == '.' || !da->current_is_dir()) {
continue;
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index e48679cad7..07df2cedd5 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -380,7 +380,7 @@ void EditorPropertyPath::_path_pressed() {
dialog->set_file_mode(save_mode ? EditorFileDialog::FILE_MODE_SAVE_FILE : EditorFileDialog::FILE_MODE_OPEN_FILE);
for (int i = 0; i < extensions.size(); i++) {
String e = extensions[i].strip_edges();
- if (e != String()) {
+ if (!e.is_empty()) {
dialog->add_filter(extensions[i].strip_edges());
}
}
@@ -706,7 +706,7 @@ void EditorPropertyFlags::setup(const Vector<String> &p_options) {
bool first = true;
for (int i = 0; i < p_options.size(); i++) {
String option = p_options[i].strip_edges();
- if (option != "") {
+ if (!option.is_empty()) {
CheckBox *cb = memnew(CheckBox);
cb->set_text(option);
cb->set_clip_text(true);
@@ -832,7 +832,7 @@ public:
update();
} else if (expand_hovered) {
expanded = !expanded;
- minimum_size_changed();
+ update_minimum_size();
update();
}
}
@@ -891,7 +891,7 @@ public:
Vector2 offset;
offset.y = rect2.size.y * 0.75;
- draw_string(font, rect2.position + offset, itos(layer_index + 1), HALIGN_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color);
+ draw_string(font, rect2.position + offset, itos(layer_index + 1), HORIZONTAL_ALIGNMENT_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color);
ofs.x += bsize + 1;
@@ -935,7 +935,7 @@ public:
}
if ((expansion_rows != prev_expansion_rows) && expanded) {
- minimum_size_changed();
+ update_minimum_size();
}
if ((expansion_rows == 0) && (layer_index == layer_count)) {
@@ -1055,7 +1055,7 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
name = ProjectSettings::get_singleton()->get(basename + vformat("/layer_%d", i + 1));
}
- if (name == "") {
+ if (name.is_empty()) {
name = vformat(TTR("Layer %d"), i + 1);
}
@@ -1186,7 +1186,7 @@ void EditorPropertyObjectID::_edit_pressed() {
void EditorPropertyObjectID::update_property() {
String type = base_type;
- if (type == "") {
+ if (type.is_empty()) {
type = "Object";
}
@@ -1283,7 +1283,8 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
}
if (mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) {
- preset->set_position(easing_draw->get_screen_transform().xform(mb->get_position()));
+ preset->set_position(easing_draw->get_screen_position() + mb->get_position());
+ preset->reset_size();
preset->popup();
// Ensure the easing doesn't appear as being dragged
@@ -1382,7 +1383,7 @@ void EditorPropertyEasing::_draw_easing() {
} else {
decimals = 1;
}
- f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), TS->format_number(rtos(exp).pad_decimals(decimals)), HALIGN_LEFT, -1, font_size, font_color);
+ f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), TS->format_number(rtos(exp).pad_decimals(decimals)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
}
void EditorPropertyEasing::update_property() {
@@ -3064,7 +3065,7 @@ void EditorPropertyResource::update_property() {
if (res.is_valid() && get_edited_object()->editor_is_section_unfolded(get_edited_property())) {
if (!sub_inspector) {
sub_inspector = memnew(EditorInspector);
- sub_inspector->set_enable_v_scroll(false);
+ sub_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
sub_inspector->set_use_doc_hints(true);
sub_inspector->set_sub_inspector(true);
@@ -3228,7 +3229,7 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri
}
}
- if ((hint.radians || degrees) && hint.suffix == String()) {
+ if ((hint.radians || degrees) && hint.suffix.is_empty()) {
hint.suffix = U"\u00B0";
}
@@ -3513,10 +3514,10 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
} break;
case Variant::NODE_PATH: {
EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath);
- if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
+ if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !p_hint_text.is_empty()) {
editor->setup(p_hint_text, Vector<StringName>(), (p_usage & PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT));
}
- if (p_hint == PROPERTY_HINT_NODE_PATH_VALID_TYPES && p_hint_text != String()) {
+ if (p_hint == PROPERTY_HINT_NODE_PATH_VALID_TYPES && !p_hint_text.is_empty()) {
Vector<String> types = p_hint_text.split(",", false);
Vector<StringName> sn = Variant(types); //convert via variant
editor->setup(NodePath(), sn, (p_usage & PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT));
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 0f59c8281f..858de7fb78 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -431,7 +431,7 @@ bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
// When the subtype is of type Object, an additional subtype may be specified in the hint string
// (e.g. Resource, Texture2D, ShaderMaterial, etc). We want the allowed type to be that, not just "Object".
- if (subtype == Variant::OBJECT && subtype_hint_string != "") {
+ if (subtype == Variant::OBJECT && !subtype_hint_string.is_empty()) {
allowed_type = subtype_hint_string;
}
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 0703677dc8..6a6634d7e5 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -52,7 +52,7 @@ void EditorResourcePicker::_update_resource() {
} else {
assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object"));
- if (edited_resource->get_name() != String()) {
+ if (!edited_resource->get_name().is_empty()) {
assign_button->set_text(edited_resource->get_name());
} else if (edited_resource->get_path().is_resource_file()) {
assign_button->set_text(edited_resource->get_path().get_file());
@@ -113,7 +113,7 @@ void EditorResourcePicker::_file_selected(const String &p_path) {
RES loaded_resource = ResourceLoader::load(p_path);
ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'.");
- if (base_type != "") {
+ if (!base_type.is_empty()) {
bool any_type_matches = false;
for (int i = 0; i < base_type.get_slice_count(","); i++) {
@@ -180,7 +180,7 @@ void EditorResourcePicker::_update_menu_items() {
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
bool paste_valid = false;
if (cb.is_valid()) {
- if (base_type == "") {
+ if (base_type.is_empty()) {
paste_valid = true;
} else {
for (int i = 0; i < base_type.get_slice_count(","); i++) {
@@ -391,7 +391,7 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) {
}
// By default provide generic "New ..." options.
- if (base_type != "") {
+ if (!base_type.is_empty()) {
int idx = 0;
Set<String> allowed_types;
@@ -571,7 +571,7 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const {
String file = files[0];
String file_type = EditorFileSystem::get_singleton()->get_file_type(file);
- if (file_type != "" && _is_type_valid(file_type, allowed_types)) {
+ if (!file_type.is_empty() && _is_type_valid(file_type, allowed_types)) {
return true;
}
}
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index e9c0b40268..15fc3b1db3 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -141,7 +141,7 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
type = ResourceLoader::get_resource_type(p_item.path);
}
- if (type == "") {
+ if (type.is_empty()) {
r_texture = Ref<ImageTexture>();
r_small_texture = Ref<ImageTexture>();
return; //could not guess type
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 0a77a8b0bb..92dae89b33 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -31,6 +31,7 @@
#include "editor_run.h"
#include "core/config/project_settings.h"
+#include "editor/editor_node.h"
#include "editor_settings.h"
#include "servers/display_server.h"
@@ -42,20 +43,17 @@ String EditorRun::get_running_scene() const {
return running_scene;
}
-Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints) {
+Error EditorRun::run(const String &p_scene) {
List<String> args;
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- String remote_host = EditorSettings::get_singleton()->get("network/debug/remote_host");
- int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
-
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
args.push_back("--path");
args.push_back(resource_path.replace(" ", "%20"));
}
args.push_back("--remote-debug");
- args.push_back("tcp://" + remote_host + ":" + String::num(remote_port));
+ args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri());
args.push_back("--allow_focus_steal_pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));
@@ -162,10 +160,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
} break;
}
- if (p_breakpoints.size()) {
+ List<String> breakpoints;
+ EditorNode::get_editor_data().get_editor_breakpoints(&breakpoints);
+
+ if (!breakpoints.is_empty()) {
args.push_back("--breakpoints");
String bpoints;
- for (const List<String>::Element *E = p_breakpoints.front(); E; E = E->next()) {
+ for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
bpoints += E->get().replace(" ", "%20");
if (E->next()) {
bpoints += ",";
@@ -175,30 +176,31 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
args.push_back(bpoints);
}
- if (p_skip_breakpoints) {
+ if (EditorDebuggerNode::get_singleton()->is_skip_breakpoints()) {
args.push_back("--skip-breakpoints");
}
- if (p_scene != "") {
+ if (!p_scene.is_empty()) {
args.push_back(p_scene);
}
String exec = OS::get_singleton()->get_executable_path();
- if (p_custom_args != "") {
+ const String raw_custom_args = ProjectSettings::get_singleton()->get("editor/run/main_run_args");
+ if (!raw_custom_args.is_empty()) {
// Allow the user to specify a command to run, similar to Steam's launch options.
// In this case, Godot will no longer be run directly; it's up to the underlying command
// to run it. For instance, this can be used on Linux to force a running project
// to use Optimus using `prime-run` or similar.
// Example: `prime-run %command% --time-scale 0.5`
- const int placeholder_pos = p_custom_args.find("%command%");
+ const int placeholder_pos = raw_custom_args.find("%command%");
Vector<String> custom_args;
if (placeholder_pos != -1) {
// Prepend executable-specific custom arguments.
// If nothing is placed before `%command%`, behave as if no placeholder was specified.
- Vector<String> exec_args = p_custom_args.substr(0, placeholder_pos).split(" ", false);
+ Vector<String> exec_args = raw_custom_args.substr(0, placeholder_pos).split(" ", false);
if (exec_args.size() >= 1) {
exec = exec_args[0];
exec_args.remove_at(0);
@@ -214,13 +216,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
// Append Godot-specific custom arguments.
- custom_args = p_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false);
+ custom_args = raw_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false);
for (int i = 0; i < custom_args.size(); i++) {
args.push_back(custom_args[i].replace(" ", "%20"));
}
} else {
// Append Godot-specific custom arguments.
- custom_args = p_custom_args.split(" ", false);
+ custom_args = raw_custom_args.split(" ", false);
for (int i = 0; i < custom_args.size(); i++) {
args.push_back(custom_args[i].replace(" ", "%20"));
}
@@ -242,7 +244,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
status = STATUS_PLAY;
- if (p_scene != "") {
+ if (!p_scene.is_empty()) {
running_scene = p_scene;
}
diff --git a/editor/editor_run.h b/editor/editor_run.h
index d6cf3fed71..3bfe28e1ad 100644
--- a/editor/editor_run.h
+++ b/editor/editor_run.h
@@ -50,7 +50,7 @@ private:
public:
Status get_status() const;
String get_running_scene() const;
- Error run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints = false);
+ Error run(const String &p_scene);
void run_native_notify() { status = STATUS_PLAY; }
void stop();
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index 751cc7a574..c7a9171709 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -45,7 +45,7 @@ class SectionedInspectorFilter : public Object {
}
String name = p_name;
- if (section != "") {
+ if (!section.is_empty()) {
name = section + "/" + name;
}
@@ -60,7 +60,7 @@ class SectionedInspectorFilter : public Object {
}
String name = p_name;
- if (section != "") {
+ if (!section.is_empty()) {
name = section + "/" + name;
}
@@ -155,7 +155,7 @@ String SectionedInspector::get_current_section() const {
String SectionedInspector::get_full_item_path(const String &p_item) {
String base = get_current_section();
- if (base != "") {
+ if (!base.is_empty()) {
return base + "/" + p_item;
} else {
return p_item;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 613e0ba7a0..95248b22b5 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -389,14 +389,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
best = locale;
}
- if (best == String() && host_lang.begins_with(locale)) {
+ if (best.is_empty() && host_lang.begins_with(locale)) {
best = locale;
}
etl++;
}
- if (best == String()) {
+ if (best.is_empty()) {
best = "en";
}
@@ -989,7 +989,7 @@ void EditorSettings::setup_network() {
if (ip == current) {
selected = ip;
}
- if (hint != "") {
+ if (!hint.is_empty()) {
hint += ",";
}
hint += ip;
@@ -1008,7 +1008,7 @@ void EditorSettings::save() {
return;
}
- if (singleton->config_file_path == "") {
+ if (singleton->config_file_path.is_empty()) {
ERR_PRINT("Cannot save EditorSettings config, no valid path");
return;
}
@@ -1218,7 +1218,7 @@ void EditorSettings::load_favorites() {
FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ);
if (f) {
String line = f->get_line().strip_edges();
- while (line != "") {
+ while (!line.is_empty()) {
favorites.push_back(line);
line = f->get_line().strip_edges();
}
@@ -1228,7 +1228,7 @@ void EditorSettings::load_favorites() {
f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::READ);
if (f) {
String line = f->get_line().strip_edges();
- while (line != "") {
+ while (!line.is_empty()) {
recent_dirs.push_back(line);
line = f->get_line().strip_edges();
}
@@ -1252,7 +1252,7 @@ void EditorSettings::list_text_editor_themes() {
List<String> custom_themes;
d->list_dir_begin();
String file = d->get_next();
- while (file != String()) {
+ while (!file.is_empty()) {
if (file.get_extension() == "tet" && !_is_default_text_editor_theme(file.get_basename().to_lower())) {
custom_themes.push_back(file.get_basename());
}
@@ -1371,7 +1371,7 @@ Vector<String> EditorSettings::get_script_templates(const String &p_extension, c
if (d) {
d->list_dir_begin();
String file = d->get_next();
- while (file != String()) {
+ while (!file.is_empty()) {
if (file.get_extension() == p_extension) {
templates.push_back(file.get_basename());
}
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index f07a5ab523..c0fa259deb 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -262,9 +262,9 @@ void EditorSpinSlider::_update_value_input_stylebox() {
// The margin values below were determined by empirical testing.
if (is_layout_rtl()) {
stylebox->set_default_margin(SIDE_LEFT, 0);
- stylebox->set_default_margin(SIDE_RIGHT, (get_label() != String() ? 23 : 16) * EDSCALE);
+ stylebox->set_default_margin(SIDE_RIGHT, (!get_label().is_empty() ? 23 : 16) * EDSCALE);
} else {
- stylebox->set_default_margin(SIDE_LEFT, (get_label() != String() ? 23 : 16) * EDSCALE);
+ stylebox->set_default_margin(SIDE_LEFT, (!get_label().is_empty() ? 23 : 16) * EDSCALE);
stylebox->set_default_margin(SIDE_RIGHT, 0);
}
@@ -308,7 +308,7 @@ void EditorSpinSlider::_draw_spin_slider() {
lc = fc;
}
- if (flat && label != String()) {
+ if (flat && !label.is_empty()) {
Color label_bg_color = get_theme_color(SNAME("dark_color_3"), SNAME("Editor"));
if (rtl) {
draw_rect(Rect2(Vector2(size.width - (sb->get_offset().x * 2 + label_width), 0), Vector2(sb->get_offset().x * 2 + label_width, size.height)), label_bg_color);
@@ -323,9 +323,9 @@ void EditorSpinSlider::_draw_spin_slider() {
}
if (rtl) {
- draw_string(font, Vector2(Math::round(size.width - sb->get_offset().x - label_width), vofs), label, HALIGN_RIGHT, -1, font_size, lc * Color(1, 1, 1, 0.5));
+ draw_string(font, Vector2(Math::round(size.width - sb->get_offset().x - label_width), vofs), label, HORIZONTAL_ALIGNMENT_RIGHT, -1, font_size, lc * Color(1, 1, 1, 0.5));
} else {
- draw_string(font, Vector2(Math::round(sb->get_offset().x), vofs), label, HALIGN_LEFT, -1, font_size, lc * Color(1, 1, 1, 0.5));
+ draw_string(font, Vector2(Math::round(sb->get_offset().x), vofs), label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, lc * Color(1, 1, 1, 0.5));
}
int suffix_start = numstr.length();
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 637394d136..7bbac11754 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1553,7 +1553,7 @@ Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) {
Ref<Theme> theme = create_editor_theme(p_theme);
const String custom_theme_path = EditorSettings::get_singleton()->get("interface/theme/custom_theme");
- if (custom_theme_path != "") {
+ if (!custom_theme_path.is_empty()) {
Ref<Theme> custom_theme = ResourceLoader::load(custom_theme_path);
if (custom_theme.is_valid()) {
theme->merge_with(custom_theme);
diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp
index a998ec7e5b..5a37d882c2 100644
--- a/editor/editor_zoom_widget.cpp
+++ b/editor/editor_zoom_widget.cpp
@@ -183,7 +183,7 @@ EditorZoomWidget::EditorZoomWidget() {
zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KeyModifierMask::CMD | Key::KEY_0));
zoom_reset->set_shortcut_context(this);
zoom_reset->set_focus_mode(FOCUS_NONE);
- zoom_reset->set_text_align(Button::TextAlign::ALIGN_CENTER);
+ zoom_reset->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
// Prevent the button's size from changing when the text size changes
zoom_reset->set_custom_minimum_size(Size2(75 * EDSCALE, 0));
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index cb88e9d75e..d9613687f1 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -53,7 +53,7 @@ void ExportTemplateManager::_update_template_status() {
da->list_dir_begin();
if (err == OK) {
String c = da->get_next();
- while (c != String()) {
+ while (!c.is_empty()) {
if (da->current_is_dir() && !c.begins_with(".")) {
templates.insert(c);
}
@@ -424,7 +424,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
ret = unzGoToNextFile(pkg);
}
- if (version == String()) {
+ if (version.is_empty()) {
EditorNode::get_singleton()->show_warning(TTR("No version.txt found inside the export templates file."));
unzClose(pkg);
return false;
@@ -827,7 +827,7 @@ ExportTemplateManager::ExportTemplateManager() {
current_missing_label->set_theme_type_variation("HeaderSmall");
current_missing_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- current_missing_label->set_align(Label::ALIGN_RIGHT);
+ current_missing_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
current_missing_label->set_text(TTR("Export templates are missing. Download them or install from a file."));
current_hb->add_child(current_missing_label);
@@ -835,7 +835,7 @@ ExportTemplateManager::ExportTemplateManager() {
current_installed_label = memnew(Label);
current_installed_label->set_theme_type_variation("HeaderSmall");
current_installed_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- current_installed_label->set_align(Label::ALIGN_RIGHT);
+ current_installed_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
current_installed_label->set_text(TTR("Export templates are installed and ready to be used."));
current_hb->add_child(current_installed_label);
current_installed_label->hide();
@@ -909,7 +909,7 @@ ExportTemplateManager::ExportTemplateManager() {
}
HBoxContainer *install_file_hb = memnew(HBoxContainer);
- install_file_hb->set_alignment(BoxContainer::ALIGN_END);
+ install_file_hb->set_alignment(BoxContainer::ALIGNMENT_END);
install_options_vb->add_child(install_file_hb);
install_file_button = memnew(Button);
diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index 8f019a95fd..66bcbb4d5d 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -88,7 +88,7 @@ void EditorFileServer::_subthread_start(void *s) {
ERR_FAIL();
}
} else {
- if (cd->efs->password != "") {
+ if (!cd->efs->password.is_empty()) {
encode_uint32(ERR_INVALID_DATA, buf4);
cd->connection->put_data(buf4, 4);
OS::get_singleton()->delay_usec(1000000);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index f40a048b75..72fc9fbc6e 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -46,6 +46,7 @@
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
#include "servers/display_server.h"
+#include "shader_create_dialog.h"
Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) {
Ref<Texture2D> file_icon;
@@ -63,7 +64,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
// Create a tree item for the subdirectory.
TreeItem *subdirectory_item = tree->create_item(p_parent);
String dname = p_dir->get_name();
- if (dname == "") {
+ if (dname.is_empty()) {
dname = "res://";
}
@@ -922,7 +923,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->select(item_index, false);
}
- if (!p_keep_selection && file != "" && fname == file) {
+ if (!p_keep_selection && !file.is_empty() && fname == file) {
files->select(item_index, true);
files->ensure_current_is_visible();
}
@@ -1669,7 +1670,7 @@ Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> select
selected_strings.sort_custom<NaturalNoCaseComparator>();
String last_path = "";
for (int i = 0; i < selected_strings.size(); i++) {
- if (last_path != "" && selected_strings[i].begins_with(last_path)) {
+ if (!last_path.is_empty() && selected_strings[i].begins_with(last_path)) {
selected_strings.remove_at(i);
i--;
}
@@ -1967,6 +1968,22 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
}
void FileSystemDock::_resource_created() {
+ String fpath = path;
+ if (!fpath.ends_with("/")) {
+ fpath = fpath.get_base_dir();
+ }
+
+ String type_name = new_resource_dialog->get_selected_type();
+ if (type_name == "Shader") {
+ make_shader_dialog->config(fpath.plus_file("new_shader"), false, false, 0);
+ make_shader_dialog->popup_centered();
+ return;
+ } else if (type_name == "VisualShader") {
+ make_shader_dialog->config(fpath.plus_file("new_shader"), false, false, 1);
+ make_shader_dialog->popup_centered();
+ return;
+ }
+
Variant c = new_resource_dialog->instance_selected();
ERR_FAIL_COND(!c);
@@ -1982,12 +1999,6 @@ void FileSystemDock::_resource_created() {
}
editor->push_item(r);
-
- String fpath = path;
- if (!fpath.ends_with("/")) {
- fpath = fpath.get_base_dir();
- }
-
editor->save_resource_as(RES(r), fpath);
}
@@ -2005,7 +2016,7 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from
tree_search_box->set_text(searched_string);
}
- bool unfold_path = (p_text == String() && path != String());
+ bool unfold_path = (p_text.is_empty() && !path.is_empty());
switch (display_mode) {
case DISPLAY_MODE_TREE_ONLY: {
_update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>(), false, false, unfold_path);
@@ -2510,6 +2521,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
tree_popup->reset_size();
_file_and_folders_fill_popup(tree_popup, paths);
tree_popup->set_position(tree->get_screen_position() + p_pos);
+ tree_popup->reset_size();
tree_popup->popup();
}
}
@@ -2524,7 +2536,8 @@ void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) {
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->set_position(tree->get_global_position() + p_pos);
+ tree_popup->set_position(tree->get_screen_position() + p_pos);
+ tree_popup->reset_size();
tree_popup->popup();
}
@@ -2549,9 +2562,9 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
// Popup.
if (!paths.is_empty()) {
file_list_popup->clear();
- file_list_popup->reset_size();
_file_and_folders_fill_popup(file_list_popup, paths, searched_string.length() == 0);
- file_list_popup->set_position(files->get_global_position() + p_pos);
+ file_list_popup->set_position(files->get_screen_position() + p_pos);
+ file_list_popup->reset_size();
file_list_popup->popup();
}
}
@@ -2572,7 +2585,8 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
file_list_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE);
file_list_popup->add_separator();
file_list_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER);
- file_list_popup->set_position(files->get_global_position() + p_pos);
+ file_list_popup->set_position(files->get_screen_position() + p_pos);
+ file_list_popup->reset_size();
file_list_popup->popup();
}
@@ -2651,7 +2665,7 @@ void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &f
DirAccess *da = DirAccess::open(p_path);
da->list_dir_begin();
String n = da->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n != "." && n != ".." && !n.ends_with(".import")) {
String npath = p_path + n + (da->current_is_dir() ? "/" : "");
_get_imported_files(npath, files);
@@ -2706,7 +2720,7 @@ void FileSystemDock::_update_import_dock() {
if (cf->has_section_key("remap", "type")) {
type = cf->get_value("remap", "type");
}
- if (import_type == "") {
+ if (import_type.is_empty()) {
import_type = type;
} else if (import_type != type) {
// All should be the same type.
@@ -2922,7 +2936,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
Label *slabel = memnew(Label);
slabel->set_text(TTR("Scanning Files,\nPlease Wait..."));
- slabel->set_align(Label::ALIGN_CENTER);
+ slabel->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
scanning_vb->add_child(slabel);
scanning_progress = memnew(ProgressBar);
@@ -2997,6 +3011,9 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
make_script_dialog->set_title(TTR("Create Script"));
add_child(make_script_dialog);
+ make_shader_dialog = memnew(ShaderCreateDialog);
+ add_child(make_shader_dialog);
+
new_resource_dialog = memnew(CreateDialog);
add_child(new_resource_dialog);
new_resource_dialog->set_base_type("Resource");
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 7c3851b94f..34b445f1b3 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -54,6 +54,7 @@
#include "script_create_dialog.h"
class EditorNode;
+class ShaderCreateDialog;
class FileSystemDock : public VBoxContainer {
GDCLASS(FileSystemDock, VBoxContainer);
@@ -158,6 +159,7 @@ private:
LineEdit *make_scene_dialog_text;
ConfirmationDialog *overwrite_dialog;
ScriptCreateDialog *make_script_dialog;
+ ShaderCreateDialog *make_shader_dialog;
CreateDialog *new_resource_dialog;
bool always_show_folders;
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 56356ff25b..9f7abfa19d 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -114,7 +114,7 @@ void FindInFiles::_notification(int p_notification) {
}
void FindInFiles::start() {
- if (_pattern == "") {
+ if (_pattern.is_empty()) {
print_verbose("Nothing to search, pattern is empty");
emit_signal(SNAME(SIGNAL_FINISHED));
return;
@@ -224,7 +224,7 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
for (int i = 0; i < 1000; ++i) {
String file = dir->get_next();
- if (file == "") {
+ if (file.is_empty()) {
break;
}
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index f01c7f50f7..788c7dc029 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -227,7 +227,7 @@ void GroupDialog::_group_renamed() {
}
}
- if (name == "") {
+ if (name.is_empty()) {
renamed_group->set_text(0, selected_group);
error->set_text(TTR("Invalid group name."));
error->popup_centered();
@@ -544,8 +544,8 @@ GroupDialog::GroupDialog() {
group_empty->set_theme_type_variation("HeaderSmall");
group_empty->set_text(TTR("Empty groups will be automatically removed."));
- group_empty->set_valign(Label::VALIGN_CENTER);
- group_empty->set_align(Label::ALIGN_CENTER);
+ group_empty->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ group_empty->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
group_empty->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
group_empty->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
nodes_to_remove->add_child(group_empty);
diff --git a/editor/icons/GPUParticlesAttractorBox.svg b/editor/icons/GPUParticlesAttractorBox3D.svg
index 7a2ee7a6b9..7a2ee7a6b9 100644
--- a/editor/icons/GPUParticlesAttractorBox.svg
+++ b/editor/icons/GPUParticlesAttractorBox3D.svg
diff --git a/editor/icons/GPUParticlesAttractorSphere.svg b/editor/icons/GPUParticlesAttractorSphere3D.svg
index 2215331a18..2215331a18 100644
--- a/editor/icons/GPUParticlesAttractorSphere.svg
+++ b/editor/icons/GPUParticlesAttractorSphere3D.svg
diff --git a/editor/icons/GPUParticlesAttractorVectorField.svg b/editor/icons/GPUParticlesAttractorVectorField3D.svg
index 87b2b21804..87b2b21804 100644
--- a/editor/icons/GPUParticlesAttractorVectorField.svg
+++ b/editor/icons/GPUParticlesAttractorVectorField3D.svg
diff --git a/editor/icons/GPUParticlesCollisionBox.svg b/editor/icons/GPUParticlesCollisionBox3D.svg
index 4f7325d086..4f7325d086 100644
--- a/editor/icons/GPUParticlesCollisionBox.svg
+++ b/editor/icons/GPUParticlesCollisionBox3D.svg
diff --git a/editor/icons/GPUParticlesCollisionHeightField.svg b/editor/icons/GPUParticlesCollisionHeightField3D.svg
index 8bdc98a84b..8bdc98a84b 100644
--- a/editor/icons/GPUParticlesCollisionHeightField.svg
+++ b/editor/icons/GPUParticlesCollisionHeightField3D.svg
diff --git a/editor/icons/GPUParticlesCollisionSDF.svg b/editor/icons/GPUParticlesCollisionSDF3D.svg
index 00eca8295d..00eca8295d 100644
--- a/editor/icons/GPUParticlesCollisionSDF.svg
+++ b/editor/icons/GPUParticlesCollisionSDF3D.svg
diff --git a/editor/icons/GPUParticlesCollisionSphere.svg b/editor/icons/GPUParticlesCollisionSphere3D.svg
index cd188ddacc..cd188ddacc 100644
--- a/editor/icons/GPUParticlesCollisionSphere.svg
+++ b/editor/icons/GPUParticlesCollisionSphere3D.svg
diff --git a/editor/icons/ProximityGroup3D.svg b/editor/icons/ProximityGroup3D.svg
deleted file mode 100644
index 5cbf8add7b..0000000000
--- a/editor/icons/ProximityGroup3D.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="m1 1v14h14v-14zm2 2h10v10h-10zm7.5 1c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82843.67157 1.5 1.5 1.5.82842-.0000048 1.5-.67157 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5zm-5 5c-.82843-.0000048-1.5.67157-1.5 1.5-.0000048.82843.67157 1.5 1.5 1.5.82843.000005 1.5-.67157 1.5-1.5.0000048-.82843-.67157-1.5-1.5-1.5zm5 0c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82842.67157 1.5 1.5 1.5.82842-.000005 1.5-.67158 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5z" fill="#fc7f7f" fill-opacity=".99608"/></svg>
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index c34379f1ec..c1f577f176 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -1362,7 +1362,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
} else if (parser.get_node_name() == "skeleton") {
parser.read();
String uri = _uri_to_id(parser.get_node_data());
- if (uri != "") {
+ if (!uri.is_empty()) {
geom->skeletons.push_back(uri);
}
}
@@ -1464,7 +1464,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
bool found_name = false;
- if (id == "") {
+ if (id.is_empty()) {
id = "%NODEID%" + itos(Math::rand());
} else {
@@ -1479,7 +1479,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
Node *node = nullptr;
name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
- if (name == "") {
+ if (name.is_empty()) {
name = id;
} else {
found_name = true;
@@ -1499,7 +1499,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
joint->sid = parser.get_attribute_value_safe("name");
}
- if (joint->sid != "") {
+ if (!joint->sid.is_empty()) {
state.sid_to_node_map[joint->sid] = id;
}
@@ -1696,16 +1696,16 @@ void Collada::_parse_animation(XMLParser &parser) {
source_param_types[current_source] = Vector<String>();
} else if (name == "float_array") {
- if (current_source != "") {
+ if (!current_source.is_empty()) {
float_sources[current_source] = _read_float_array(parser);
}
} else if (name == "Name_array") {
- if (current_source != "") {
+ if (!current_source.is_empty()) {
string_sources[current_source] = _read_string_array(parser);
}
} else if (name == "accessor") {
- if (current_source != "" && parser.has_attribute("stride")) {
+ if (!current_source.is_empty() && parser.has_attribute("stride")) {
source_strides[current_source] = parser.get_attribute_value("stride").to_int();
}
} else if (name == "sampler") {
@@ -1725,7 +1725,7 @@ void Collada::_parse_animation(XMLParser &parser) {
}
} else if (name == "input") {
- if (current_sampler != "") {
+ if (!current_sampler.is_empty()) {
samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
}
@@ -1838,7 +1838,7 @@ void Collada::_parse_animation(XMLParser &parser) {
track.component = track.param.get_slice(".", 1).to_upper();
}
track.param = track.param.get_slice(".", 0);
- if (names.size() > 1 && track.component == "") {
+ if (names.size() > 1 && track.component.is_empty()) {
//this is a guess because the collada spec is ambiguous here...
//i suppose if you have many names (outputs) you can't use a component and i should abide to that.
track.component = name;
@@ -1855,7 +1855,7 @@ void Collada::_parse_animation(XMLParser &parser) {
state.referenced_tracks[target].push_back(state.animation_tracks.size() - 1);
- if (id != "") {
+ if (!id.is_empty()) {
if (!state.by_id_tracks.has(id)) {
state.by_id_tracks[id] = Vector<int>();
}
@@ -1953,10 +1953,10 @@ void Collada::_parse_library(XMLParser &parser) {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "mesh") {
- state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
_parse_mesh_geometry(parser, id, name2);
} else if (parser.get_node_name() == "spline") {
- state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
_parse_curve_geometry(parser, id, name2);
} else if (!parser.is_empty()) {
parser.skip_section();
@@ -2286,7 +2286,7 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
if (nj->controller) {
String base = nj->source;
- while (base != "" && !state.mesh_data_map.has(base)) {
+ while (!base.is_empty() && !state.mesh_data_map.has(base)) {
if (state.skin_controller_data_map.has(base)) {
SkinControllerData &sk = state.skin_controller_data_map[base];
base = sk.base;
diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp
index 45937e20bc..b63c2bf350 100644
--- a/editor/import/dynamicfont_import_settings.cpp
+++ b/editor/import/dynamicfont_import_settings.cpp
@@ -1083,7 +1083,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item = glyph_table->create_item(root);
ERR_FAIL_NULL(item);
item->set_text(0, _pad_zeros(String::num_int64(c, 16)));
- item->set_text_align(0, TreeItem::ALIGN_LEFT);
+ item->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
item->set_selectable(0, false);
item->set_custom_bg_color(0, glyph_table->get_theme_color("dark_color_3", "Editor"));
}
@@ -1101,7 +1101,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item->set_custom_bg_color(col + 1, glyph_table->get_theme_color("dark_color_2", "Editor"));
}
item->set_metadata(col + 1, c);
- item->set_text_align(col + 1, TreeItem::ALIGN_CENTER);
+ item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_selectable(col + 1, true);
item->set_custom_font(col + 1, font_main);
item->set_custom_font_size(col + 1, get_theme_font_size("font_size") * 2);
@@ -1159,7 +1159,7 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) {
/*************************************************************************/
void DynamicFontImportSettings::_lang_add() {
- menu_langs->set_position(lang_list->get_screen_transform().xform(lang_list->get_local_mouse_position()));
+ menu_langs->set_position(lang_list->get_screen_position() + lang_list->get_local_mouse_position());
menu_langs->reset_size();
menu_langs->popup();
}
@@ -1186,7 +1186,7 @@ void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p
}
void DynamicFontImportSettings::_script_add() {
- menu_scripts->set_position(script_list->get_screen_transform().xform(script_list->get_local_mouse_position()));
+ menu_scripts->set_position(script_list->get_screen_position() + script_list->get_local_mouse_position());
menu_scripts->reset_size();
menu_scripts->popup();
}
@@ -1597,7 +1597,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
menu_langs = memnew(PopupMenu);
menu_langs->set_name("Language");
- for (int i = 0; langs[i].name != String(); i++) {
+ for (int i = 0; !langs[i].name.is_empty(); i++) {
if (langs[i].name == "-") {
menu_langs->add_separator();
} else {
@@ -1609,7 +1609,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
menu_scripts = memnew(PopupMenu);
menu_scripts->set_name("Script");
- for (int i = 0; scripts[i].name != String(); i++) {
+ for (int i = 0; !scripts[i].name.is_empty(); i++) {
if (scripts[i].name == "-") {
menu_scripts->add_separator();
} else {
@@ -1632,7 +1632,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
root_vb->add_child(main_pages);
label_warn = memnew(Label);
- label_warn->set_align(Label::ALIGN_CENTER);
+ label_warn->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_warn->set_text("");
root_vb->add_child(label_warn);
label_warn->add_theme_color_override("font_color", warn_color);
@@ -1656,8 +1656,8 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
font_preview_label = memnew(Label);
font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE);
- font_preview_label->set_align(Label::ALIGN_CENTER);
- font_preview_label->set_valign(Label::VALIGN_CENTER);
+ font_preview_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ font_preview_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
font_preview_label->set_autowrap_mode(Label::AUTOWRAP_ARBITRARY);
font_preview_label->set_clip_text(true);
font_preview_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1694,7 +1694,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
label_vars = memnew(Label);
page2_hb_vars->add_child(label_vars);
- label_vars->set_align(Label::ALIGN_CENTER);
+ label_vars->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_vars->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_vars->set_text(TTR("Configuration:"));
@@ -1826,7 +1826,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
glyph_tree->connect("item_selected", callable_mp(this, &DynamicFontImportSettings::_range_selected));
glyph_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
glyph_root = glyph_tree->create_item();
- for (int i = 0; unicode_ranges[i].name != String(); i++) {
+ for (int i = 0; !unicode_ranges[i].name.is_empty(); i++) {
_add_glyph_range_item(unicode_ranges[i].start, unicode_ranges[i].end, unicode_ranges[i].name);
}
@@ -1845,7 +1845,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
page5_vb->add_child(hb_lang);
label_langs = memnew(Label);
- label_langs->set_align(Label::ALIGN_CENTER);
+ label_langs->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_langs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_langs->set_text(TTR("Language support overrides"));
hb_lang->add_child(label_langs);
@@ -1873,7 +1873,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
page5_vb->add_child(hb_script);
label_script = memnew(Label);
- label_script->set_align(Label::ALIGN_CENTER);
+ label_script->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_script->set_text(TTR("Script support overrides"));
hb_script->add_child(label_script);
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 076c0cc62b..91f8e5b910 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -303,7 +303,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
} break;
}
- if (p_node->name != "") {
+ if (!p_node->name.is_empty()) {
node->set_name(p_node->name);
}
NodeMap nm;
@@ -317,7 +317,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
p_parent->add_child(node, true);
node->set_owner(scene);
- if (p_node->empty_draw_type != "") {
+ if (!p_node->empty_draw_type.is_empty()) {
node->set_meta("empty_draw_type", Variant(p_node->empty_draw_type));
}
@@ -340,9 +340,9 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<StandardMaterial3D> material = memnew(StandardMaterial3D);
String base_name;
- if (src_mat.name != "") {
+ if (!src_mat.name.is_empty()) {
base_name = src_mat.name;
- } else if (effect.name != "") {
+ } else if (!effect.name.is_empty()) {
base_name = effect.name;
} else {
base_name = "Material";
@@ -360,9 +360,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// DIFFUSE
- if (effect.diffuse.texture != "") {
+ if (!effect.diffuse.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.diffuse.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -381,9 +381,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// SPECULAR
- if (effect.specular.texture != "") {
+ if (!effect.specular.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.specular.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -406,9 +406,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// EMISSION
- if (effect.emission.texture != "") {
+ if (!effect.emission.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.emission.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -433,9 +433,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// NORMAL
- if (effect.bump.texture != "") {
+ if (!effect.bump.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.bump.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -525,7 +525,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
normal_ofs = vertex_ofs;
}
- if (normal_source_id != "") {
+ if (!normal_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(normal_source_id), ERR_INVALID_DATA);
normal_src = &meshdata.sources[normal_source_id];
}
@@ -545,7 +545,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
binormal_ofs = vertex_ofs;
}
- if (binormal_source_id != "") {
+ if (!binormal_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(binormal_source_id), ERR_INVALID_DATA);
binormal_src = &meshdata.sources[binormal_source_id];
}
@@ -565,7 +565,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
tangent_ofs = vertex_ofs;
}
- if (tangent_source_id != "") {
+ if (!tangent_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(tangent_source_id), ERR_INVALID_DATA);
tangent_src = &meshdata.sources[tangent_source_id];
}
@@ -585,7 +585,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
uv_ofs = vertex_ofs;
}
- if (uv_source_id != "") {
+ if (!uv_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(uv_source_id), ERR_INVALID_DATA);
uv_src = &meshdata.sources[uv_source_id];
}
@@ -605,7 +605,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
uv2_ofs = vertex_ofs;
}
- if (uv2_source_id != "") {
+ if (!uv2_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(uv2_source_id), ERR_INVALID_DATA);
uv2_src = &meshdata.sources[uv2_source_id];
}
@@ -625,7 +625,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
color_ofs = vertex_ofs;
}
- if (color_source_id != "") {
+ if (!color_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(color_source_id), ERR_INVALID_DATA);
color_src = &meshdata.sources[color_source_id];
}
@@ -914,7 +914,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
material = material_cache[target];
}
- } else if (p.material != "") {
+ } else if (!p.material.is_empty()) {
WARN_PRINT("Collada: Unreferenced material in geometry instance: " + p.material);
}
}
@@ -1198,7 +1198,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
- ERR_FAIL_COND_V_MSG(ngsource != "", ERR_INVALID_DATA, "Controller instance source '" + ngsource + "' is neither skin or morph!");
+ ERR_FAIL_COND_V_MSG(!ngsource.is_empty(), ERR_INVALID_DATA, "Controller instance source '" + ngsource + "' is neither skin or morph!");
} else {
meshid = ng2->source;
@@ -1215,13 +1215,13 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
mesh = Ref<ImporterMesh>(memnew(ImporterMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
String name = meshdata.name;
- if (name == "") {
+ if (name.is_empty()) {
name = "Mesh";
}
int counter = 2;
while (mesh_unique_names.has(name)) {
name = meshdata.name;
- if (name == "") {
+ if (name.is_empty()) {
name = "Mesh";
}
name += itos(counter++);
@@ -1261,7 +1261,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
mi->set_surface_material(i, material);
- } else if (matname != "") {
+ } else if (!matname.is_empty()) {
WARN_PRINT("Collada: Unreferenced material in geometry instance: " + matname);
}
}
@@ -1343,7 +1343,7 @@ void ColladaImport::_fix_param_animation_tracks() {
// test source(s)
String source = ng->source;
- while (source != "") {
+ while (!source.is_empty()) {
if (collada.state.skin_controller_data_map.has(source)) {
const Collada::SkinControllerData &skin = collada.state.skin_controller_data_map[source];
@@ -1796,7 +1796,7 @@ Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint3
AnimationPlayer *ap = memnew(AnimationPlayer);
for (int i = 0; i < state.animations.size(); i++) {
String name;
- if (state.animations[i]->get_name() == "") {
+ if (state.animations[i]->get_name().is_empty()) {
name = "default";
} else {
name = state.animations[i]->get_name();
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index 7948d9e577..7a226802f2 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -113,7 +113,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
while (line.size() == locales.size() + 1) {
String key = line[0];
- if (key != "") {
+ if (!key.is_empty()) {
for (int i = 1; i < line.size(); i++) {
translations.write[i - 1]->add_message(key, line[i].c_unescape());
}
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index bb68de99b1..9e3cdbdeff 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -235,7 +235,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
while (l.length() && l[l.length() - 1] == '\\') {
String add = f->get_line().strip_edges();
l += add;
- if (add == String()) {
+ if (add.is_empty()) {
break;
}
}
@@ -301,7 +301,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
surf_tool->set_normal(normals[norm]);
}
- if (face[idx].size() >= 2 && face[idx][1] != String()) {
+ if (face[idx].size() >= 2 && !face[idx][1].is_empty()) {
int uv = face[idx][1].to_int() - 1;
if (uv < 0) {
uv += uvs.size() + 1;
@@ -363,9 +363,9 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
mesh = surf_tool->commit(mesh, mesh_flags);
- if (current_material != String()) {
+ if (!current_material.is_empty()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
- } else if (current_group != String()) {
+ } else if (!current_group.is_empty()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, current_group);
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index a25b694a60..330c7125fe 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -481,7 +481,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
fixed_name = _fixstr(name, "convcolonly");
}
- ERR_FAIL_COND_V(fixed_name == String(), nullptr);
+ ERR_FAIL_COND_V(fixed_name.is_empty(), nullptr);
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
@@ -577,7 +577,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
fixed_name = _fixstr(name, "convcol");
}
- if (fixed_name != String()) {
+ if (!fixed_name.is_empty()) {
if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
mi->set_name(fixed_name);
}
@@ -710,7 +710,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
mat_id = mat->get_name();
}
- if (mat_id != String() && p_material_data.has(mat_id)) {
+ if (!mat_id.is_empty() && p_material_data.has(mat_id)) {
Dictionary matdata = p_material_data[mat_id];
for (int j = 0; j < post_importer_plugins.size(); j++) {
@@ -1433,7 +1433,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
String script_ext_hint;
for (const String &E : script_extentions) {
- if (script_ext_hint != "") {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "*." + E;
@@ -1559,7 +1559,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
mesh_id = src_mesh_node->get_mesh()->get_name();
}
- if (mesh_id != String() && p_mesh_data.has(mesh_id)) {
+ if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) {
Dictionary mesh_settings = p_mesh_data[mesh_id];
if (mesh_settings.has("generate/shadow_meshes")) {
@@ -1649,7 +1649,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
- if (save_to_file != String()) {
+ if (!save_to_file.is_empty()) {
Ref<Mesh> existing = Ref<Resource>(ResourceCache::get(save_to_file));
if (existing.is_valid()) {
//if somehow an existing one is useful, create
@@ -2051,7 +2051,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
String post_import_script_path = p_options["import_script/path"];
Ref<EditorScenePostImport> post_import_script;
- if (post_import_script_path != "") {
+ if (!post_import_script_path.is_empty()) {
Ref<Script> scr = ResourceLoader::load(post_import_script_path);
if (!scr.is_valid()) {
EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 5690d49a55..a376596f9b 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -92,7 +92,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
if (p_material->has_meta("import_id")) {
import_id = p_material->get_meta("import_id");
has_import_id = true;
- } else if (p_material->get_name() != "") {
+ } else if (!p_material->get_name().is_empty()) {
import_id = p_material->get_name();
has_import_id = true;
} else {
@@ -148,7 +148,7 @@ void SceneImportSettings::_fill_mesh(Tree *p_tree, const Ref<Mesh> &p_mesh, Tree
if (p_mesh->has_meta("import_id")) {
import_id = p_mesh->get_meta("import_id");
has_import_id = true;
- } else if (p_mesh->get_name() != String()) {
+ } else if (!p_mesh->get_name().is_empty()) {
import_id = p_mesh->get_name();
has_import_id = true;
} else {
@@ -414,7 +414,7 @@ void SceneImportSettings::_update_camera() {
float rot_y = cam_rot_y;
float zoom = cam_zoom;
- if (selected_type == "Node" || selected_type == "") {
+ if (selected_type == "Node" || selected_type.is_empty()) {
camera_aabb = contents_aabb;
} else {
if (mesh_preview->get_mesh().is_valid()) {
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index cc6b4e66e4..3507eaff94 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -525,7 +525,7 @@ void ImportDock::_reimport() {
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
ERR_CONTINUE(!importer.is_valid());
String group_file_property = importer->get_option_group_file();
- if (group_file_property != String()) {
+ if (!group_file_property.is_empty()) {
//can import from a group (as in, atlas)
ERR_CONTINUE(!params->values.has(group_file_property));
String group_file = params->values[group_file_property];
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 5622d0b145..f594a5a3a8 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -312,7 +312,7 @@ void InspectorDock::_prepare_history() {
Resource *r = Object::cast_to<Resource>(obj);
if (r->get_path().is_resource_file()) {
text = r->get_path().get_file();
- } else if (r->get_name() != String()) {
+ } else if (!r->get_name().is_empty()) {
text = r->get_name();
} else {
text = r->get_class();
@@ -460,7 +460,7 @@ void InspectorDock::open_resource(const String &p_type) {
void InspectorDock::set_warning(const String &p_message) {
warning->hide();
- if (p_message != String()) {
+ if (!p_message.is_empty()) {
warning->show();
warning_dialog->set_text(p_message);
}
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 5c25e6aae9..9d48a43d4d 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -497,7 +497,7 @@ void LocalizationEditor::update_translations() {
TreeItem *t = translation_filter->create_item(root);
t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- t->set_text(0, n);
+ t->set_text(0, vformat("[%s] %s", l, n));
t->set_editable(0, true);
t->set_tooltip(0, l);
t->set_checked(0, is_checked);
@@ -537,7 +537,7 @@ void LocalizationEditor::update_translations() {
if (langnames.length() > 0) {
langnames += ",";
}
- langnames += names[i];
+ langnames += vformat("[%s] %s", langs[i], names[i]);
translation_locales_idxs_remap.write[l_idx] = i;
l_idx++;
}
@@ -546,7 +546,7 @@ void LocalizationEditor::update_translations() {
if (i > 0) {
langnames += ",";
}
- langnames += names[i];
+ langnames += vformat("[%s] %s", langs[i], names[i]);
}
}
@@ -641,7 +641,7 @@ LocalizationEditor::LocalizationEditor() {
translation_locales_list_created = false;
TabContainer *translations = memnew(TabContainer);
- translations->set_tab_align(TabContainer::ALIGN_LEFT);
+ translations->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
translations->set_v_size_flags(Control::SIZE_EXPAND_FILL);
add_child(translations);
diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp
index 1e707c1a60..1a30770b53 100644
--- a/editor/multi_node_edit.cpp
+++ b/editor/multi_node_edit.cpp
@@ -75,7 +75,7 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value,
ur->add_do_property(n, name, path);
} else {
Variant new_value;
- if (p_field == "") {
+ if (p_field.is_empty()) {
// whole value
new_value = p_value;
} else {
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 532413897b..c3dc7eae28 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -128,8 +128,8 @@ NodeDock::NodeDock() {
select_a_node->set_text(TTR("Select a single node to edit its signals and groups."));
select_a_node->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
select_a_node->set_v_size_flags(SIZE_EXPAND_FILL);
- select_a_node->set_valign(Label::VALIGN_CENTER);
- select_a_node->set_align(Label::ALIGN_CENTER);
+ select_a_node->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ select_a_node->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
select_a_node->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
add_child(select_a_node);
}
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 58f92a98a6..72d94e61ca 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -554,7 +554,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
String num = String::num(vertex.vertex);
Size2 num_size = font->get_string_size(num, font_size);
- p_overlay->draw_string(font, point - num_size * 0.5, num, HALIGN_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
+ p_overlay->draw_string(font, point - num_size * 0.5, num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
}
}
}
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index cfb7217baa..f16ea36a23 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -98,7 +98,8 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
menu->add_separator();
menu->add_item(TTR("Load..."), MENU_LOAD_FILE);
- menu->set_position(blend_space_draw->get_screen_transform().xform(mb->get_position()));
+ menu->set_position(blend_space_draw->get_screen_position() + mb->get_position());
+ menu->reset_size();
menu->popup();
add_point_pos = (mb->get_position() / blend_space_draw->get_size()).x;
@@ -222,7 +223,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
float x = point;
blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor);
- blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor);
+ blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft);
}
@@ -551,7 +552,7 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
if (error != error_label->get_text()) {
error_label->set_text(error);
- if (error != String()) {
+ if (!error.is_empty()) {
error_panel->show();
} else {
error_panel->hide();
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 9af060ed84..b107478724 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -121,7 +121,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
menu->add_separator();
menu->add_item(TTR("Load..."), MENU_LOAD_FILE);
- menu->set_position(blend_space_draw->get_screen_transform().xform(mb->get_position()));
+ menu->set_position(blend_space_draw->get_screen_position() + mb->get_position());
+ menu->reset_size();
menu->popup();
add_point_pos = (mb->get_position() / blend_space_draw->get_size());
add_point_pos.y = 1.0 - add_point_pos.y;
@@ -411,14 +412,14 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (blend_space->get_min_space().y < 0) {
int y = (blend_space->get_max_space().y / (blend_space->get_max_space().y - blend_space->get_min_space().y)) * s.height;
blend_space_draw->draw_line(Point2(0, y), Point2(5 * EDSCALE, y), linecolor);
- blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor);
+ blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
blend_space_draw->draw_line(Point2(5 * EDSCALE, y), Point2(s.width, y), linecolor_soft);
}
if (blend_space->get_min_space().x < 0) {
int x = (-blend_space->get_min_space().x / (blend_space->get_max_space().x - blend_space->get_min_space().x)) * s.width;
blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor);
- blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HALIGN_LEFT, -1, font_size, linecolor);
+ blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft);
}
@@ -760,7 +761,7 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
if (error != error_label->get_text()) {
error_label->set_text(error);
- if (error != String()) {
+ if (!error.is_empty()) {
error_panel->show();
} else {
error_panel->hide();
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 75d2bed1b2..d9a6f19384 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -83,7 +83,7 @@ void AnimationNodeBlendTreeEditor::_update_options_menu(bool p_has_input_ports)
}
add_node->get_popup()->add_separator();
add_node->get_popup()->add_item(TTR("Load..."), MENU_LOAD_FILE);
- use_popup_menu_position = false;
+ use_position_from_popup_menu = false;
}
Size2 AnimationNodeBlendTreeEditor::get_minimum_size() const {
@@ -292,7 +292,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
anode = EditorSettings::get_singleton()->get_resource_clipboard();
ERR_FAIL_COND(!anode.is_valid());
base_name = anode->get_class();
- } else if (add_options[p_idx].type != String()) {
+ } else if (!add_options[p_idx].type.is_empty()) {
AnimationNode *an = Object::cast_to<AnimationNode>(ClassDB::instantiate(add_options[p_idx].type));
ERR_FAIL_COND(!an);
anode = Ref<AnimationNode>(an);
@@ -319,8 +319,8 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
}
Point2 instance_pos = graph->get_scroll_ofs();
- if (use_popup_menu_position) {
- instance_pos += popup_menu_position;
+ if (use_position_from_popup_menu) {
+ instance_pos += position_from_popup_menu;
} else {
instance_pos += graph->get_size() * 0.5;
}
@@ -355,14 +355,15 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
void AnimationNodeBlendTreeEditor::_popup(bool p_has_input_ports, const Vector2 &p_popup_position, const Vector2 &p_node_position) {
_update_options_menu(p_has_input_ports);
- use_popup_menu_position = true;
- popup_menu_position = p_popup_position;
- add_node->get_popup()->set_position(p_node_position);
+ use_position_from_popup_menu = true;
+ position_from_popup_menu = p_node_position;
+ add_node->get_popup()->set_position(p_popup_position);
+ add_node->get_popup()->reset_size();
add_node->get_popup()->popup();
}
void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) {
- _popup(false, graph->get_local_mouse_position(), p_position);
+ _popup(false, graph->get_screen_position() + graph->get_local_mouse_position(), p_position);
}
void AnimationNodeBlendTreeEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) {
@@ -599,7 +600,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
String accum;
for (int i = 0; i < path.get_name_count(); i++) {
String name = path.get_name(i);
- if (accum != String()) {
+ if (!accum.is_empty()) {
accum += "/";
}
accum += name;
@@ -751,7 +752,7 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
if (error != error_label->get_text()) {
error_label->set_text(error);
- if (error != String()) {
+ if (!error.is_empty()) {
error_panel->show();
} else {
error_panel->hide();
@@ -820,13 +821,13 @@ AnimationNodeBlendTreeEditor *AnimationNodeBlendTreeEditor::singleton = nullptr;
void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<AnimationNode> p_node) {
String prev_name = blend_tree->get_node_name(p_node);
- ERR_FAIL_COND(prev_name == String());
+ ERR_FAIL_COND(prev_name.is_empty());
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(prev_name));
ERR_FAIL_COND(!gn);
const String &new_name = p_text;
- ERR_FAIL_COND(new_name == "" || new_name.find(".") != -1 || new_name.find("/") != -1);
+ ERR_FAIL_COND(new_name.is_empty() || new_name.find(".") != -1 || new_name.find("/") != -1);
if (new_name == prev_name) {
return; //nothing to do
@@ -918,7 +919,7 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
singleton = this;
updating = false;
- use_popup_menu_position = false;
+ use_position_from_popup_menu = false;
graph = memnew(GraphEdit);
add_child(graph);
@@ -945,7 +946,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
add_node->set_text(TTR("Add Node..."));
graph->get_zoom_hbox()->move_child(add_node, 0);
add_node->get_popup()->connect("id_pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_add_node));
- add_node->connect("about_to_popup", callable_mp(this, &AnimationNodeBlendTreeEditor::_update_options_menu));
+ add_node->connect("about_to_popup", callable_mp(this, &AnimationNodeBlendTreeEditor::_update_options_menu), varray(false));
add_options.push_back(AddOption("Animation", "AnimationNodeAnimation"));
add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot", 2));
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 0fcafad40e..68da5c6f79 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -49,8 +49,8 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
Ref<AnimationNodeBlendTree> blend_tree;
GraphEdit *graph;
MenuButton *add_node;
- Vector2 popup_menu_position;
- bool use_popup_menu_position;
+ Vector2 position_from_popup_menu;
+ bool use_position_from_popup_menu;
PanelContainer *error_panel;
Label *error_label;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 226046f250..14390511de 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -42,6 +42,7 @@
#include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning.
#include "scene/main/window.h"
#include "scene/resources/animation.h"
+#include "scene/scene_string_names.h"
#include "servers/rendering_server.h"
void AnimationPlayerEditor::_node_removed(Node *p_node) {
@@ -189,7 +190,7 @@ void AnimationPlayerEditor::_play_pressed() {
current = animation->get_item_text(animation->get_selected());
}
- if (current != "") {
+ if (!current.is_empty()) {
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
}
@@ -206,7 +207,7 @@ void AnimationPlayerEditor::_play_from_pressed() {
current = animation->get_item_text(animation->get_selected());
}
- if (current != "") {
+ if (!current.is_empty()) {
float time = player->get_current_animation_position();
if (current == player->get_assigned_animation() && player->is_playing()) {
@@ -227,7 +228,7 @@ void AnimationPlayerEditor::_play_bw_pressed() {
current = animation->get_item_text(animation->get_selected());
}
- if (current != "") {
+ if (!current.is_empty()) {
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
}
@@ -244,7 +245,7 @@ void AnimationPlayerEditor::_play_bw_from_pressed() {
current = animation->get_item_text(animation->get_selected());
}
- if (current != "") {
+ if (!current.is_empty()) {
float time = player->get_current_animation_position();
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
@@ -279,7 +280,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
current = animation->get_item_text(animation->get_selected());
}
- if (current != "") {
+ if (!current.is_empty()) {
player->set_assigned_animation(current);
Ref<Animation> anim = player->get_animation(current);
@@ -396,7 +397,7 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource)
String path;
//file->set_current_path(current_path);
- if (p_resource->get_path() != "") {
+ if (!p_resource->get_path().is_empty()) {
path = p_resource->get_path();
if (extensions.size()) {
if (extensions.find(p_resource->get_path().get_extension().to_lower()) == nullptr) {
@@ -405,7 +406,7 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource)
}
} else {
if (extensions.size()) {
- if (p_resource->get_name() != "") {
+ if (!p_resource->get_name().is_empty()) {
path = p_resource->get_name() + "." + extensions.front()->get().to_lower();
} else {
String resource_name_snake_case = p_resource->get_class().camelcase_to_underscore();
@@ -485,7 +486,7 @@ void AnimationPlayerEditor::_animation_name_edited() {
player->stop();
String new_name = name->get_text();
- if (new_name == "" || new_name.find(":") != -1 || new_name.find("/") != -1) {
+ if (new_name.is_empty() || new_name.find(":") != -1 || new_name.find("/") != -1) {
error_dialog->set_text(TTR("Invalid animation name!"));
error_dialog->popup_centered();
return;
@@ -719,7 +720,7 @@ void AnimationPlayerEditor::_animation_edit() {
void AnimationPlayerEditor::_save_animation(String p_file) {
String current = animation->get_item_text(animation->get_selected());
- if (current != "") {
+ if (!current.is_empty()) {
Ref<Animation> anim = player->get_animation(current);
ERR_FAIL_COND(!Object::cast_to<Resource>(*anim));
@@ -836,12 +837,12 @@ void AnimationPlayerEditor::_update_player() {
for (const StringName &E : animlist) {
Ref<Texture2D> icon;
if (E == player->get_autoplay()) {
- if (E == "RESET") {
+ if (E == SceneStringNames::get_singleton()->RESET) {
icon = autoplay_reset_icon;
} else {
icon = autoplay_icon;
}
- } else if (E == "RESET") {
+ } else if (E == SceneStringNames::get_singleton()->RESET) {
icon = reset_icon;
}
animation->add_icon_item(icon, E);
@@ -1006,7 +1007,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool
updating = true;
String current = player->get_assigned_animation();
- if (current == "" || !player->has_animation(current)) {
+ if (current.is_empty() || !player->has_animation(current)) {
updating = false;
current = "";
return;
@@ -1085,7 +1086,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
}
Ref<Animation> anim;
- if (current != String()) {
+ if (!current.is_empty()) {
anim = player->get_animation(current);
}
@@ -1140,7 +1141,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
}
String name = anim2->get_name();
- if (name == "") {
+ if (name.is_empty()) {
name = TTR("Pasted Animation");
}
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 191f5d9071..cf3bc58af9 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -118,7 +118,8 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
menu->add_separator();
menu->add_item(TTR("Load..."), MENU_LOAD_FILE);
- menu->set_position(state_machine_draw->get_screen_transform().xform(mb->get_position()));
+ menu->set_position(state_machine_draw->get_screen_position() + mb->get_position());
+ menu->reset_size();
menu->popup();
add_node_pos = mb->get_position() / EDSCALE + state_machine->get_graph_offset();
}
@@ -151,7 +152,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
edit_rect.position -= line_sb->get_offset();
edit_rect.size += line_sb->get_minimum_size();
- name_edit_popup->set_position(state_machine_draw->get_screen_transform().xform(edit_rect.position));
+ name_edit_popup->set_position(state_machine_draw->get_screen_position() + edit_rect.position);
name_edit_popup->set_size(edit_rect.size);
name_edit->set_text(node_rects[i].node_name);
name_edit_popup->popup();
@@ -437,7 +438,7 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
return;
}
- if (base_name == String()) {
+ if (base_name.is_empty()) {
base_name = node->get_class().replace_first("AnimationNode", "");
}
@@ -760,12 +761,12 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
bool onstart = state_machine->get_start_node() == name;
if (onstart) {
- state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("Start"), HALIGN_LEFT, -1, font_size, font_color);
+ state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("Start"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
}
if (state_machine->get_end_node() == name) {
int endofs = nr.node.size.x - font->get_string_size(TTR("End"), font_size).x;
- state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("End"), HALIGN_LEFT, -1, font_size, font_color);
+ state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("End"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
}
offset.x += sb->get_offset().x;
@@ -785,7 +786,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
nr.name.position = offset + Vector2(0, (h - font->get_height(font_size)) / 2).floor();
nr.name.size = Vector2(strsize, font->get_height(font_size));
- state_machine_draw->draw_string(font, nr.name.position + Vector2(0, font->get_ascent(font_size)), name, HALIGN_LEFT, -1, font_size, font_color);
+ state_machine_draw->draw_string(font, nr.name.position + Vector2(0, font->get_ascent(font_size)), name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
offset.x += strsize + sep;
if (needs_editor) {
@@ -926,7 +927,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
if (error != error_label->get_text()) {
error_label->set_text(error);
- if (error != String()) {
+ if (!error.is_empty()) {
error_panel->show();
} else {
error_panel->hide();
@@ -1058,7 +1059,7 @@ void AnimationNodeStateMachineEditor::_removed_from_graph() {
void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
const String &new_name = p_text;
- ERR_FAIL_COND(new_name == "" || new_name.find(".") != -1 || new_name.find("/") != -1);
+ ERR_FAIL_COND(new_name.is_empty() || new_name.find(".") != -1 || new_name.find("/") != -1);
if (new_name == prev_name) {
return; // Nothing to do.
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index 6c5606fbfd..d65ed9cea2 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -226,8 +226,7 @@ AnimationTreeEditor::AnimationTreeEditor() {
AnimationNodeAnimation::get_editable_animation_list = get_animation_list;
path_edit = memnew(ScrollContainer);
add_child(path_edit);
- path_edit->set_enable_h_scroll(true);
- path_edit->set_enable_v_scroll(false);
+ path_edit->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
path_hb = memnew(HBoxContainer);
path_edit->add_child(path_hb);
path_hb->add_child(memnew(Label(TTR("Path:"))));
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 1a216b3862..0925b34ac1 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -288,8 +288,7 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
previews = memnew(ScrollContainer);
previews_bg->add_child(previews);
- previews->set_enable_v_scroll(false);
- previews->set_enable_h_scroll(true);
+ previews->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
preview_hb = memnew(HBoxContainer);
preview_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -344,7 +343,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
if (p_code != 200) {
error_text = TTR("Request failed, return code:") + " " + itos(p_code);
status->set_text(TTR("Failed:") + " " + itos(p_code));
- } else if (sha256 != "") {
+ } else if (!sha256.is_empty()) {
String download_sha256 = FileAccess::get_sha256(download->get_download_file());
if (sha256 != download_sha256) {
error_text = TTR("Bad download hash, assuming file has been tampered with.") + "\n";
@@ -355,7 +354,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
} break;
}
- if (error_text != String()) {
+ if (!error_text.is_empty()) {
download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text);
download_error->popup_centered();
// Let the user retry the download.
@@ -922,7 +921,7 @@ void EditorAssetLibrary::_search(int p_page) {
support_list += String(support_key[i]) + "+";
}
}
- if (support_list != String()) {
+ if (!support_list.is_empty()) {
args += "&support=" + support_list.substr(0, support_list.length() - 1);
}
@@ -935,7 +934,7 @@ void EditorAssetLibrary::_search(int p_page) {
args += "&reverse=true";
}
- if (filter->get_text() != String()) {
+ if (!filter->get_text().is_empty()) {
args += "&filter=" + filter->get_text().uri_encode();
}
@@ -1188,7 +1187,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
library_vb->add_child(asset_bottom_page);
if (result.is_empty()) {
- if (filter->get_text() != String()) {
+ if (!filter->get_text().is_empty()) {
library_error->set_text(
vformat(TTR("No results for \"%s\"."), filter->get_text()));
} else {
@@ -1219,7 +1218,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
item->connect("author_selected", callable_mp(this, &EditorAssetLibrary::_select_author));
item->connect("category_selected", callable_mp(this, &EditorAssetLibrary::_select_category));
- if (r.has("icon_url") && r["icon_url"] != "") {
+ if (r.has("icon_url") && !r["icon_url"].operator String().is_empty()) {
_request_image(item->get_instance_id(), r["icon_url"], IMAGE_QUEUE_ICON, 0);
}
}
@@ -1256,7 +1255,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
description->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"], r["version"], r["version_string"], r["description"], r["download_url"], r["browse_url"], r["download_hash"]);
- if (r.has("icon_url") && r["icon_url"] != "") {
+ if (r.has("icon_url") && !r["icon_url"].operator String().is_empty()) {
_request_image(description->get_instance_id(), r["icon_url"], IMAGE_QUEUE_ICON, 0);
}
@@ -1431,8 +1430,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_scroll_bg->set_v_size_flags(Control::SIZE_EXPAND_FILL);
library_scroll = memnew(ScrollContainer);
- library_scroll->set_enable_v_scroll(true);
- library_scroll->set_enable_h_scroll(false);
+ library_scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
library_scroll_bg->add_child(library_scroll);
@@ -1454,11 +1452,11 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_vb_border->add_child(library_vb);
library_loading = memnew(Label(TTR("Loading...")));
- library_loading->set_align(Label::ALIGN_CENTER);
+ library_loading->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
library_vb->add_child(library_loading);
library_error = memnew(Label);
- library_error->set_align(Label::ALIGN_CENTER);
+ library_error->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
library_error->hide();
library_vb->add_child(library_error);
@@ -1499,8 +1497,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
set_process_unhandled_key_input(true); // Global shortcuts since there is no main element to be focused.
downloads_scroll = memnew(ScrollContainer);
- downloads_scroll->set_enable_h_scroll(true);
- downloads_scroll->set_enable_v_scroll(false);
+ downloads_scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
library_main->add_child(downloads_scroll);
downloads_hb = memnew(HBoxContainer);
downloads_scroll->add_child(downloads_hb);
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index c76713f534..c621ade5c8 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -241,7 +241,7 @@ AudioStreamEditor::AudioStreamEditor() {
_stop_button->connect("pressed", callable_mp(this, &AudioStreamEditor::_stop));
_current_label = memnew(Label);
- _current_label->set_align(Label::ALIGN_RIGHT);
+ _current_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
_current_label->set_h_size_flags(SIZE_EXPAND_FILL);
_current_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
_current_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index a3378d1550..4a19e7752e 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1460,7 +1460,7 @@ bool CanvasItemEditor::_gui_input_open_scene_on_double_click(const Ref<InputEven
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
CanvasItem *canvas_item = selection[0];
- if (canvas_item->get_scene_file_path() != "" && canvas_item != editor->get_edited_scene()) {
+ if (!canvas_item->get_scene_file_path().is_empty() && canvas_item != editor->get_edited_scene()) {
editor->open_request(canvas_item->get_scene_file_path());
return true;
}
@@ -2258,7 +2258,8 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
selection_menu_additive_selection = b->is_shift_pressed();
- selection_menu->set_position(get_screen_transform().xform(b->get_position()));
+ selection_menu->set_position(get_screen_position() + b->get_position());
+ selection_menu->reset_size();
selection_menu->popup();
return true;
}
@@ -2266,7 +2267,7 @@ 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->reset_size();
- add_node_menu->set_position(get_screen_position() + b->get_position());
+ add_node_menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
add_node_menu->popup();
node_create_position = transform.affine_inverse().xform((get_local_mouse_position()));
return true;
@@ -2339,7 +2340,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (selection2.size() > 0) {
drag_type = DRAG_MOVE;
- drag_from = click;
+ drag_from = drag_start_origin;
_save_canvas_item_state(drag_selection);
}
return true;
@@ -2650,7 +2651,7 @@ void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string
p_position += Vector2(-text_size.x / 2, text_size.y + 5);
break;
}
- viewport->draw_string(font, p_position, p_string, HALIGN_LEFT, -1, font_size, color);
+ viewport->draw_string(font, p_position, p_string, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color);
}
void CanvasItemEditor::_draw_margin_at_position(int p_value, Point2 p_position, Side p_side) {
@@ -2710,7 +2711,7 @@ void CanvasItemEditor::_draw_guides() {
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, 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, outline_size, outline_color);
viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE));
}
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) {
@@ -2718,7 +2719,7 @@ void CanvasItemEditor::_draw_guides() {
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, 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, outline_size, outline_color);
viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE));
}
}
@@ -2790,7 +2791,7 @@ void CanvasItemEditor::_draw_rulers() {
if (i % (major_subdivision * minor_subdivision) == 0) {
viewport->draw_line(Point2(position.x, 0), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE));
real_t val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x;
- viewport->draw_string(font, Point2(position.x + 2, font->get_height(font_size)), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HALIGN_LEFT, -1, font_size, font_color);
+ viewport->draw_string(font, Point2(position.x + 2, font->get_height(font_size)), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
} else {
if (i % minor_subdivision == 0) {
viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE));
@@ -2810,7 +2811,7 @@ void CanvasItemEditor::_draw_rulers() {
Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(font_size), position.y - 2));
viewport->draw_set_transform_matrix(viewport->get_transform() * text_xform);
- viewport->draw_string(font, Point2(), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HALIGN_LEFT, -1, font_size, font_color);
+ viewport->draw_string(font, Point2(), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
viewport->draw_set_transform_matrix(viewport->get_transform());
} else {
@@ -2913,14 +2914,6 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 corner = Point2(begin.x, end.y);
Vector2 length_vector = (begin - end).abs() / zoom;
- bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x));
-
- viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3));
- if (draw_secondary_lines) {
- viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE));
- viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE));
- }
-
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"));
@@ -2936,7 +2929,23 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2);
text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5);
text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5);
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
+
+ if (begin.is_equal_approx(end)) {
+ viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_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);
+ return;
+ }
+
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
+
+ bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x));
+
+ viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3));
+ if (draw_secondary_lines) {
+ viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE));
+ viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE));
+ }
if (draw_secondary_lines) {
const real_t horizontal_angle_rad = length_vector.angle();
@@ -2946,16 +2955,16 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 text_pos2 = text_pos;
text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
Point2 v_angle_text_pos = Point2();
v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width);
v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5);
- viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
text_pos2 = text_pos;
text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
Point2 h_angle_text_pos = Point2();
h_angle_text_pos.x = CLAMP(end.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width);
@@ -2972,7 +2981,7 @@ void CanvasItemEditor::_draw_ruler_tool() {
h_angle_text_pos.y = MIN(text_pos.y - height_multiplier * text_height, MIN(end.y - text_height * 0.5, text_pos2.y - height_multiplier * text_height));
}
}
- viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
// Angle arcs
int arc_point_count = 8;
@@ -3007,17 +3016,17 @@ void CanvasItemEditor::_draw_ruler_tool() {
text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2);
if (draw_secondary_lines) {
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
Point2 text_pos2 = text_pos;
text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
text_pos2 = text_pos;
text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HALIGN_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
} else {
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
}
}
} else {
@@ -3580,7 +3589,7 @@ void CanvasItemEditor::_draw_hover() {
viewport->draw_texture(node_icon, pos, Color(1.0, 1.0, 1.0, 0.5));
// Draw name
- viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, HALIGN_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
+ viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
}
}
@@ -5267,7 +5276,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
select_button->set_pressed(true);
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), Key::Q));
select_button->set_shortcut_context(this);
- select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
+ select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
hb->add_child(memnew(VSeparator));
@@ -5296,7 +5305,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SCALE));
scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), Key::S));
scale_button->set_shortcut_context(this);
- scale_button->set_tooltip(TTR("Scale Mode"));
+ scale_button->set_tooltip(TTR("Shift: Scale proportionally."));
hb->add_child(memnew(VSeparator));
@@ -5834,7 +5843,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
return false;
}
- if (editor->get_edited_scene()->get_scene_file_path() != "") { // cyclical instancing
+ if (!editor->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing
if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
return false;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index daf34903e6..3bb707d415 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -117,7 +117,7 @@ void CurveEditor::gui_input(const Ref<InputEvent> &p_event) {
switch (mb.get_button_index()) {
case MouseButton::RIGHT:
_context_click_pos = mpos;
- open_context_menu(get_global_transform().xform(mpos));
+ open_context_menu(get_screen_position() + mpos);
break;
case MouseButton::MIDDLE:
@@ -460,7 +460,7 @@ void CurveEditor::remove_point(int index) {
Curve::Point p = _curve_ref->get_point(index);
ur.add_do_method(*_curve_ref, "remove_point", index);
- ur.add_undo_method(*_curve_ref, "add_point", p.pos, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
+ ur.add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
if (index == _selected_point) {
set_selected_point(-1);
@@ -675,11 +675,11 @@ void CurveEditor::_draw() {
// X axis
float y = curve.get_min_value();
Vector2 off(0, font_height - 1);
- draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", HALIGN_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
}
{
@@ -688,9 +688,9 @@ void CurveEditor::_draw() {
float m1 = 0.5 * (curve.get_min_value() + curve.get_max_value());
float m2 = curve.get_max_value();
Vector2 off(1, -1);
- draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), HALIGN_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), HALIGN_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
}
// Draw tangents for current point
@@ -750,10 +750,10 @@ void CurveEditor::_draw() {
if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) {
text_color.a *= 0.4;
- draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HALIGN_LEFT, -1, font_size, text_color);
+ draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
} else if (curve.get_point_count() == 0) {
text_color.a *= 0.4;
- draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HALIGN_LEFT, -1, font_size, text_color);
+ draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
}
}
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 9702c7e734..3b85fad345 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -477,7 +477,7 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
}
String code = scr->get_source_code().strip_edges();
- if (code == "") {
+ if (code.is_empty()) {
return Ref<Texture2D>();
}
@@ -851,7 +851,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
Ref<Font> font = sampled_font;
- font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1));
+ font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(1, 1, 1));
RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 44c789b145..4b50f484a4 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -57,6 +57,27 @@ void GPUParticles2DEditorPlugin::_file_selected(const String &p_file) {
emission_mask->popup_centered();
}
+void GPUParticles2DEditorPlugin::_selection_changed() {
+ List<Node *> selected_nodes = editor->get_editor_selection()->get_selected_node_list();
+
+ if (selected_particles.is_empty() && selected_nodes.is_empty()) {
+ return;
+ }
+
+ for (GPUParticles2D *SP : selected_particles) {
+ SP->set_show_visibility_rect(false);
+ }
+ selected_particles.clear();
+
+ for (Node *P : selected_nodes) {
+ GPUParticles2D *selected_particle = Object::cast_to<GPUParticles2D>(P);
+ if (selected_particle != nullptr) {
+ selected_particle->set_show_visibility_rect(true);
+ selected_particles.push_back(selected_particle);
+ }
+ }
+}
+
void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
switch (p_idx) {
case MENU_GENERATE_VISIBILITY_RECT: {
@@ -334,6 +355,7 @@ void GPUParticles2DEditorPlugin::_notification(int p_what) {
menu->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles2DEditorPlugin::_menu_callback));
menu->set_icon(menu->get_theme_icon(SNAME("GPUParticles2D"), SNAME("EditorIcons")));
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));
}
}
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h
index 0b2028b745..bdfc021aa7 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.h
@@ -56,6 +56,7 @@ class GPUParticles2DEditorPlugin : public EditorPlugin {
};
GPUParticles2D *particles;
+ List<GPUParticles2D *> selected_particles;
EditorFileDialog *file;
EditorNode *editor;
@@ -79,6 +80,7 @@ class GPUParticles2DEditorPlugin : public EditorPlugin {
void _menu_callback(int p_idx);
void _generate_visibility_rect();
void _generate_emission_mask();
+ void _selection_changed();
protected:
void _notification(int p_what);
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index 6df2e34ceb..f6788f80ba 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -30,11 +30,11 @@
#include "gpu_particles_collision_sdf_editor_plugin.h"
-void GPUParticlesCollisionSDFEditorPlugin::_bake() {
+void GPUParticlesCollisionSDF3DEditorPlugin::_bake() {
if (col_sdf) {
if (col_sdf->get_texture().is_null() || !col_sdf->get_texture()->get_path().is_resource_file()) {
String path = get_tree()->get_edited_scene_root()->get_scene_file_path();
- if (path == String()) {
+ if (path.is_empty()) {
path = "res://" + col_sdf->get_name() + "_data.exr";
} else {
String ext = path.get_extension();
@@ -49,8 +49,8 @@ void GPUParticlesCollisionSDFEditorPlugin::_bake() {
}
}
-void GPUParticlesCollisionSDFEditorPlugin::edit(Object *p_object) {
- GPUParticlesCollisionSDF *s = Object::cast_to<GPUParticlesCollisionSDF>(p_object);
+void GPUParticlesCollisionSDF3DEditorPlugin::edit(Object *p_object) {
+ GPUParticlesCollisionSDF3D *s = Object::cast_to<GPUParticlesCollisionSDF3D>(p_object);
if (!s) {
return;
}
@@ -58,46 +58,50 @@ void GPUParticlesCollisionSDFEditorPlugin::edit(Object *p_object) {
col_sdf = s;
}
-bool GPUParticlesCollisionSDFEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("GPUParticlesCollisionSDF");
+bool GPUParticlesCollisionSDF3DEditorPlugin::handles(Object *p_object) const {
+ return p_object->is_class("GPUParticlesCollisionSDF3D");
}
-void GPUParticlesCollisionSDFEditorPlugin::_notification(int p_what) {
+void GPUParticlesCollisionSDF3DEditorPlugin::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
if (!col_sdf) {
return;
}
+ // Set information tooltip on the Bake button. This information is useful
+ // to optimize performance (video RAM size) and reduce collision tunneling (individual cell size).
+
const Vector3i size = col_sdf->get_estimated_cell_size();
- String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z);
- int data_size = 2;
- const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
- text += " - " + vformat(TTR("VRAM Size: %s MB"), String::num(size_mb, 2));
+ const Vector3 extents = col_sdf->get_extents();
- if (bake_info->get_text() == text) {
- return;
+ int data_size = 2;
+ const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
+ // Add a qualitative measurement to help the user assess whether a GPUParticlesCollisionSDF3D node is using a lot of VRAM.
+ String size_quality;
+ if (size_mb < 8.0) {
+ size_quality = TTR("Low");
+ } else if (size_mb < 32.0) {
+ size_quality = TTR("Moderate");
+ } else {
+ size_quality = TTR("High");
}
- // Color the label depending on the estimated performance level.
- Color color;
- if (size_mb <= 16.0 + CMP_EPSILON) {
- // Fast.
- color = bake_info->get_theme_color(SNAME("success_color"), SNAME("Editor"));
- } else if (size_mb <= 64.0 + CMP_EPSILON) {
- // Medium.
- color = bake_info->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- } else {
- // Slow.
- color = bake_info->get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ String text;
+ text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
+ text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
+ text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
+
+ // Only update the tooltip when needed to avoid constant redrawing.
+ if (bake->get_tooltip(Point2()) == text) {
+ return;
}
- bake_info->add_theme_color_override("font_color", color);
- bake_info->set_text(text);
+ bake->set_tooltip(text);
}
}
-void GPUParticlesCollisionSDFEditorPlugin::make_visible(bool p_visible) {
+void GPUParticlesCollisionSDF3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
bake_hb->show();
set_process(true);
@@ -107,26 +111,26 @@ void GPUParticlesCollisionSDFEditorPlugin::make_visible(bool p_visible) {
}
}
-EditorProgress *GPUParticlesCollisionSDFEditorPlugin::tmp_progress = nullptr;
+EditorProgress *GPUParticlesCollisionSDF3DEditorPlugin::tmp_progress = nullptr;
-void GPUParticlesCollisionSDFEditorPlugin::bake_func_begin(int p_steps) {
+void GPUParticlesCollisionSDF3DEditorPlugin::bake_func_begin(int p_steps) {
ERR_FAIL_COND(tmp_progress != nullptr);
tmp_progress = memnew(EditorProgress("bake_sdf", TTR("Bake SDF"), p_steps));
}
-void GPUParticlesCollisionSDFEditorPlugin::bake_func_step(int p_step, const String &p_description) {
+void GPUParticlesCollisionSDF3DEditorPlugin::bake_func_step(int p_step, const String &p_description) {
ERR_FAIL_COND(tmp_progress == nullptr);
tmp_progress->step(p_description, p_step, false);
}
-void GPUParticlesCollisionSDFEditorPlugin::bake_func_end() {
+void GPUParticlesCollisionSDF3DEditorPlugin::bake_func_end() {
ERR_FAIL_COND(tmp_progress == nullptr);
memdelete(tmp_progress);
tmp_progress = nullptr;
}
-void GPUParticlesCollisionSDFEditorPlugin::_sdf_save_path_and_bake(const String &p_path) {
+void GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake(const String &p_path) {
probe_file->hide();
if (col_sdf) {
Ref<Image> bake_img = col_sdf->bake();
@@ -164,10 +168,10 @@ void GPUParticlesCollisionSDFEditorPlugin::_sdf_save_path_and_bake(const String
}
}
-void GPUParticlesCollisionSDFEditorPlugin::_bind_methods() {
+void GPUParticlesCollisionSDF3DEditorPlugin::_bind_methods() {
}
-GPUParticlesCollisionSDFEditorPlugin::GPUParticlesCollisionSDFEditorPlugin(EditorNode *p_node) {
+GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
bake_hb = memnew(HBoxContainer);
bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -176,26 +180,22 @@ GPUParticlesCollisionSDFEditorPlugin::GPUParticlesCollisionSDFEditorPlugin(Edito
bake->set_flat(true);
bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
bake->set_text(TTR("Bake SDF"));
- bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDFEditorPlugin::_bake));
+ bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_bake));
bake_hb->add_child(bake);
- bake_info = memnew(Label);
- bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- bake_info->set_clip_text(true);
- bake_hb->add_child(bake_info);
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb);
col_sdf = nullptr;
probe_file = memnew(EditorFileDialog);
probe_file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
probe_file->add_filter("*.exr");
- probe_file->connect("file_selected", callable_mp(this, &GPUParticlesCollisionSDFEditorPlugin::_sdf_save_path_and_bake));
+ probe_file->connect("file_selected", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake));
get_editor_interface()->get_base_control()->add_child(probe_file);
probe_file->set_title(TTR("Select path for SDF Texture"));
- GPUParticlesCollisionSDF::bake_begin_function = bake_func_begin;
- GPUParticlesCollisionSDF::bake_step_function = bake_func_step;
- GPUParticlesCollisionSDF::bake_end_function = bake_func_end;
+ GPUParticlesCollisionSDF3D::bake_begin_function = bake_func_begin;
+ GPUParticlesCollisionSDF3D::bake_step_function = bake_func_step;
+ GPUParticlesCollisionSDF3D::bake_end_function = bake_func_end;
}
-GPUParticlesCollisionSDFEditorPlugin::~GPUParticlesCollisionSDFEditorPlugin() {
+GPUParticlesCollisionSDF3DEditorPlugin::~GPUParticlesCollisionSDF3DEditorPlugin() {
}
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
index 5a71fc44ef..ce7ca18293 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
@@ -36,13 +36,12 @@
#include "scene/3d/gpu_particles_collision_3d.h"
#include "scene/resources/material.h"
-class GPUParticlesCollisionSDFEditorPlugin : public EditorPlugin {
- GDCLASS(GPUParticlesCollisionSDFEditorPlugin, EditorPlugin);
+class GPUParticlesCollisionSDF3DEditorPlugin : public EditorPlugin {
+ GDCLASS(GPUParticlesCollisionSDF3DEditorPlugin, EditorPlugin);
- GPUParticlesCollisionSDF *col_sdf;
+ GPUParticlesCollisionSDF3D *col_sdf;
HBoxContainer *bake_hb;
- Label *bake_info;
Button *bake;
EditorNode *editor;
@@ -61,14 +60,14 @@ protected:
void _notification(int p_what);
public:
- virtual String get_name() const override { return "GPUParticlesCollisionSDF"; }
+ virtual String get_name() const override { return "GPUParticlesCollisionSDF3D"; }
bool has_main_screen() const override { return false; }
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- GPUParticlesCollisionSDFEditorPlugin(EditorNode *p_node);
- ~GPUParticlesCollisionSDFEditorPlugin();
+ GPUParticlesCollisionSDF3DEditorPlugin(EditorNode *p_node);
+ ~GPUParticlesCollisionSDF3DEditorPlugin();
};
#endif // GPU_PARTICLES_COLLISION_SDF_EDITOR_PLUGIN_H
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index 123087446c..d7b469cb74 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -44,10 +44,10 @@ void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
switch (err) {
case LightmapGI::BAKE_ERROR_NO_SAVE_PATH: {
String scene_path = lightmap->get_scene_file_path();
- if (scene_path == String()) {
+ if (scene_path.is_empty()) {
scene_path = lightmap->get_owner()->get_scene_file_path();
}
- if (scene_path == String()) {
+ if (scene_path.is_empty()) {
EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene and try again."));
break;
}
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 140d2952dd..bfbe6e26a9 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -69,8 +69,24 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en
material = p_material;
camera->set_environment(p_env);
if (!material.is_null()) {
- sphere_instance->set_material_override(material);
- box_instance->set_material_override(material);
+ Shader::Mode mode = p_material->get_shader_mode();
+ switch (mode) {
+ case Shader::MODE_CANVAS_ITEM:
+ layout_3d->hide();
+ layout_2d->show();
+ vc->hide();
+ rect_instance->set_material(material);
+ break;
+ case Shader::MODE_SPATIAL:
+ layout_2d->hide();
+ layout_3d->show();
+ vc->show();
+ sphere_instance->set_material_override(material);
+ box_instance->set_material_override(material);
+ break;
+ default:
+ break;
+ }
} else {
hide();
}
@@ -106,6 +122,21 @@ void MaterialEditor::_bind_methods() {
}
MaterialEditor::MaterialEditor() {
+ // canvas item
+
+ layout_2d = memnew(HBoxContainer);
+ layout_2d->set_alignment(BoxContainer::ALIGNMENT_CENTER);
+ add_child(layout_2d);
+ layout_2d->set_anchors_and_offsets_preset(PRESET_WIDE);
+
+ rect_instance = memnew(ColorRect);
+ layout_2d->add_child(rect_instance);
+ rect_instance->set_custom_minimum_size(Size2(150, 150) * EDSCALE);
+
+ layout_2d->set_visible(false);
+
+ // spatial
+
vc = memnew(SubViewportContainer);
vc->set_stretch(true);
add_child(vc);
@@ -154,12 +185,12 @@ MaterialEditor::MaterialEditor() {
set_custom_minimum_size(Size2(1, 150) * EDSCALE);
- HBoxContainer *hb = memnew(HBoxContainer);
- add_child(hb);
- hb->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
+ layout_3d = memnew(HBoxContainer);
+ add_child(layout_3d);
+ layout_3d->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
VBoxContainer *vb_shape = memnew(VBoxContainer);
- hb->add_child(vb_shape);
+ layout_3d->add_child(vb_shape);
sphere_switch = memnew(TextureButton);
sphere_switch->set_toggle_mode(true);
@@ -173,10 +204,10 @@ MaterialEditor::MaterialEditor() {
vb_shape->add_child(box_switch);
box_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(box_switch));
- hb->add_spacer();
+ layout_3d->add_spacer();
VBoxContainer *vb_light = memnew(VBoxContainer);
- hb->add_child(vb_light);
+ layout_3d->add_child(vb_light);
light_1_switch = memnew(TextureButton);
light_1_switch->set_toggle_mode(true);
@@ -207,8 +238,8 @@ bool EditorInspectorPluginMaterial::can_handle(Object *p_object) {
if (!material) {
return false;
}
-
- return material->get_shader_mode() == Shader::MODE_SPATIAL;
+ Shader::Mode mode = material->get_shader_mode();
+ return mode == Shader::MODE_SPATIAL || mode == Shader::MODE_CANVAS_ITEM;
}
void EditorInspectorPluginMaterial::parse_begin(Object *p_object) {
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 62549843f7..8262b8149d 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -39,6 +39,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/mesh_instance_3d.h"
+#include "scene/gui/color_rect.h"
#include "scene/resources/material.h"
class SubViewportContainer;
@@ -46,22 +47,27 @@ class SubViewportContainer;
class MaterialEditor : public Control {
GDCLASS(MaterialEditor, Control);
- SubViewportContainer *vc;
- SubViewport *viewport;
- MeshInstance3D *sphere_instance;
- MeshInstance3D *box_instance;
- DirectionalLight3D *light1;
- DirectionalLight3D *light2;
- Camera3D *camera;
+ HBoxContainer *layout_2d = nullptr;
+ ColorRect *rect_instance = nullptr;
+
+ SubViewportContainer *vc = nullptr;
+ SubViewport *viewport = nullptr;
+ MeshInstance3D *sphere_instance = nullptr;
+ MeshInstance3D *box_instance = nullptr;
+ DirectionalLight3D *light1 = nullptr;
+ DirectionalLight3D *light2 = nullptr;
+ Camera3D *camera = nullptr;
Ref<SphereMesh> sphere_mesh;
Ref<BoxMesh> box_mesh;
- TextureButton *sphere_switch;
- TextureButton *box_switch;
+ HBoxContainer *layout_3d = nullptr;
+
+ TextureButton *sphere_switch = nullptr;
+ TextureButton *box_switch = nullptr;
- TextureButton *light_1_switch;
- TextureButton *light_2_switch;
+ TextureButton *light_1_switch = nullptr;
+ TextureButton *light_2_switch = nullptr;
Ref<Material> material;
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 18e7480287..fd62f632dc 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -61,7 +61,7 @@ void MeshLibraryEditor::_menu_update_confirm(bool p_apply_xforms) {
cd_update->hide();
apply_xforms = p_apply_xforms;
String existing = mesh_library->get_meta("_editor_source_scene");
- ERR_FAIL_COND(existing == "");
+ ERR_FAIL_COND(existing.is_empty());
_import_scene_cbk(existing);
}
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 5514bccabb..517aca596a 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -48,7 +48,7 @@ void MultiMeshEditor::_populate() {
Ref<Mesh> mesh;
- if (mesh_source->get_text() == "") {
+ if (mesh_source->get_text().is_empty()) {
Ref<MultiMesh> multimesh;
multimesh = node->get_multimesh();
if (multimesh.is_null()) {
@@ -89,7 +89,7 @@ void MultiMeshEditor::_populate() {
}
}
- if (surface_source->get_text() == "") {
+ if (surface_source->get_text().is_empty()) {
err_dialog->set_text(TTR("No surface source specified."));
err_dialog->popup_centered();
return;
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 74fbef3caf..32355735cc 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -244,8 +244,10 @@ void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden)
RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
}
-void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) {
+void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) {
ERR_FAIL_COND(!spatial_node);
+ ERR_FAIL_COND_MSG(!p_mesh.is_valid(), "EditorNode3DGizmo.add_mesh() requires a valid Mesh resource.");
+
Instance ins;
ins.mesh = p_mesh;
@@ -2579,7 +2581,7 @@ void CPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
GPUParticles3DGizmoPlugin::GPUParticles3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
create_material("particles_material", gizmo_color);
- gizmo_color.a = 0.1;
+ 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_handle_material("handles");
@@ -2765,11 +2767,11 @@ int GPUParticlesCollision3DGizmoPlugin::get_priority() const {
String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
const Node3D *cs = p_gizmo->get_spatial_node();
- if (Object::cast_to<GPUParticlesCollisionSphere>(cs) || Object::cast_to<GPUParticlesAttractorSphere>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) {
return "Radius";
}
- if (Object::cast_to<GPUParticlesCollisionBox>(cs) || Object::cast_to<GPUParticlesAttractorBox>(cs) || Object::cast_to<GPUParticlesAttractorVectorField>(cs) || Object::cast_to<GPUParticlesCollisionSDF>(cs) || Object::cast_to<GPUParticlesCollisionHeightField>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionBox3D>(cs) || Object::cast_to<GPUParticlesAttractorBox3D>(cs) || Object::cast_to<GPUParticlesAttractorVectorField3D>(cs) || Object::cast_to<GPUParticlesCollisionSDF3D>(cs) || Object::cast_to<GPUParticlesCollisionHeightField3D>(cs)) {
return "Extents";
}
@@ -2779,11 +2781,11 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz
Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
const Node3D *cs = p_gizmo->get_spatial_node();
- if (Object::cast_to<GPUParticlesCollisionSphere>(cs) || Object::cast_to<GPUParticlesAttractorSphere>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) {
return p_gizmo->get_spatial_node()->call("get_radius");
}
- if (Object::cast_to<GPUParticlesCollisionBox>(cs) || Object::cast_to<GPUParticlesAttractorBox>(cs) || Object::cast_to<GPUParticlesAttractorVectorField>(cs) || Object::cast_to<GPUParticlesCollisionSDF>(cs) || Object::cast_to<GPUParticlesCollisionHeightField>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionBox3D>(cs) || Object::cast_to<GPUParticlesAttractorBox3D>(cs) || Object::cast_to<GPUParticlesAttractorVectorField3D>(cs) || Object::cast_to<GPUParticlesCollisionSDF3D>(cs) || Object::cast_to<GPUParticlesCollisionHeightField3D>(cs)) {
return Vector3(p_gizmo->get_spatial_node()->call("get_extents"));
}
@@ -2801,7 +2803,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
- if (Object::cast_to<GPUParticlesCollisionSphere>(sn) || Object::cast_to<GPUParticlesAttractorSphere>(sn)) {
+ if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) {
Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
@@ -2816,7 +2818,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
sn->call("set_radius", d);
}
- if (Object::cast_to<GPUParticlesCollisionBox>(sn) || Object::cast_to<GPUParticlesAttractorBox>(sn) || Object::cast_to<GPUParticlesAttractorVectorField>(sn) || Object::cast_to<GPUParticlesCollisionSDF>(sn) || Object::cast_to<GPUParticlesCollisionHeightField>(sn)) {
+ if (Object::cast_to<GPUParticlesCollisionBox3D>(sn) || Object::cast_to<GPUParticlesAttractorBox3D>(sn) || Object::cast_to<GPUParticlesAttractorVectorField3D>(sn) || Object::cast_to<GPUParticlesCollisionSDF3D>(sn) || Object::cast_to<GPUParticlesCollisionHeightField3D>(sn)) {
Vector3 axis;
axis[p_id] = 1.0;
Vector3 ra, rb;
@@ -2839,7 +2841,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
Node3D *sn = p_gizmo->get_spatial_node();
- if (Object::cast_to<GPUParticlesCollisionSphere>(sn) || Object::cast_to<GPUParticlesAttractorSphere>(sn)) {
+ if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) {
if (p_cancel) {
sn->call("set_radius", p_restore);
return;
@@ -2852,7 +2854,7 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *
ur->commit_action();
}
- if (Object::cast_to<GPUParticlesCollisionBox>(sn) || Object::cast_to<GPUParticlesAttractorBox>(sn) || Object::cast_to<GPUParticlesAttractorVectorField>(sn) || Object::cast_to<GPUParticlesCollisionSDF>(sn) || Object::cast_to<GPUParticlesCollisionHeightField>(sn)) {
+ if (Object::cast_to<GPUParticlesCollisionBox3D>(sn) || Object::cast_to<GPUParticlesAttractorBox3D>(sn) || Object::cast_to<GPUParticlesAttractorVectorField3D>(sn) || Object::cast_to<GPUParticlesCollisionSDF3D>(sn) || Object::cast_to<GPUParticlesCollisionHeightField3D>(sn)) {
if (p_cancel) {
sn->call("set_extents", p_restore);
return;
@@ -2869,7 +2871,6 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *
void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Node3D *cs = p_gizmo->get_spatial_node();
- print_line("redraw request " + itos(cs != nullptr));
p_gizmo->clear();
const Ref<Material> material =
@@ -2879,7 +2880,7 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Ref<Material> handles_material = get_material("handles");
- if (Object::cast_to<GPUParticlesCollisionSphere>(cs) || Object::cast_to<GPUParticlesAttractorSphere>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) {
float r = cs->call("get_radius");
Vector<Vector3> points;
@@ -2921,7 +2922,7 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_handles(handles, handles_material);
}
- if (Object::cast_to<GPUParticlesCollisionBox>(cs) || Object::cast_to<GPUParticlesAttractorBox>(cs) || Object::cast_to<GPUParticlesAttractorVectorField>(cs) || Object::cast_to<GPUParticlesCollisionSDF>(cs) || Object::cast_to<GPUParticlesCollisionHeightField>(cs)) {
+ if (Object::cast_to<GPUParticlesCollisionBox3D>(cs) || Object::cast_to<GPUParticlesAttractorBox3D>(cs) || Object::cast_to<GPUParticlesAttractorVectorField3D>(cs) || Object::cast_to<GPUParticlesCollisionSDF3D>(cs) || Object::cast_to<GPUParticlesCollisionHeightField3D>(cs)) {
Vector<Vector3> lines;
AABB aabb;
aabb.position = -cs->call("get_extents").operator Vector3();
@@ -2946,9 +2947,9 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_collision_segments(lines);
p_gizmo->add_handles(handles, handles_material);
- GPUParticlesCollisionSDF *col_sdf = Object::cast_to<GPUParticlesCollisionSDF>(cs);
+ GPUParticlesCollisionSDF3D *col_sdf = Object::cast_to<GPUParticlesCollisionSDF3D>(cs);
if (col_sdf) {
- static const int subdivs[GPUParticlesCollisionSDF::RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
+ static const int subdivs[GPUParticlesCollisionSDF3D::RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
int subdiv = subdivs[col_sdf->get_resolution()];
float cell_size = aabb.get_longest_axis_size() / subdiv;
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index 56e4ad5518..cf9a464b69 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -45,7 +45,7 @@ class EditorNode3DGizmo : public Node3DGizmo {
struct Instance {
RID instance;
- Ref<ArrayMesh> mesh;
+ Ref<Mesh> mesh;
Ref<Material> material;
Ref<SkinReference> skin_reference;
bool extra_margin = false;
@@ -95,7 +95,7 @@ protected:
public:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
- void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
+ void add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index d3b462cda5..f49b749046 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1291,7 +1291,8 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
selection_menu->set_item_tooltip(i, String(spat->get_name()) + "\nType: " + spat->get_class() + "\nPath: " + node_path);
}
- selection_menu->set_position(get_screen_transform().xform(b->get_position()));
+ selection_menu->set_position(get_screen_position() + b->get_position());
+ selection_menu->reset_size();
selection_menu->popup();
}
}
@@ -1749,7 +1750,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} else {
const bool movement_threshold_passed = _edit.original_mouse_pos.distance_to(_edit.mouse_pos) > 8 * EDSCALE;
if (clicked.is_valid() && movement_threshold_passed) {
- _compute_edit(_edit.mouse_pos);
+ _compute_edit(_edit.original_mouse_pos);
clicked = ObjectID();
_edit.mode = TRANSFORM_TRANSLATE;
@@ -2986,7 +2987,7 @@ static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2
surface.draw_texture(icon, icon_pos);
// Draw text below the bar (for speed/zoom information).
- surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text, HALIGN_LEFT, -1.f, font_size);
+ surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text, HORIZONTAL_ALIGNMENT_LEFT, -1.f, font_size);
}
void Node3DEditorViewport::_draw() {
@@ -3026,9 +3027,9 @@ void Node3DEditorViewport::_draw() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
Point2 msgpos = Point2(5, get_size().y - 20);
- font->draw_string(ci, msgpos + Point2(1, 1), message, HALIGN_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
- font->draw_string(ci, msgpos + Point2(-1, -1), message, HALIGN_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
- font->draw_string(ci, msgpos, message, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 1));
+ font->draw_string(ci, msgpos + Point2(1, 1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
+ font->draw_string(ci, msgpos + Point2(-1, -1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
+ font->draw_string(ci, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
}
if (_edit.mode == TRANSFORM_ROTATE) {
@@ -4048,7 +4049,23 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
if (mesh != nullptr) {
MeshInstance3D *mesh_instance = memnew(MeshInstance3D);
mesh_instance->set_mesh(mesh);
- mesh_instance->set_name(path.get_file().get_basename());
+
+ // Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
+ String name = path.get_file().get_basename();
+ switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) {
+ case NAME_CASING_PASCAL_CASE:
+ name = name.capitalize().replace(" ", "");
+ break;
+ case NAME_CASING_CAMEL_CASE:
+ name = name.capitalize().replace(" ", "");
+ name[0] = name.to_lower()[0];
+ break;
+ case NAME_CASING_SNAKE_CASE:
+ name = name.capitalize().replace(" ", "_").to_lower();
+ break;
+ }
+ mesh_instance->set_name(name);
+
instantiated_scene = mesh_instance;
} else {
if (!scene.is_valid()) { // invalid scene
@@ -4063,7 +4080,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
return false;
}
- if (editor->get_edited_scene()->get_scene_file_path() != "") { // cyclical instancing
+ if (!editor->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing
if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
return false;
@@ -4221,10 +4238,9 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
if (root_node) {
target_node = root_node;
} else {
- accept->set_text(TTR("Cannot drag and drop into scene with no root node."));
- accept->popup_centered();
- _remove_preview();
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ target_node = get_tree()->get_edited_scene_root();
}
} else {
accept->set_text(TTR("Cannot drag and drop into multiple selected nodes."));
@@ -4428,7 +4444,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
cinema_label = memnew(Label);
cinema_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
- cinema_label->set_align(Label::ALIGN_CENTER);
+ cinema_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
surface->add_child(cinema_label);
cinema_label->set_text(TTR("Cinematic Preview"));
cinema_label->hide();
@@ -4439,7 +4455,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
locked_label->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -10 * EDSCALE);
locked_label->set_h_grow_direction(GROW_DIRECTION_END);
locked_label->set_v_grow_direction(GROW_DIRECTION_BEGIN);
- locked_label->set_align(Label::ALIGN_CENTER);
+ locked_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
surface->add_child(locked_label);
locked_label->set_text(TTR("View Rotation Locked"));
locked_label->hide();
@@ -6631,6 +6647,7 @@ void Node3DEditor::unhandled_key_input(const Ref<InputEvent> &p_event) {
void Node3DEditor::_sun_environ_settings_pressed() {
Vector2 pos = sun_environ_settings->get_screen_position() + sun_environ_settings->get_size();
sun_environ_popup->set_position(pos - Vector2(sun_environ_popup->get_contents_minimum_size().width / 2, 0));
+ sun_environ_popup->reset_size();
sun_environ_popup->popup();
}
@@ -7644,7 +7661,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
sun_title->set_theme_type_variation("HeaderSmall");
sun_vb->add_child(sun_title);
sun_title->set_text(TTR("Preview Sun"));
- sun_title->set_align(Label::ALIGN_CENTER);
+ sun_title->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
CenterContainer *sun_direction_center = memnew(CenterContainer);
sun_direction = memnew(Control);
@@ -7732,8 +7749,8 @@ void fragment() {
sun_state = memnew(Label);
sun_environ_hb->add_child(sun_state);
- sun_state->set_align(Label::ALIGN_CENTER);
- sun_state->set_valign(Label::VALIGN_CENTER);
+ sun_state->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ sun_state->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
sun_state->set_h_size_flags(SIZE_EXPAND_FILL);
VSeparator *sc = memnew(VSeparator);
@@ -7751,7 +7768,7 @@ void fragment() {
environ_vb->add_child(environ_title);
environ_title->set_text(TTR("Preview Environment"));
- environ_title->set_align(Label::ALIGN_CENTER);
+ environ_title->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
environ_sky_color = memnew(ColorPickerButton);
environ_sky_color->set_edit_alpha(false);
@@ -7799,8 +7816,8 @@ void fragment() {
environ_state = memnew(Label);
sun_environ_hb->add_child(environ_state);
- environ_state->set_align(Label::ALIGN_CENTER);
- environ_state->set_valign(Label::VALIGN_CENTER);
+ environ_state->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ environ_state->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
environ_state->set_h_size_flags(SIZE_EXPAND_FILL);
preview_sun = memnew(DirectionalLight3D);
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
index 0328b1bea6..1e85b19a84 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
@@ -42,10 +42,10 @@ void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) {
switch (err) {
case OccluderInstance3D::BAKE_ERROR_NO_SAVE_PATH: {
String scene_path = occluder_instance->get_scene_file_path();
- if (scene_path == String()) {
+ if (scene_path.is_empty()) {
scene_path = occluder_instance->get_owner()->get_scene_file_path();
}
- if (scene_path == String()) {
+ if (scene_path.is_empty()) {
EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for the occluder.\nSave your scene and try again."));
break;
}
diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp
index c949621e28..7f3ebc01d5 100644
--- a/editor/plugins/ot_features_plugin.cpp
+++ b/editor/plugins/ot_features_plugin.cpp
@@ -136,6 +136,7 @@ void OpenTypeFeaturesAdd::update_property() {
void OpenTypeFeaturesAdd::_features_menu() {
Size2 size = get_size();
menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
+ menu->reset_size();
menu->popup();
}
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index b1e104e680..71955cf62c 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -51,7 +51,7 @@ PhysicalBone3DEditor::PhysicalBone3DEditor(EditorNode *p_editor) :
editor(p_editor) {
spatial_editor_hb = memnew(HBoxContainer);
spatial_editor_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- spatial_editor_hb->set_alignment(BoxContainer::ALIGN_BEGIN);
+ spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_BEGIN);
Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb);
spatial_editor_hb->add_child(memnew(VSeparator));
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 79cfcbec64..affcab9e7d 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -170,7 +170,7 @@ void Polygon2DEditor::_update_bone_list() {
if (np.get_name_count()) {
name = np.get_name(np.get_name_count() - 1);
}
- if (name == String()) {
+ if (name.is_empty()) {
name = "Bone " + itos(i);
}
cb->set_text(name);
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index eae6916a92..30b7a26aab 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -110,7 +110,7 @@ void ResourcePreloaderEditor::_item_edited() {
return;
}
- if (new_name == "" || new_name.find("\\") != -1 || new_name.find("/") != -1 || preloader->has_resource(new_name)) {
+ if (new_name.is_empty() || new_name.find("\\") != -1 || new_name.find("/") != -1 || preloader->has_resource(new_name)) {
s->set_text(0, old_name);
return;
}
@@ -147,10 +147,10 @@ void ResourcePreloaderEditor::_paste_pressed() {
}
String name = r->get_name();
- if (name == "") {
+ if (name.is_empty()) {
name = r->get_path().get_file();
}
- if (name == "") {
+ if (name.is_empty()) {
name = r->get_class();
}
@@ -300,7 +300,7 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
if (r.is_valid()) {
String basename;
- if (r->get_name() != "") {
+ if (!r->get_name().is_empty()) {
basename = r->get_name();
} else if (r->get_path().is_resource_file()) {
basename = r->get_path().get_basename();
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 0f3c50a861..d1830bf5af 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -89,7 +89,7 @@ void EditorPropertyRootMotion::_node_assign() {
String accum;
for (int i = 0; i < path.get_name_count(); i++) {
String name = path.get_name(i);
- if (accum != String()) {
+ if (!accum.is_empty()) {
accum += "/";
}
accum += name;
@@ -277,7 +277,7 @@ bool EditorInspectorRootMotionPlugin::can_handle(Object *p_object) {
bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) {
EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion);
- if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
+ if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !p_hint_text.is_empty()) {
editor->setup(p_hint_text);
}
add_property_editor(p_path, editor);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index aeb6ba13d5..caaac2c7d3 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -179,7 +179,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() {
for (const String &comment : comments) {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
- highlighter->add_color_region(beg, end, comment_color, end == "");
+ highlighter->add_color_region(beg, end, comment_color, end.is_empty());
}
/* Strings */
@@ -189,7 +189,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() {
for (const String &string : strings) {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
- highlighter->add_color_region(beg, end, string_color, end == "");
+ highlighter->add_color_region(beg, end, string_color, end.is_empty());
}
}
}
@@ -321,7 +321,7 @@ void ScriptEditorQuickOpen::_update_search() {
for (int i = 0; i < functions.size(); i++) {
String file = functions[i];
- if ((search_box->get_text() == "" || file.findn(search_box->get_text()) != -1)) {
+ if ((search_box->get_text().is_empty() || file.findn(search_box->get_text()) != -1)) {
TreeItem *ti = search_options->create_item(root);
ti->set_text(0, file);
if (root->get_first_child() == ti) {
@@ -392,7 +392,7 @@ ScriptEditor *ScriptEditor::script_editor = nullptr;
String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) {
String val = EditorDebuggerNode::get_singleton()->get_var_value(p_text);
- if (val != String()) {
+ if (!val.is_empty()) {
return p_text + ": " + val;
} else {
return String();
@@ -1679,7 +1679,7 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
String base = script->get_path();
loaded_scripts.insert(base);
- if (base.begins_with("local://") || base == "") {
+ if (base.begins_with("local://") || base.is_empty()) {
continue;
}
@@ -1831,7 +1831,7 @@ void ScriptEditor::_update_members_overview() {
for (int i = 0; i < functions.size(); i++) {
String filter = filter_methods->get_text();
String name = functions[i].get_slice(":", 0);
- if (filter == "" || filter.is_subsequence_ofi(name)) {
+ if (filter.is_empty() || filter.is_subsequence_ofi(name)) {
members_overview->add_item(name);
members_overview->set_item_metadata(members_overview->get_item_count() - 1, functions[i].get_slice(":", 1).to_int() - 1);
}
@@ -2076,7 +2076,7 @@ void ScriptEditor::_update_script_names() {
Vector<_ScriptEditorItemData> sedata_filtered;
for (int i = 0; i < sedata.size(); i++) {
String filter = filter_scripts->get_text();
- if (filter == "" || filter.is_subsequence_ofi(sedata[i].name)) {
+ if (filter.is_empty() || filter.is_subsequence_ofi(sedata[i].name)) {
sedata_filtered.push_back(sedata[i]);
}
}
@@ -2648,7 +2648,7 @@ void ScriptEditor::_editor_settings_changed() {
_update_autosave_timer();
- if (current_theme == "") {
+ if (current_theme.is_empty()) {
current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme");
} else if (current_theme != String(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))) {
current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme");
@@ -2840,7 +2840,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
for (int i = 0; i < files.size(); i++) {
String file = files[i];
- if (file == "" || !FileAccess::exists(file)) {
+ if (file.is_empty() || !FileAccess::exists(file)) {
continue;
}
if (ResourceLoader::exists(file, "Script")) {
@@ -2920,7 +2920,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
int num_tabs_before = tab_container->get_child_count();
for (int i = 0; i < files.size(); i++) {
String file = files[i];
- if (file == "" || !FileAccess::exists(file)) {
+ if (file.is_empty() || !FileAccess::exists(file)) {
continue;
}
@@ -3055,7 +3055,7 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_sort"), WINDOW_SORT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/toggle_scripts_panel"), TOGGLE_SCRIPTS_PANEL);
- context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ context_menu->set_position(get_screen_position() + get_local_mouse_position());
context_menu->reset_size();
context_menu->popup();
}
@@ -3126,7 +3126,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
for (int i = 0; i < helps.size(); i++) {
String path = helps[i];
- if (path == "") { // invalid, skip
+ if (path.is_empty()) { // invalid, skip
continue;
}
_help_class_open(path);
@@ -3197,7 +3197,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
}
void ScriptEditor::_help_class_open(const String &p_class) {
- if (p_class == "") {
+ if (p_class.is_empty()) {
return;
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 30a4cef8ca..d5af7c5b38 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -90,7 +90,7 @@ ConnectionInfoDialog::ConnectionInfoDialog() {
add_child(vbc);
method = memnew(Label);
- method->set_align(Label::ALIGN_CENTER);
+ method->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
vbc->add_child(method);
tree = memnew(Tree);
@@ -205,7 +205,7 @@ void ScriptTextEditor::_set_theme_for_script() {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
if (!text_edit->has_string_delimiter(beg)) {
- text_edit->add_string_delimiter(beg, end, end == "");
+ text_edit->add_string_delimiter(beg, end, end.is_empty());
}
if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) {
@@ -219,7 +219,7 @@ void ScriptTextEditor::_set_theme_for_script() {
for (const String &comment : comments) {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
- text_edit->add_comment_delimiter(beg, end, end == "");
+ text_edit->add_comment_delimiter(beg, end, end.is_empty());
if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) {
text_edit->add_auto_brace_completion_pair(beg, end);
@@ -381,7 +381,7 @@ String ScriptTextEditor::get_name() {
name = TTR("[unsaved]");
} else if (script->is_built_in()) {
const String &script_name = script->get_name();
- if (script_name != "") {
+ if (!script_name.is_empty()) {
// If the built-in script has a custom resource name defined,
// display the built-in script name as follows: `ResourceName (scene_file.tscn)`
name = vformat("%s (%s)", script_name, name.get_slice("::", 0));
@@ -990,7 +990,7 @@ void ScriptTextEditor::_gutter_clicked(int p_line, int p_gutter) {
}
String method = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter);
- if (method == "") {
+ if (method.is_empty()) {
return;
}
@@ -1137,7 +1137,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
if (expression.parse(line) == OK) {
Variant result = expression.execute(Array(), Variant(), false);
- if (expression.get_error_text() == "") {
+ if (expression.get_error_text().is_empty()) {
results.push_back(whitespace + result.get_construct_string());
} else {
results.push_back(line);
@@ -1263,19 +1263,19 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case HELP_CONTEXTUAL: {
String text = tx->get_selected_text();
- if (text == "") {
+ if (text.is_empty()) {
text = tx->get_word_under_caret();
}
- if (text != "") {
+ if (!text.is_empty()) {
emit_signal(SNAME("request_help"), text);
}
} break;
case LOOKUP_SYMBOL: {
String text = tx->get_word_under_caret();
- if (text == "") {
+ if (text.is_empty()) {
text = tx->get_selected_text();
}
- if (text != "") {
+ if (!text.is_empty()) {
_lookup_symbol(text, tx->get_caret_line(), tx->get_caret_column());
}
} break;
@@ -1560,10 +1560,10 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
String word_at_pos = tx->get_word_at_pos(local_pos);
- if (word_at_pos == "") {
+ if (word_at_pos.is_empty()) {
word_at_pos = tx->get_word_under_caret();
}
- if (word_at_pos == "") {
+ if (word_at_pos.is_empty()) {
word_at_pos = tx->get_selected_text();
}
@@ -1611,7 +1611,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
float alpha = color.size() > 3 ? color[3] : 1.0f;
color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
}
- color_panel->set_position(get_global_transform().xform(local_pos));
+ color_panel->set_position(get_screen_position() + local_pos);
} else {
has_color = false;
}
@@ -1688,7 +1688,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->set_item_disabled(context_menu->get_item_index(EDIT_UNDO), !tx->has_undo());
context_menu->set_item_disabled(context_menu->get_item_index(EDIT_REDO), !tx->has_redo());
- context_menu->set_position(get_global_transform().xform(p_pos));
+ context_menu->set_position(get_screen_position() + p_pos);
context_menu->reset_size();
context_menu->popup();
}
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 7c1fda77bb..fa23ccf200 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -204,7 +204,13 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
ShaderLanguage sl;
String calltip;
- sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip);
+ ShaderLanguage::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()));
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode()));
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_global_variable_type;
+
+ sl.complete(p_code, info, r_options, calltip);
get_text_editor()->set_code_hint(calltip);
}
@@ -216,12 +222,18 @@ void ShaderTextEditor::_validate_script() {
//List<StringName> params;
//shader->get_param_list(&params);
+ ShaderLanguage::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()));
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode()));
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_global_variable_type;
+
ShaderLanguage sl;
sl.enable_warning_checking(saved_warnings_enabled);
sl.set_warning_flags(saved_warning_flags);
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
+ Error err = sl.compile(code, info);
if (err != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
@@ -645,7 +657,7 @@ void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- context_menu->set_position(get_global_transform().xform(p_position));
+ context_menu->set_position(get_screen_position() + p_position);
context_menu->reset_size();
context_menu->popup();
}
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index 1e62261244..517de1901f 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -97,7 +97,7 @@ void ShaderFileEditor::_version_selected(int p_option) {
error_text->push_font(get_theme_font(SNAME("source"), SNAME("EditorFonts")));
- if (error == String()) {
+ if (error.is_empty()) {
error_text->add_text(TTR("Shader stage compiled without errors."));
} else {
error_text->add_text(error);
@@ -107,7 +107,7 @@ void ShaderFileEditor::_version_selected(int p_option) {
void ShaderFileEditor::_update_options() {
ERR_FAIL_COND(shader_file.is_null());
- if (shader_file->get_base_error() != String()) {
+ if (!shader_file->get_base_error().is_empty()) {
stage_hb->hide();
versions->hide();
error_text->clear();
@@ -136,7 +136,7 @@ void ShaderFileEditor::_update_options() {
for (int i = 0; i < version_list.size(); i++) {
String title = version_list[i];
- if (title == "") {
+ if (title.is_empty()) {
title = "default";
}
@@ -148,7 +148,7 @@ void ShaderFileEditor::_update_options() {
bool failed = false;
for (int j = 0; j < RD::SHADER_STAGE_MAX; j++) {
String error = bytecode->get_stage_compile_error(RD::ShaderStage(j));
- if (error != String()) {
+ if (!error.is_empty()) {
failed = true;
}
}
@@ -182,7 +182,7 @@ void ShaderFileEditor::_update_options() {
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i));
String error = bytecode->get_stage_compile_error(RD::ShaderStage(i));
- bool disable = error == String() && bc.is_empty();
+ bool disable = error.is_empty() && bc.is_empty();
stages[i]->set_disabled(disable);
if (!disable) {
if (stages[i]->is_pressed()) {
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 5f21c8c881..bb5ef0f6eb 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -964,6 +964,7 @@ void Skeleton3DEditor::select_bone(int p_idx) {
Skeleton3DEditor::~Skeleton3DEditor() {
if (skeleton) {
+ select_bone(-1);
#ifdef TOOLS_ENABLED
skeleton->disconnect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible));
skeleton->disconnect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed));
@@ -973,6 +974,7 @@ Skeleton3DEditor::~Skeleton3DEditor() {
#endif
handles_mesh_instance->get_parent()->remove_child(handles_mesh_instance);
}
+ edit_mode_toggled(false);
handles_mesh_instance->queue_delete();
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index eb5e527640..48b10d5a8b 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -526,8 +526,6 @@ Sprite2DEditor::Sprite2DEditor() {
debug_uv_dialog->add_child(vb);
ScrollContainer *scroll = memnew(ScrollContainer);
scroll->set_custom_minimum_size(Size2(800, 500) * EDSCALE);
- scroll->set_enable_h_scroll(true);
- scroll->set_enable_v_scroll(true);
vb->add_margin_child(TTR("Preview:"), scroll, true);
debug_uv = memnew(Control);
debug_uv->connect("draw", callable_mp(this, &Sprite2DEditor::_debug_uv_draw));
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index d455f4618b..316ef7b195 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -1238,8 +1238,6 @@ SpriteFramesEditor::SpriteFramesEditor() {
split_sheet_preview->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_preview_input));
split_sheet_scroll = memnew(ScrollContainer);
- split_sheet_scroll->set_enable_h_scroll(true);
- split_sheet_scroll->set_enable_v_scroll(true);
split_sheet_scroll->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_scroll_input));
split_sheet_panel->add_child(split_sheet_scroll);
CenterContainer *cc = memnew(CenterContainer);
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index e252792c43..cbde382d67 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -71,7 +71,7 @@ String TextEditor::get_name() {
name = TTR("[unsaved]");
} else if (text_file->is_built_in()) {
const String &text_file_name = text_file->get_name();
- if (text_file_name != "") {
+ if (!text_file_name.is_empty()) {
// If the built-in text_file has a custom resource name defined,
// display the built-in text_file name as follows: `ResourceName (scene_file.tscn)`
name = vformat("%s (%s)", text_file_name, name.get_slice("::", 0));
@@ -507,7 +507,7 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is
context_menu->set_item_disabled(context_menu->get_item_index(EDIT_UNDO), !tx->has_undo());
context_menu->set_item_disabled(context_menu->get_item_index(EDIT_REDO), !tx->has_redo());
- context_menu->set_position(get_global_transform().xform(p_position));
+ context_menu->set_position(get_screen_position() + p_position);
context_menu->reset_size();
context_menu->popup();
}
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index f94439f344..89016b8758 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -941,7 +941,7 @@ ThemeItemImportTree::ThemeItemImportTree() {
ScrollContainer *import_bulk_sc = memnew(ScrollContainer);
import_bulk_sc->set_custom_minimum_size(Size2(260.0, 0.0) * EDSCALE);
- import_bulk_sc->set_enable_h_scroll(false);
+ import_bulk_sc->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
import_main_hb->add_child(import_bulk_sc);
VBoxContainer *import_bulk_vb = memnew(VBoxContainer);
import_bulk_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1115,7 +1115,7 @@ ThemeItemImportTree::ThemeItemImportTree() {
label_set->add_child(select_items_label);
HBoxContainer *button_set = memnew(HBoxContainer);
- button_set->set_alignment(BoxContainer::ALIGN_END);
+ button_set->set_alignment(BoxContainer::ALIGNMENT_END);
all_set->add_child(button_set);
select_all_items_button->set_flat(true);
select_all_items_button->set_tooltip(select_all_items_tooltip);
@@ -1130,7 +1130,7 @@ ThemeItemImportTree::ThemeItemImportTree() {
button_set->add_child(deselect_all_items_button);
deselect_all_items_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_deselect_all_data_type_pressed), varray(i));
- total_selected_items_label->set_align(Label::ALIGN_RIGHT);
+ total_selected_items_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
total_selected_items_label->hide();
import_bulk_vb->add_child(total_selected_items_label);
@@ -1783,7 +1783,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() {
set_hide_on_ok(false); // Closing may require a confirmation in some cases.
tc = memnew(TabContainer);
- tc->set_tab_align(TabContainer::TabAlign::ALIGN_LEFT);
+ tc->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
add_child(tc);
// Edit Items tab.
@@ -1909,8 +1909,8 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() {
edit_items_message = memnew(Label);
edit_items_message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
edit_items_message->set_mouse_filter(Control::MOUSE_FILTER_STOP);
- edit_items_message->set_align(Label::ALIGN_CENTER);
- edit_items_message->set_valign(Label::VALIGN_CENTER);
+ edit_items_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ edit_items_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
edit_items_message->set_autowrap_mode(Label::AUTOWRAP_WORD);
edit_items_tree->add_child(edit_items_message);
@@ -2113,7 +2113,7 @@ VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
ScrollContainer *items_sc = memnew(ScrollContainer);
items_sc->set_v_size_flags(SIZE_EXPAND_FILL);
- items_sc->set_enable_h_scroll(false);
+ items_sc->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
items_tab->add_child(items_sc);
VBoxContainer *items_list = memnew(VBoxContainer);
items_list->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -2581,11 +2581,11 @@ void ThemeTypeEditor::_update_type_items() {
}
// Various type settings.
- if (ClassDB::class_exists(edited_type)) {
+ if (edited_type.is_empty() || ClassDB::class_exists(edited_type)) {
type_variation_edit->set_editable(false);
type_variation_edit->set_text("");
type_variation_button->hide();
- type_variation_locked->show();
+ type_variation_locked->set_visible(!edited_type.is_empty());
} else {
type_variation_edit->set_editable(true);
type_variation_edit->set_text(edited_theme->get_type_variation_base(edited_type));
@@ -3102,7 +3102,7 @@ ThemeTypeEditor::ThemeTypeEditor() {
ScrollContainer *type_settings_sc = memnew(ScrollContainer);
type_settings_sc->set_v_size_flags(SIZE_EXPAND_FILL);
- type_settings_sc->set_enable_h_scroll(false);
+ type_settings_sc->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
type_settings_tab->add_child(type_settings_sc);
VBoxContainer *type_settings_list = memnew(VBoxContainer);
type_settings_list->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -3129,7 +3129,7 @@ ThemeTypeEditor::ThemeTypeEditor() {
type_variation_locked = memnew(Label);
type_variation_vb->add_child(type_variation_locked);
- type_variation_locked->set_align(Label::ALIGN_CENTER);
+ type_variation_locked->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
type_variation_locked->set_autowrap_mode(Label::AUTOWRAP_WORD);
type_variation_locked->set_text(TTR("A type associated with a built-in class cannot be marked as a variation of another type."));
type_variation_locked->hide();
@@ -3329,7 +3329,7 @@ ThemeEditor::ThemeEditor() {
preview_tabs_vb->add_child(preview_tabs_content);
preview_tabs = memnew(TabBar);
- preview_tabs->set_tab_align(TabBar::ALIGN_LEFT);
+ preview_tabs->set_tab_alignment(TabBar::ALIGNMENT_LEFT);
preview_tabs->set_h_size_flags(SIZE_EXPAND_FILL);
preview_tabbar_hb->add_child(preview_tabs);
preview_tabs->connect("tab_changed", callable_mp(this, &ThemeEditor::_change_preview_tab));
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index f13fcb005f..9a5ecd3802 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -47,7 +47,7 @@ void ThemeEditorPreview::add_preview_overlay(Control *p_overlay) {
void ThemeEditorPreview::_propagate_redraw(Control *p_at) {
p_at->notification(NOTIFICATION_THEME_CHANGED);
- p_at->minimum_size_changed();
+ p_at->update_minimum_size();
p_at->update();
for (int i = 0; i < p_at->get_child_count(); i++) {
Control *a = Object::cast_to<Control>(p_at->get_child(i));
@@ -136,7 +136,7 @@ void ThemeEditorPreview::_draw_picker_overlay() {
Point2 label_pos = highlight_label_rect.position;
label_pos.y += highlight_label_rect.size.y - margin_bottom;
label_pos.x += margin_left;
- picker_overlay->draw_string(theme_cache.preview_picker_font, label_pos, highlight_name, HALIGN_LEFT, -1, theme_cache.font_size);
+ picker_overlay->draw_string(theme_cache.preview_picker_font, label_pos, highlight_name, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size);
}
}
@@ -157,6 +157,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
emit_signal(SNAME("control_picked"), theme_type);
picker_button->set_pressed(false);
picker_overlay->set_visible(false);
+ return;
}
}
@@ -167,6 +168,9 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
hovered_control = _find_hovered_control(preview_content, mp);
picker_overlay->update();
}
+
+ // Forward input to the scroll container underneath to allow scrolling.
+ preview_container->gui_input(p_event);
}
void ThemeEditorPreview::_reset_picker_overlay() {
@@ -223,9 +227,7 @@ ThemeEditorPreview::ThemeEditorPreview() {
preview_body->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(preview_body);
- ScrollContainer *preview_container = memnew(ScrollContainer);
- preview_container->set_enable_v_scroll(true);
- preview_container->set_enable_h_scroll(true);
+ preview_container = memnew(ScrollContainer);
preview_body->add_child(preview_container);
MarginContainer *preview_root = memnew(MarginContainer);
@@ -363,7 +365,7 @@ DefaultThemeEditorPreview::DefaultThemeEditorPreview() {
vhb->add_child(memnew(VSeparator));
VBoxContainer *hvb = memnew(VBoxContainer);
vhb->add_child(hvb);
- hvb->set_alignment(BoxContainer::ALIGN_CENTER);
+ hvb->set_alignment(BoxContainer::ALIGNMENT_CENTER);
hvb->set_h_size_flags(SIZE_EXPAND_FILL);
hvb->add_child(memnew(HSlider));
HScrollBar *hsb = memnew(HScrollBar);
diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h
index f973119257..73422b4fba 100644
--- a/editor/plugins/theme_editor_preview.h
+++ b/editor/plugins/theme_editor_preview.h
@@ -55,6 +55,7 @@
class ThemeEditorPreview : public VBoxContainer {
GDCLASS(ThemeEditorPreview, VBoxContainer);
+ ScrollContainer *preview_container;
ColorRect *preview_bg;
MarginContainer *preview_overlay;
Control *picker_overlay;
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index efccac7b74..e4a16274fe 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -309,8 +309,8 @@ AtlasMergingDialog::AtlasMergingDialog() {
select_2_atlases_label = memnew(Label);
select_2_atlases_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
select_2_atlases_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- select_2_atlases_label->set_align(Label::ALIGN_CENTER);
- select_2_atlases_label->set_valign(Label::VALIGN_CENTER);
+ select_2_atlases_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ select_2_atlases_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
select_2_atlases_label->set_text(TTR("Please select two atlases or more."));
atlas_merging_right_panel->add_child(select_2_atlases_label);
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 604143ef93..6a3261cbee 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -616,7 +616,7 @@ TileAtlasView::TileAtlasView() {
Label *base_tile_label = memnew(Label);
base_tile_label->set_mouse_filter(Control::MOUSE_FILTER_PASS);
base_tile_label->set_text(TTR("Base Tiles"));
- base_tile_label->set_align(Label::ALIGN_CENTER);
+ base_tile_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
left_vbox->add_child(base_tile_label);
base_tiles_root_control = memnew(Control);
@@ -660,7 +660,7 @@ TileAtlasView::TileAtlasView() {
Label *alternative_tiles_label = memnew(Label);
alternative_tiles_label->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
alternative_tiles_label->set_text(TTR("Alternative Tiles"));
- alternative_tiles_label->set_align(Label::ALIGN_CENTER);
+ alternative_tiles_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
right_vbox->add_child(alternative_tiles_label);
alternative_tiles_root_control = memnew(Control);
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 44cf6b42bc..5ded607ab5 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -218,7 +218,7 @@ void GenericTilePolygonEditor::_base_control_draw() {
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
String text = multiple_polygon_mode ? vformat("%d:%d", tinted_polygon_index, tinted_point_index) : vformat("%d", tinted_point_index);
Size2 text_size = font->get_string_size(text, font_size);
- base_control->draw_string(font, xform.xform(polygons[tinted_polygon_index][tinted_point_index]) - text_size * 0.5, text, HALIGN_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
+ base_control->draw_string(font, xform.xform(polygons[tinted_polygon_index][tinted_point_index]) - text_size * 0.5, text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
}
if (drag_type == DRAG_TYPE_CREATE_POINT) {
@@ -1113,7 +1113,7 @@ void TileDataDefaultEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2
}
Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.get_origin() + Vector2i(-string_size.x / 2, string_size.y / 2), text, HALIGN_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.get_origin() + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
}
}
@@ -1700,7 +1700,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
text = "-";
}
Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HALIGN_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
}
}
}
@@ -1876,7 +1876,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til
text = "-";
}
Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HALIGN_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
}
}
}
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 73b1fc7c67..b4d6f3659d 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -598,7 +598,10 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
- // Do nothing.
+ // Cancel tile pasting on right-click
+ if (mb->get_button_index() == MouseButton::RIGHT) {
+ drag_type = DRAG_TYPE_NONE;
+ }
} else if (tool_buttons_group->get_pressed_button() == select_tool_button) {
drag_start_mouse_pos = mpos;
if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) {
@@ -2093,8 +2096,8 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
missing_source_label->set_text(TTR("This TileMap's TileSet has no source configured. Edit the TileSet resource to add one."));
missing_source_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
missing_source_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- missing_source_label->set_align(Label::ALIGN_CENTER);
- missing_source_label->set_valign(Label::VALIGN_CENTER);
+ missing_source_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ missing_source_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
missing_source_label->hide();
tiles_bottom_panel->add_child(missing_source_label);
@@ -2152,8 +2155,8 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
invalid_source_label->set_text(TTR("Invalid source selected."));
invalid_source_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
invalid_source_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- invalid_source_label->set_align(Label::ALIGN_CENTER);
- invalid_source_label->set_valign(Label::VALIGN_CENTER);
+ invalid_source_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ invalid_source_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
invalid_source_label->hide();
atlas_sources_split_container->add_child(invalid_source_label);
@@ -3783,7 +3786,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
// Draw the warning icon.
- int min_axis = missing_tile_texture->get_size().min_axis();
+ Vector2::Axis min_axis = missing_tile_texture->get_size().min_axis_index();
Vector2 icon_size;
icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
@@ -3981,8 +3984,8 @@ TileMapEditor::TileMapEditor() {
missing_tileset_label->set_text(TTR("The edited TileMap node has no TileSet resource."));
missing_tileset_label->set_h_size_flags(SIZE_EXPAND_FILL);
missing_tileset_label->set_v_size_flags(SIZE_EXPAND_FILL);
- missing_tileset_label->set_align(Label::ALIGN_CENTER);
- missing_tileset_label->set_valign(Label::VALIGN_CENTER);
+ missing_tileset_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ missing_tileset_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
missing_tileset_label->hide();
add_child(missing_tileset_label);
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index a48c0e795c..660eb94cf5 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -2321,7 +2321,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
// Middle panel.
ScrollContainer *middle_panel = memnew(ScrollContainer);
- middle_panel->set_enable_h_scroll(false);
+ middle_panel->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
middle_panel->set_custom_minimum_size(Size2i(200, 0) * EDSCALE);
split_container_right_side->add_child(middle_panel);
@@ -2339,14 +2339,14 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_inspector = memnew(EditorInspector);
tile_inspector->set_undo_redo(undo_redo);
- tile_inspector->set_enable_v_scroll(false);
+ tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
tile_inspector->edit(tile_proxy_object);
tile_inspector->set_use_folding(true);
tile_inspector->connect("property_selected", callable_mp(this, &TileSetAtlasSourceEditor::_inspector_property_selected));
middle_vbox_container->add_child(tile_inspector);
tile_inspector_no_tile_selected_label = memnew(Label);
- tile_inspector_no_tile_selected_label->set_align(Label::ALIGN_CENTER);
+ tile_inspector_no_tile_selected_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
tile_inspector_no_tile_selected_label->set_text(TTR("No tile selected."));
middle_vbox_container->add_child(tile_inspector_no_tile_selected_label);
@@ -2385,7 +2385,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
atlas_source_inspector = memnew(EditorInspector);
atlas_source_inspector->set_undo_redo(undo_redo);
- atlas_source_inspector->set_enable_v_scroll(false);
+ atlas_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
atlas_source_inspector->edit(atlas_source_proxy_object);
middle_vbox_container->add_child(atlas_source_inspector);
@@ -2527,8 +2527,8 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_atlas_view_missing_source_label = memnew(Label);
tile_atlas_view_missing_source_label->set_text(TTR("Add or select an atlas texture to the left panel."));
- tile_atlas_view_missing_source_label->set_align(Label::ALIGN_CENTER);
- tile_atlas_view_missing_source_label->set_valign(Label::VALIGN_CENTER);
+ tile_atlas_view_missing_source_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ tile_atlas_view_missing_source_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tile_atlas_view_missing_source_label->set_h_size_flags(SIZE_EXPAND_FILL);
tile_atlas_view_missing_source_label->set_v_size_flags(SIZE_EXPAND_FILL);
tile_atlas_view_missing_source_label->hide();
diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp
index 915ce50836..b7495dbea9 100644
--- a/editor/plugins/tiles/tile_set_editor.cpp
+++ b/editor/plugins/tiles/tile_set_editor.cpp
@@ -682,7 +682,7 @@ TileSetEditor::TileSetEditor() {
split_container_left_side->add_child(sources_list);
HBoxContainer *sources_bottom_actions = memnew(HBoxContainer);
- sources_bottom_actions->set_alignment(HBoxContainer::ALIGN_END);
+ sources_bottom_actions->set_alignment(BoxContainer::ALIGNMENT_END);
split_container_left_side->add_child(sources_bottom_actions);
sources_delete_button = memnew(Button);
@@ -722,8 +722,8 @@ TileSetEditor::TileSetEditor() {
no_source_selected_label->set_text(TTR("No TileSet source selected. Select or create a TileSet source."));
no_source_selected_label->set_h_size_flags(SIZE_EXPAND_FILL);
no_source_selected_label->set_v_size_flags(SIZE_EXPAND_FILL);
- no_source_selected_label->set_align(Label::ALIGN_CENTER);
- no_source_selected_label->set_valign(Label::VALIGN_CENTER);
+ no_source_selected_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ no_source_selected_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
split_container_right_side->add_child(no_source_selected_label);
// Atlases editor.
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 d687d9651d..035fe57d95 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
@@ -459,7 +459,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
// Middle panel.
ScrollContainer *middle_panel = memnew(ScrollContainer);
- middle_panel->set_enable_h_scroll(false);
+ middle_panel->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
middle_panel->set_custom_minimum_size(Size2i(200, 0) * EDSCALE);
split_container_right_side->add_child(middle_panel);
@@ -477,7 +477,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
scenes_collection_source_inspector = memnew(EditorInspector);
scenes_collection_source_inspector->set_undo_redo(undo_redo);
- scenes_collection_source_inspector->set_enable_v_scroll(false);
+ scenes_collection_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object);
middle_vbox_container->add_child(scenes_collection_source_inspector);
@@ -493,7 +493,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
tile_inspector = memnew(EditorInspector);
tile_inspector->set_undo_redo(undo_redo);
- tile_inspector->set_enable_v_scroll(false);
+ tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
tile_inspector->edit(tile_proxy_object);
tile_inspector->set_use_folding(true);
middle_vbox_container->add_child(tile_inspector);
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 28352d25eb..eea0d2789d 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -266,7 +266,7 @@ void VersionControlEditorPlugin::_display_file_diff(String p_file_path) {
void VersionControlEditorPlugin::_refresh_file_diff() {
String open_file = diff_file_name->get_text();
- if (open_file != "") {
+ if (!open_file.is_empty()) {
_display_file_diff(diff_file_name->get_text());
}
}
@@ -299,7 +299,7 @@ void VersionControlEditorPlugin::_update_commit_status() {
}
void VersionControlEditorPlugin::_update_commit_button() {
- commit_button->set_disabled(commit_message->get_text().strip_edges() == "");
+ commit_button->set_disabled(commit_message->get_text().strip_edges().is_empty());
}
void VersionControlEditorPlugin::_commit_message_gui_input(const Ref<InputEvent> &p_event) {
@@ -416,11 +416,11 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
set_up_ok_button->set_text(TTR("Close"));
set_up_vbc = memnew(VBoxContainer);
- set_up_vbc->set_alignment(VBoxContainer::ALIGN_CENTER);
+ set_up_vbc->set_alignment(BoxContainer::ALIGNMENT_CENTER);
set_up_dialog->add_child(set_up_vbc);
set_up_hbc = memnew(HBoxContainer);
- set_up_hbc->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL);
+ set_up_hbc->set_h_size_flags(BoxContainer::SIZE_EXPAND_FILL);
set_up_vbc->add_child(set_up_hbc);
set_up_vcs_status = memnew(RichTextLabel);
@@ -447,7 +447,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
version_commit_dock->set_visible(false);
commit_box_vbc = memnew(VBoxContainer);
- commit_box_vbc->set_alignment(VBoxContainer::ALIGN_BEGIN);
+ commit_box_vbc->set_alignment(VBoxContainer::ALIGNMENT_BEGIN);
commit_box_vbc->set_h_size_flags(VBoxContainer::SIZE_EXPAND_FILL);
commit_box_vbc->set_v_size_flags(VBoxContainer::SIZE_EXPAND_FILL);
version_commit_dock->add_child(commit_box_vbc);
@@ -530,7 +530,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
commit_box_vbc->add_child(commit_button);
commit_status = memnew(Label);
- commit_status->set_align(Label::ALIGN_CENTER);
+ commit_status->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
commit_box_vbc->add_child(commit_status);
version_control_dock = memnew(PanelContainer);
@@ -555,7 +555,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
diff_file_name = memnew(Label);
diff_file_name->set_text(TTR("No file diff is active"));
diff_file_name->set_h_size_flags(Label::SIZE_EXPAND_FILL);
- diff_file_name->set_align(Label::ALIGN_RIGHT);
+ diff_file_name->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
diff_hbc->add_child(diff_file_name);
diff_refresh_button = memnew(Button);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index da73fc093c..365cfd9232 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -591,7 +591,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (vsnode->is_use_prop_slots()) {
String error = vsnode->get_warning(visual_shader->get_mode(), p_type);
- if (error != String()) {
+ if (!error.is_empty()) {
Label *error_label = memnew(Label);
error_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
error_label->set_text(error);
@@ -877,7 +877,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
node->add_child(offset);
String error = vsnode->get_warning(visual_shader->get_mode(), p_type);
- if (error != String()) {
+ if (!error.is_empty()) {
Label *error_label = memnew(Label);
error_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
error_label->set_text(error);
@@ -1191,7 +1191,7 @@ void VisualShaderEditor::update_custom_nodes() {
category = category.rstrip("/");
category = category.lstrip("/");
category = "Addons/" + category;
- if (subcategory != "") {
+ if (!subcategory.is_empty()) {
category += "/" + subcategory;
}
@@ -1687,7 +1687,7 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *p
ERR_FAIL_COND(!line_edit);
String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, false);
- if (validated_name == String() || prev_name == validated_name) {
+ if (validated_name.is_empty() || prev_name == validated_name) {
line_edit->set_text(node->get_input_port_name(p_port_id));
return;
}
@@ -1715,7 +1715,7 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *
ERR_FAIL_COND(!line_edit);
String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, true);
- if (validated_name == String() || prev_name == validated_name) {
+ if (validated_name.is_empty() || prev_name == validated_name) {
line_edit->set_text(node->get_output_port_name(p_port_id));
return;
}
@@ -2078,6 +2078,7 @@ void VisualShaderEditor::_comment_desc_popup_show(const Point2 &p_position, int
}
comment_desc_change_edit->set_text(node->get_description());
comment_desc_change_popup->set_meta("id", p_node_id);
+ comment_desc_change_popup->reset_size();
comment_desc_change_popup->popup();
comment_desc_change_popup->set_position(p_position);
}
@@ -2409,7 +2410,7 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
bool is_custom = add_options[p_idx].is_custom;
- if (!is_custom && add_options[p_idx].type != String()) {
+ if (!is_custom && !add_options[p_idx].type.is_empty()) {
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(add_options[p_idx].type));
ERR_FAIL_COND(!vsn);
@@ -3165,7 +3166,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
}
menu_point = graph->get_local_mouse_position();
- Point2 gpos = Input::get_singleton()->get_mouse_position();
+ Point2 gpos = get_screen_position() + get_local_mouse_position();
popup_menu->set_position(gpos);
popup_menu->reset_size();
popup_menu->popup();
@@ -3184,28 +3185,21 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNod
saved_node_pos_dirty = true;
saved_node_pos = graph->get_local_mouse_position();
- Point2 gpos = Input::get_singleton()->get_mouse_position();
- members_dialog->popup();
+ Point2 gpos = get_screen_position() + get_local_mouse_position();
members_dialog->set_position(gpos);
} else {
- members_dialog->popup();
saved_node_pos_dirty = false;
- members_dialog->set_position(graph->get_global_position() + Point2(5 * EDSCALE, 65 * EDSCALE));
+ members_dialog->set_position(graph->get_screen_position() + Point2(5 * EDSCALE, 65 * EDSCALE));
}
+ members_dialog->popup();
- // keep dialog within window bounds
- Size2 window_size = DisplayServer::get_singleton()->window_get_size();
+ // Keep dialog within window bounds.
+ Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
Rect2 dialog_rect = Rect2(members_dialog->get_position(), members_dialog->get_size());
- if (dialog_rect.position.y + dialog_rect.size.y > window_size.y) {
- int difference = dialog_rect.position.y + dialog_rect.size.y - window_size.y;
- members_dialog->set_position(members_dialog->get_position() - Point2(0, difference));
- }
- if (dialog_rect.position.x + dialog_rect.size.x > window_size.x) {
- int difference = dialog_rect.position.x + dialog_rect.size.x - window_size.x;
- members_dialog->set_position(members_dialog->get_position() - Point2(difference, 0));
- }
+ Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+ members_dialog->set_position(members_dialog->get_position() - difference);
- node_filter->call_deferred(SNAME("grab_focus")); // still not visible
+ node_filter->call_deferred(SNAME("grab_focus")); // Still not visible.
node_filter->select_all();
}
@@ -3781,10 +3775,10 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) {
_convert_constants_to_uniforms(true);
break;
case NodeMenuOptions::SET_COMMENT_TITLE:
- _comment_title_popup_show(get_global_mouse_position(), selected_comment);
+ _comment_title_popup_show(get_screen_position() + get_local_mouse_position(), selected_comment);
break;
case NodeMenuOptions::SET_COMMENT_DESCRIPTION:
- _comment_desc_popup_show(get_global_mouse_position(), selected_comment);
+ _comment_desc_popup_show(get_screen_position() + get_local_mouse_position(), selected_comment);
break;
default:
break;
@@ -3949,9 +3943,15 @@ void VisualShaderEditor::_update_preview() {
preview_text->set_text(code);
+ ShaderLanguage::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode()));
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode()));
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_global_variable_type;
+
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
+ Error err = sl.compile(code, info);
for (int i = 0; i < preview_text->get_line_count(); i++) {
preview_text->set_line_background_color(i, Color(0, 0, 0, 0));
@@ -4247,8 +4247,8 @@ VisualShaderEditor::VisualShaderEditor() {
alert = memnew(AcceptDialog);
alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD);
- alert->get_label()->set_align(Label::ALIGN_CENTER);
- alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ alert->get_label()->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
alert->get_label()->set_custom_minimum_size(Size2(400, 60) * EDSCALE);
add_child(alert);
@@ -4556,6 +4556,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("BitwiseNOT", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the result of bitwise NOT (~a) operation on the integer."), VisualShaderNodeIntFunc::FUNC_BITWISE_NOT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
@@ -4595,6 +4596,11 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), VisualShaderNodeFloatOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), VisualShaderNodeIntOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseAND", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_AND, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseLeftShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_OR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseRightShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseXOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_XOR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), VisualShaderNodeFloatOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), VisualShaderNodeIntOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), VisualShaderNodeFloatOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR));
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index 9a44d40dcb..4e81fc4e77 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -34,7 +34,7 @@ void VoxelGIEditorPlugin::_bake() {
if (voxel_gi) {
if (voxel_gi->get_probe_data().is_null()) {
String path = get_tree()->get_edited_scene_root()->get_scene_file_path();
- if (path == String()) {
+ if (path.is_empty()) {
path = "res://" + voxel_gi->get_name() + "_data.res";
} else {
String ext = path.get_extension();
@@ -67,31 +67,36 @@ void VoxelGIEditorPlugin::_notification(int p_what) {
return;
}
+ // Set information tooltip on the Bake button. This information is useful
+ // to optimize performance (video RAM size) and reduce light leaking (individual cell size).
+
const Vector3i size = voxel_gi->get_estimated_cell_size();
- String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z);
+
+ const Vector3 extents = voxel_gi->get_extents();
+
const int data_size = 4;
const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
- text += " - " + vformat(TTR("VRAM Size: %s MB"), String::num(size_mb, 2));
-
- if (bake_info->get_text() == text) {
- return;
+ // Add a qualitative measurement to help the user assess whether a VoxelGI node is using a lot of VRAM.
+ String size_quality;
+ if (size_mb < 16.0) {
+ size_quality = TTR("Low");
+ } else if (size_mb < 64.0) {
+ size_quality = TTR("Moderate");
+ } else {
+ size_quality = TTR("High");
}
- // Color the label depending on the estimated performance level.
- Color color;
- if (size_mb <= 16.0 + CMP_EPSILON) {
- // Fast.
- color = bake_info->get_theme_color(SNAME("success_color"), SNAME("Editor"));
- } else if (size_mb <= 64.0 + CMP_EPSILON) {
- // Medium.
- color = bake_info->get_theme_color(SNAME("warning_color"), SNAME("Editor"));
- } else {
- // Slow.
- color = bake_info->get_theme_color(SNAME("error_color"), SNAME("Editor"));
+ String text;
+ text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
+ text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
+ text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
+
+ // Only update the tooltip when needed to avoid constant redrawing.
+ if (bake->get_tooltip(Point2()) == text) {
+ return;
}
- bake_info->add_theme_color_override("font_color", color);
- bake_info->set_text(text);
+ bake->set_tooltip(text);
}
}
@@ -147,10 +152,6 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin(EditorNode *p_node) {
bake->set_text(TTR("Bake GI Probe"));
bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake));
bake_hb->add_child(bake);
- bake_info = memnew(Label);
- bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- bake_info->set_clip_text(true);
- bake_hb->add_child(bake_info);
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb);
voxel_gi = nullptr;
diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h
index 4d3cfe90f6..ed66728557 100644
--- a/editor/plugins/voxel_gi_editor_plugin.h
+++ b/editor/plugins/voxel_gi_editor_plugin.h
@@ -42,7 +42,6 @@ class VoxelGIEditorPlugin : public EditorPlugin {
VoxelGI *voxel_gi;
HBoxContainer *bake_hb;
- Label *bake_info;
Button *bake;
EditorNode *editor;
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index a97d38323e..0b748c12b6 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -178,7 +178,7 @@ void ProjectExportDialog::_update_export_all() {
Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_preset(i);
bool needs_templates;
String error;
- if (preset->get_export_path() == "" || !preset->get_platform()->can_export(preset, error, needs_templates)) {
+ if (preset->get_export_path().is_empty() || !preset->get_platform()->can_export(preset, error, needs_templates)) {
can_export = false;
break;
}
@@ -244,7 +244,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
bool needs_templates;
String error;
if (!current->get_platform()->can_export(current, error, needs_templates)) {
- if (error != String()) {
+ if (!error.is_empty()) {
Vector<String> items = error.split("\n", false);
error = "";
for (int i = 0; i < items.size(); i++) {
@@ -336,7 +336,7 @@ void ProjectExportDialog::_update_feature_list() {
Vector<String> custom_list = custom.split(",");
for (int i = 0; i < custom_list.size(); i++) {
String f = custom_list[i].strip_edges();
- if (f != String()) {
+ if (!f.is_empty()) {
features.push_back(f);
}
}
@@ -871,7 +871,7 @@ void ProjectExportDialog::_open_export_template_manager() {
void ProjectExportDialog::_validate_export_path(const String &p_path) {
// Disable export via OK button or Enter key if LineEdit has an empty filename
- bool invalid_path = (p_path.get_file().get_basename() == "");
+ bool invalid_path = (p_path.get_file().get_basename().is_empty());
// Check if state change before needlessly messing with signals
if (invalid_path && export_project->get_ok_button()->is_disabled()) {
@@ -904,7 +904,7 @@ void ProjectExportDialog::_export_project() {
export_project->add_filter("*." + extension_list[i] + " ; " + platform->get_name() + " Export");
}
- if (current->get_export_path() != "") {
+ if (!current->get_export_path().is_empty()) {
export_project->set_current_path(current->get_export_path());
} else {
if (extension_list.size() >= 1) {
@@ -1073,7 +1073,7 @@ ProjectExportDialog::ProjectExportDialog() {
// Subsections.
sections = memnew(TabContainer);
- sections->set_tab_align(TabContainer::ALIGN_LEFT);
+ sections->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
sections->set_use_hidden_tabs_for_min_size(true);
settings_vb->add_child(sections);
sections->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1292,10 +1292,10 @@ ProjectExportDialog::ProjectExportDialog() {
default_filename = EditorSettings::get_singleton()->get_project_metadata("export_options", "default_filename", "");
// If no default set, use project name
- if (default_filename == "") {
+ if (default_filename.is_empty()) {
// If no project name defined, use a sane default
default_filename = ProjectSettings::get_singleton()->get("application/config/name");
- if (default_filename == "") {
+ if (default_filename.is_empty()) {
default_filename = "UnnamedProject";
}
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0be1f6d85b..134f238bb6 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -102,7 +102,6 @@ private:
FileDialog *fdialog;
FileDialog *fdialog_install;
OptionButton *vcs_metadata_selection;
- CheckBox *create_default_environment;
String zip_path;
String zip_title;
AcceptDialog *dialog_error;
@@ -162,7 +161,7 @@ private:
}
}
- if (valid_path == "") {
+ if (valid_path.is_empty()) {
set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR);
memdelete(d);
get_ok_button()->set_disabled(true);
@@ -176,7 +175,7 @@ private:
valid_install_path = install_path->get_text().strip_edges();
}
- if (valid_install_path == "") {
+ if (valid_install_path.is_empty()) {
set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR, INSTALL_PATH);
memdelete(d);
get_ok_button()->set_disabled(true);
@@ -185,7 +184,7 @@ private:
}
if (mode == MODE_IMPORT || mode == MODE_RENAME) {
- if (valid_path != "" && !d->file_exists("project.godot")) {
+ if (!valid_path.is_empty() && !d->file_exists("project.godot")) {
if (valid_path.ends_with(".zip")) {
FileAccess *src_f = nullptr;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -226,7 +225,7 @@ private:
d->list_dir_begin();
is_folder_empty = true;
String n = d->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (!n.begins_with(".")) {
// Allow `.`, `..` (reserved current/parent folder names)
// and hidden files/folders to be present.
@@ -266,7 +265,7 @@ private:
d->list_dir_begin();
is_folder_empty = true;
String n = d->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (!n.begins_with(".")) {
// Allow `.`, `..` (reserved current/parent folder names)
// and hidden files/folders to be present.
@@ -296,16 +295,16 @@ private:
void _path_text_changed(const String &p_path) {
String sp = _test_path();
- if (sp != "") {
+ if (!sp.is_empty()) {
// If the project name is empty or default, infer the project name from the selected folder name
- if (project_name->get_text().strip_edges() == "" || project_name->get_text().strip_edges() == TTR("New Game Project")) {
+ if (project_name->get_text().strip_edges().is_empty() || project_name->get_text().strip_edges() == TTR("New Game Project")) {
sp = sp.replace("\\", "/");
int lidx = sp.rfind("/");
if (lidx != -1) {
sp = sp.substr(lidx + 1, sp.length()).capitalize();
}
- if (sp == "" && mode == MODE_IMPORT) {
+ if (sp.is_empty() && mode == MODE_IMPORT) {
sp = TTR("Imported Project");
}
@@ -314,7 +313,7 @@ private:
}
}
- if (created_folder_path != "" && created_folder_path != p_path) {
+ if (!created_folder_path.is_empty() && created_folder_path != p_path) {
_remove_created_folder();
}
}
@@ -383,7 +382,7 @@ private:
void _create_folder() {
const String project_name_no_edges = project_name->get_text().strip_edges();
- if (project_name_no_edges == "" || created_folder_path != "" || project_name_no_edges.ends_with(".")) {
+ if (project_name_no_edges.is_empty() || !created_folder_path.is_empty() || project_name_no_edges.ends_with(".")) {
set_message(TTR("Invalid project name."), MESSAGE_WARNING);
return;
}
@@ -418,7 +417,7 @@ private:
_test_path();
- if (p_text.strip_edges() == "") {
+ if (p_text.strip_edges().is_empty()) {
set_message(TTR("It would be a good idea to name your project."), MESSAGE_ERROR);
}
}
@@ -433,7 +432,7 @@ private:
if (mode == MODE_RENAME) {
String dir2 = _test_path();
- if (dir2 == "") {
+ if (dir2.is_empty()) {
set_message(TTR("Invalid project path (changed anything?)."), MESSAGE_ERROR);
return;
}
@@ -495,31 +494,10 @@ private:
initial_settings["application/config/name"] = project_name->get_text().strip_edges();
initial_settings["application/config/icon"] = "res://icon.png";
- if (create_default_environment->is_pressed()) {
- initial_settings["rendering/environment/defaults/default_environment"] = "res://default_env.tres";
- }
-
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
} else {
ResourceSaver::save(dir.plus_file("icon.png"), create_unscaled_default_project_icon());
- FileAccess *f;
- if (create_default_environment->is_pressed()) {
- f = FileAccess::open(dir.plus_file("default_env.tres"), FileAccess::WRITE);
- if (!f) {
- set_message(TTR("Couldn't create default_env.tres in project path."), MESSAGE_ERROR);
- } else {
- f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
- f->store_line("");
- f->store_line("[sub_resource type=\"Sky\" id=\"1\"]");
- f->store_line("");
- f->store_line("[resource]");
- f->store_line("background_mode = 2");
- f->store_line("sky = SubResource( \"1\" )");
- memdelete(f);
- }
- }
-
EditorVCSInterface::create_vcs_metadata_files(EditorVCSInterface::VCSMetadata(vcs_metadata_selection->get_selected()), dir);
}
} else if (mode == MODE_INSTALL) {
@@ -568,7 +546,7 @@ private:
String path = fname;
- if (path == String() || path == zip_root || !zip_root.is_subsequence_of(path)) {
+ if (path.is_empty() || path == zip_root || !zip_root.is_subsequence_of(path)) {
//
} else if (path.ends_with("/")) { // a dir
@@ -639,7 +617,7 @@ private:
}
void _remove_created_folder() {
- if (created_folder_path != "") {
+ if (!created_folder_path.is_empty()) {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
d->remove(created_folder_path);
memdelete(d);
@@ -739,7 +717,7 @@ public:
} else {
fav_dir = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path");
- if (fav_dir != "") {
+ if (!fav_dir.is_empty()) {
project_path->set_text(fav_dir);
fdialog->set_current_dir(fav_dir);
} else {
@@ -872,7 +850,7 @@ public:
iphb->add_child(install_browse);
msg = memnew(Label);
- msg->set_align(Label::ALIGN_CENTER);
+ msg->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
vb->add_child(msg);
// rasterizer selection
@@ -926,8 +904,8 @@ public:
l->set_text(TTR("The renderer can be changed later, but scenes may need to be adjusted."));
// Add some extra spacing to separate it from the list above and the buttons below.
l->set_custom_minimum_size(Size2(0, 40) * EDSCALE);
- l->set_align(Label::ALIGN_CENTER);
- l->set_valign(Label::VALIGN_CENTER);
+ l->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ l->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
l->set_modulate(Color(1, 1, 1, 0.7));
rasterizer_container->add_child(l);
@@ -945,10 +923,6 @@ public:
Control *spacer = memnew(Control);
spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
default_files_container->add_child(spacer);
- create_default_environment = memnew(CheckBox);
- create_default_environment->set_text("Create Default Environment");
- create_default_environment->set_pressed(true);
- default_files_container->add_child(create_default_environment);
fdialog = memnew(FileDialog);
fdialog->set_access(FileDialog::ACCESS_FILESYSTEM);
@@ -1184,7 +1158,7 @@ void ProjectList::load_project_icon(int p_index) {
Ref<Texture2D> default_icon = get_theme_icon(SNAME("DefaultProjectIcon"), SNAME("EditorIcons"));
Ref<Texture2D> icon;
- if (item.icon != "") {
+ if (!item.icon.is_empty()) {
Ref<Image> img;
img.instantiate();
Error err = img->load(item.icon.replace_first("res://", item.path + "/"));
@@ -1217,7 +1191,7 @@ ProjectList::Item ProjectList::load_project_data(const String &p_property_key, b
String project_name = TTR("Unnamed Project");
if (cf_err == OK) {
String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", ""));
- if (cf_project_name != "") {
+ if (!cf_project_name.is_empty()) {
project_name = cf_project_name.xml_unescape();
}
config_version = (int)cf->get_value("", "config_version", 0);
@@ -1233,46 +1207,6 @@ ProjectList::Item ProjectList::load_project_data(const String &p_property_key, b
const String main_scene = cf->get_value("application", "run/main_scene", "");
PackedStringArray project_features = cf->get_value("application", "config/features", PackedStringArray());
- bool project_features_dirty = false;
- // If there is no feature list currently present, force one to generate.
- if (project_features.is_empty()) {
- project_features = ProjectSettings::get_required_features();
- project_features_dirty = true;
- }
- // Check the rendering API.
- const String rendering_api = cf->get_value("rendering", "quality/driver/driver_name", "");
- if (rendering_api != "") {
- // Add the rendering API as a project feature if it doesn't already exist.
- if (!project_features.has(rendering_api)) {
- project_features.append(rendering_api);
- project_features_dirty = true;
- }
- }
- // Check for the existence of a csproj file.
- if (FileAccess::exists(path.plus_file(project_name + ".csproj"))) {
- // If there is a csproj file, add the C# feature if it doesn't already exist.
- if (!project_features.has("C#")) {
- project_features.append("C#");
- project_features_dirty = true;
- }
- } else {
- // If there isn't a csproj file, remove the C# feature if it exists.
- if (project_features.has("C#")) {
- project_features.remove_at(project_features.find("C#"));
- project_features_dirty = true;
- }
- }
- if (project_features_dirty) {
- project_features.sort();
- // Write the updated feature list, but only if the project config version is the same.
- // Never write to project files with a different config version!
- if (config_version == ProjectSettings::CONFIG_VERSION) {
- ProjectSettings *ps = ProjectSettings::get_singleton();
- ps->load_custom(conf);
- ps->set("application/config/features", project_features);
- ps->save_custom(conf);
- }
- }
PackedStringArray unsupported_features = ProjectSettings::get_unsupported_features(project_features);
uint64_t last_edited = 0;
@@ -1427,7 +1361,7 @@ void ProjectList::create_project_item_control(int p_index) {
favorite->set_mouse_filter(MOUSE_FILTER_PASS);
favorite->connect("pressed", callable_mp(this, &ProjectList::_favorite_pressed), varray(hb));
favorite_box->add_child(favorite);
- favorite_box->set_alignment(BoxContainer::ALIGN_CENTER);
+ favorite_box->set_alignment(BoxContainer::ALIGNMENT_CENTER);
hb->add_child(favorite_box);
hb->favorite_button = favorite;
hb->set_is_favorite(item.favorite);
@@ -1470,11 +1404,11 @@ void ProjectList::create_project_item_control(int p_index) {
int length = unsupported_features_str.length();
if (length > 0) {
Label *unsupported_label = memnew(Label(unsupported_features_str));
- unsupported_label->set_custom_minimum_size(Size2(length * 15, 10));
+ unsupported_label->set_custom_minimum_size(Size2(length * 15, 10) * EDSCALE);
unsupported_label->add_theme_font_override("font", get_theme_font(SNAME("title"), SNAME("EditorFonts")));
unsupported_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
unsupported_label->set_clip_text(true);
- unsupported_label->set_align(Label::ALIGN_RIGHT);
+ unsupported_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
title_hb->add_child(unsupported_label);
Control *spacer = memnew(Control());
spacer->set_custom_minimum_size(Size2(10, 10));
@@ -1539,7 +1473,7 @@ void ProjectList::sort_projects() {
Item &item = _projects.write[i];
bool visible = true;
- if (_search_term != "") {
+ if (!_search_term.is_empty()) {
String search_path;
if (_search_term.find("/") != -1) {
// Search path will match the whole path
@@ -1851,7 +1785,7 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
const Item &clicked_project = _projects[clicked_index];
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
- if (mb->is_shift_pressed() && _selected_project_keys.size() > 0 && _last_clicked != "" && clicked_project.project_key != _last_clicked) {
+ if (mb->is_shift_pressed() && _selected_project_keys.size() > 0 && !_last_clicked.is_empty() && clicked_project.project_key != _last_clicked) {
int anchor_index = -1;
for (int i = 0; i < _projects.size(); ++i) {
const Item &p = _projects[i];
@@ -2200,7 +2134,7 @@ void ProjectManager::_open_selected_projects_ask() {
PackedStringArray unsupported_features = project.unsupported_features;
Label *ask_update_label = ask_update_settings->get_label();
- ask_update_label->set_align(Label::ALIGN_LEFT); // Reset in case of previous center align.
+ ask_update_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); // Reset in case of previous center align.
// Check if the config_version property was empty or 0
if (config_version == 0) {
@@ -2244,7 +2178,7 @@ void ProjectManager::_open_selected_projects_ask() {
warning_message += vformat(TTR("Warning: This project uses the following features not supported by this build of Godot:\n\n%s\n\n"), unsupported_features_str);
}
warning_message += TTR("Open anyway? Project will be modified.");
- ask_update_label->set_align(Label::ALIGN_CENTER);
+ ask_update_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
ask_update_settings->set_text(warning_message);
ask_update_settings->popup_centered();
return;
@@ -2259,7 +2193,7 @@ void ProjectManager::_run_project_confirm() {
for (int i = 0; i < selected_list.size(); ++i) {
const String &selected_main = selected_list[i].main_scene;
- if (selected_main == "") {
+ if (selected_main.is_empty()) {
run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in the Project Settings under the \"Application\" category."));
run_error_diag->popup_centered();
continue;
@@ -2312,7 +2246,7 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path);
da->list_dir_begin();
String n = da->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (da->current_is_dir() && !n.begins_with(".")) {
_scan_dir(da->get_current_dir().plus_file(n), r_projects);
} else if (n == "project.godot") {
@@ -2454,7 +2388,7 @@ void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) {
if (dir->change_dir(folders[0]) == OK) {
dir->list_dir_begin();
String file = dir->get_next();
- while (confirm && file != String()) {
+ while (confirm && !file.is_empty()) {
if (!dir->current_is_dir() && file.ends_with("project.godot")) {
confirm = false;
}
@@ -2603,7 +2537,7 @@ ProjectManager::ProjectManager() {
tabs = memnew(TabContainer);
center_box->add_child(tabs);
tabs->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
HBoxContainer *projects_hb = memnew(HBoxContainer);
@@ -2661,7 +2595,7 @@ ProjectManager::ProjectManager() {
_project_list = memnew(ProjectList);
_project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
_project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, callable_mp(this, &ProjectManager::_open_selected_projects_ask));
- _project_list->set_enable_h_scroll(false);
+ _project_list->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
pc->add_child(_project_list);
}
@@ -2732,7 +2666,7 @@ ProjectManager::ProjectManager() {
{
// Version info and language options
settings_hb = memnew(HBoxContainer);
- settings_hb->set_alignment(BoxContainer::ALIGN_END);
+ settings_hb->set_alignment(BoxContainer::ALIGNMENT_END);
settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
settings_hb->set_anchors_and_offsets_preset(Control::PRESET_TOP_RIGHT);
@@ -2783,7 +2717,7 @@ ProjectManager::ProjectManager() {
for (int i = 0; i < editor_languages.size(); i++) {
String lang = editor_languages[i];
String lang_name = TranslationServer::get_singleton()->get_locale_name(lang);
- language_btn->add_item(lang_name + " [" + lang + "]", i);
+ language_btn->add_item(vformat("[%s] %s", lang, lang_name), i);
language_btn->set_item_metadata(i, lang);
if (current_lang == lang) {
language_btn->select(i);
@@ -2892,7 +2826,7 @@ ProjectManager::ProjectManager() {
}
String autoscan_path = EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path");
- if (autoscan_path != "") {
+ if (!autoscan_path.is_empty()) {
if (dir_access->dir_exists(autoscan_path)) {
_scan_begin(autoscan_path);
} else {
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index db12e90540..f6975594cb 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -78,7 +78,7 @@ void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) {
}
void ProjectSettingsEditor::_setting_selected(const String &p_path) {
- if (p_path == String()) {
+ if (p_path.is_empty()) {
return;
}
@@ -147,12 +147,12 @@ void ProjectSettingsEditor::_update_property_box() {
const Vector<String> t = setting.split(".", true, 1);
const String name = t[0];
const String feature = (t.size() == 2) ? t[1] : "";
- bool feature_invalid = (t.size() == 2) && (t[1] == "");
+ bool feature_invalid = (t.size() == 2) && (t[1].is_empty());
add_button->set_disabled(true);
del_button->set_disabled(true);
- if (feature != "") {
+ if (!feature.is_empty()) {
feature_invalid = true;
for (int i = 1; i < feature_box->get_item_count(); i++) {
if (feature == feature_box->get_item_text(i)) {
@@ -163,11 +163,11 @@ void ProjectSettingsEditor::_update_property_box() {
}
}
- if (feature == "" || feature_invalid) {
+ if (feature.is_empty() || feature_invalid) {
feature_box->select(0);
}
- if (property_box->get_text() == "") {
+ if (property_box->get_text().is_empty()) {
return;
}
@@ -244,7 +244,7 @@ void ProjectSettingsEditor::_add_feature_overrides() {
Vector<String> custom_list = custom.split(",");
for (int j = 0; j < custom_list.size(); j++) {
String f = custom_list[j].strip_edges();
- if (f != String()) {
+ if (!f.is_empty()) {
presets.insert(f);
}
}
@@ -513,13 +513,13 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
data = p_data;
tab_container = memnew(TabContainer);
- tab_container->set_tab_align(TabContainer::ALIGN_LEFT);
+ tab_container->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tab_container->set_use_hidden_tabs_for_min_size(true);
add_child(tab_container);
VBoxContainer *general_editor = memnew(VBoxContainer);
general_editor->set_name(TTR("General"));
- general_editor->set_alignment(BoxContainer::ALIGN_BEGIN);
+ general_editor->set_alignment(BoxContainer::ALIGNMENT_BEGIN);
general_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tab_container->add_child(general_editor);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 061f4d218a..abe1bcf9e5 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -482,7 +482,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
Vector<String> flags = hint_text.split(",");
for (int i = 0; i < flags.size(); i++) {
String flag = flags[i];
- if (flag == "") {
+ if (flag.is_empty()) {
continue;
}
menu->add_check_item(flag, i);
@@ -552,7 +552,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
add_child(create_dialog);
}
- if (hint_text != String()) {
+ if (!hint_text.is_empty()) {
create_dialog->set_base_type(hint_text);
} else {
create_dialog->set_base_type("Object");
@@ -853,7 +853,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
if (p_name == "script" && hint_text == "Script" && Object::cast_to<Node>(owner)) {
menu->add_item(TTR("New Script"), OBJ_MENU_NEW_SCRIPT);
menu->add_separator();
- } else if (hint_text != "") {
+ } else if (!hint_text.is_empty()) {
int idx = 0;
Vector<EditorData::CustomType> custom_resources;
@@ -933,7 +933,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
bool paste_valid = false;
if (cb.is_valid()) {
- if (hint_text == "") {
+ if (hint_text.is_empty()) {
paste_valid = true;
} else {
for (int i = 0; i < hint_text.get_slice_count(","); i++) {
@@ -1108,7 +1108,7 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
return;
}
- if (hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && hint_text != String()) {
+ if (hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !hint_text.is_empty()) {
Node *node = get_node(hint_text);
if (node) {
Node *tonode = node->get_node(p_path);
@@ -1191,7 +1191,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
file->clear_filters();
- if (hint_text != "") {
+ if (!hint_text.is_empty()) {
Vector<String> extensions = hint_text.split(",");
for (int i = 0; i < extensions.size(); i++) {
String filter = extensions[i];
@@ -1410,7 +1410,7 @@ void CustomPropertyEditor::_draw_easing() {
prev = h;
}
- f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), String::num(exp, 2), HALIGN_LEFT, -1, font_size, color);
+ f->draw_string(ci, Point2(10, 10 + f->get_ascent(font_size)), String::num(exp, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color);
}
void CustomPropertyEditor::_text_edit_changed() {
@@ -1864,7 +1864,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
slider->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified));
action_hboxes = memnew(HBoxContainer);
- action_hboxes->set_alignment(BoxContainer::ALIGN_CENTER);
+ action_hboxes->set_alignment(BoxContainer::ALIGNMENT_CENTER);
value_vbox->add_child(action_hboxes);
for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
action_buttons[i] = memnew(Button);
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 877b4552c1..838686ead6 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -181,7 +181,7 @@ void PropertySelector::_update_search() {
continue;
}
- if (search_box->get_text() != String() && E.name.findn(search_text) == -1) {
+ if (!search_box->get_text().is_empty() && E.name.findn(search_text) == -1) {
continue;
}
@@ -194,7 +194,7 @@ void PropertySelector::_update_search() {
item->set_metadata(0, E.name);
item->set_icon(0, type_icons[E.type]);
- if (!found && search_box->get_text() != String() && E.name.findn(search_text) != -1) {
+ if (!found && !search_box->get_text().is_empty() && E.name.findn(search_text) != -1) {
item->select(0);
found = true;
}
@@ -269,7 +269,7 @@ void PropertySelector::_update_search() {
continue;
}
- if (search_box->get_text() != String() && name.findn(search_text) == -1) {
+ if (!search_box->get_text().is_empty() && name.findn(search_text) == -1) {
continue;
}
@@ -318,7 +318,7 @@ void PropertySelector::_update_search() {
item->set_metadata(0, name);
item->set_selectable(0, true);
- if (!found && search_box->get_text() != String() && name.findn(search_text) != -1) {
+ if (!found && !search_box->get_text().is_empty() && name.findn(search_text) != -1) {
item->select(0);
found = true;
}
@@ -353,7 +353,7 @@ void PropertySelector::_item_selected() {
String class_type;
if (type != Variant::NIL) {
class_type = Variant::get_type_name(type);
- } else if (base_type != String()) {
+ } else if (!base_type.is_empty()) {
class_type = base_type;
} else if (instance) {
class_type = instance->get_class();
@@ -362,7 +362,7 @@ void PropertySelector::_item_selected() {
DocTools *dd = EditorHelp::get_doc_data();
String text;
if (properties) {
- while (class_type != String()) {
+ while (!class_type.is_empty()) {
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(class_type);
if (E) {
for (int i = 0; i < E->get().properties.size(); i++) {
@@ -373,7 +373,7 @@ void PropertySelector::_item_selected() {
}
}
- if (text != String()) {
+ if (!text.is_empty()) {
break;
}
@@ -381,7 +381,7 @@ void PropertySelector::_item_selected() {
class_type = ClassDB::get_parent_class(class_type);
}
} else {
- while (class_type != String()) {
+ while (!class_type.is_empty()) {
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(class_type);
if (E) {
for (int i = 0; i < E->get().methods.size(); i++) {
@@ -392,7 +392,7 @@ void PropertySelector::_item_selected() {
}
}
- if (text != String()) {
+ if (!text.is_empty()) {
break;
}
@@ -401,7 +401,7 @@ void PropertySelector::_item_selected() {
}
}
- if (text != String()) {
+ if (!text.is_empty()) {
// Display both property name and description, since the help bit may be displayed
// far away from the location (especially if the dialog was resized to be taller).
help_bit->set_text(vformat("[b]%s[/b]: %s", name, text));
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 7868414d89..b4ab6493ef 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -79,7 +79,7 @@ void EditorQuickOpen::_build_search_cache(EditorFileSystemDirectory *p_efsd) {
void EditorQuickOpen::_update_search() {
const String search_text = search_box->get_text();
- const bool empty_search = search_text == "";
+ const bool empty_search = search_text.is_empty();
// Filter possible candidates.
Vector<Entry> entries;
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index eb73f88e61..8cf5a26c55 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -114,7 +114,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
vbc->add_child(cbut_collapse_features);
tabc_features = memnew(TabContainer);
- tabc_features->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabc_features->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabc_features->set_use_hidden_tabs_for_min_size(true);
vbc->add_child(tabc_features);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 611038a947..1934850160 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -190,7 +190,7 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N
break;
}
- if (edited_scene->get_scene_file_path() != "") {
+ if (!edited_scene->get_scene_file_path().is_empty()) {
if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i]));
accept->popup_centered();
@@ -419,6 +419,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!selected_item) {
selected_item = tree->get_root();
+ if (!selected_item) {
+ break;
+ }
}
bool collapsed = _is_collapsed_recursive(selected_item);
@@ -464,7 +467,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
bool has_cycle = false;
- if (edited_scene->get_scene_file_path() != String()) {
+ if (!edited_scene->get_scene_file_path().is_empty()) {
for (Node *E : node_clipboard) {
if (edited_scene->get_scene_file_path() == E->get_scene_file_path()) {
has_cycle = true;
@@ -807,7 +810,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
return;
}
- if (node->get_scene_file_path() != String()) {
+ if (!node->get_scene_file_path().is_empty()) {
accept->set_text(TTR("Instantiated scenes can't become root"));
accept->popup_centered();
return;
@@ -886,7 +889,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *node = remove_list[0];
if (node == editor_data->get_edited_scene_root()) {
msg = vformat(TTR("Delete the root node \"%s\"?"), node->get_name());
- } else if (node->get_scene_file_path() == "" && node->get_child_count() > 0) {
+ } else if (node->get_scene_file_path().is_empty() && node->get_child_count() > 0) {
// Display this message only for non-instantiated scenes
msg = vformat(TTR("Delete node \"%s\" and its children?"), node->get_name());
} else {
@@ -933,7 +936,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
- if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_scene_file_path() != "") {
+ if (tocopy != editor_data->get_edited_scene_root() && !tocopy->get_scene_file_path().is_empty()) {
accept->set_text(TTR("Can't save the branch of an already instantiated scene.\nTo create a variation of a scene, you can make an inherited scene based on the instantiated scene using Scene > New Inherited Scene... instead."));
accept->popup_centered();
break;
@@ -1049,7 +1052,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
- ERR_FAIL_COND(node->get_scene_file_path() == String());
+ ERR_FAIL_COND(node->get_scene_file_path().is_empty());
undo_redo->create_action(TTR("Make Local"));
undo_redo->add_do_method(node, "set_scene_file_path", "");
undo_redo->add_undo_method(node, "set_scene_file_path", node->get_scene_file_path());
@@ -1306,6 +1309,7 @@ void SceneTreeDock::_notification(int p_what) {
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_2d->set_icon(get_theme_icon(SNAME("Node2D"), SNAME("EditorIcons")));
button_3d->set_icon(get_theme_icon(SNAME("Node3D"), SNAME("EditorIcons")));
button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
@@ -1699,7 +1703,7 @@ bool SceneTreeDock::_validate_no_instance() {
List<Node *> selection = editor_selection->get_selected_node_list();
for (Node *E : selection) {
- if (E != edited_scene && E->get_scene_file_path() != "") {
+ if (E != edited_scene && !E->get_scene_file_path().is_empty()) {
accept->set_text(TTR("This operation can't be done on instantiated scenes."));
accept->popup_centered();
return false;
@@ -2757,7 +2761,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
bool can_replace = true;
for (Node *E : selection) {
- if (E != edited_scene && (E->get_owner() != edited_scene || E->get_scene_file_path() != "")) {
+ if (E != edited_scene && (E->get_owner() != edited_scene || !E->get_scene_file_path().is_empty())) {
can_replace = false;
break;
}
@@ -2789,7 +2793,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
}
- bool is_external = (selection[0]->get_scene_file_path() != "");
+ bool is_external = (!selection[0]->get_scene_file_path().is_empty());
if (is_external) {
bool is_inherited = selection[0]->get_scene_inherited_state() != nullptr;
bool is_top_level = selection[0]->get_owner() == nullptr;
@@ -2902,9 +2906,9 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) {
Ref<Script> existing = selected->get_script();
String path = selected->get_scene_file_path();
- if (path == "") {
+ if (path.is_empty()) {
String root_path = editor_data->get_edited_scene_root()->get_scene_file_path();
- if (root_path == "") {
+ if (root_path.is_empty()) {
path = String("res://").plus_file(selected->get_name());
} else {
path = root_path.get_base_dir().plus_file(selected->get_name());
@@ -2952,7 +2956,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) {
}
String path = selected_shader_material->get_path();
- if (path == "") {
+ if (path.is_empty()) {
String root_path;
if (editor_data->get_edited_scene_root()) {
root_path = editor_data->get_edited_scene_root()->get_scene_file_path();
@@ -2963,7 +2967,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) {
} else {
shader_name = selected_shader_material->get_name();
}
- if (root_path == "") {
+ if (root_path.is_empty()) {
path = String("res://").plus_file(shader_name);
} else {
path = root_path.get_base_dir().plus_file(shader_name);
@@ -2973,7 +2977,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) {
shader_create_dialog->connect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created));
shader_create_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
shader_create_dialog->connect("cancelled", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
- shader_create_dialog->config(path, true, true, p_preferred_mode);
+ shader_create_dialog->config(path, true, true, -1, p_preferred_mode);
shader_create_dialog->popup_centered();
}
@@ -3066,7 +3070,7 @@ void SceneTreeDock::_update_create_root_dialog() {
while (!f->eof_reached()) {
String l = f->get_line().strip_edges();
- if (l != String()) {
+ if (!l.is_empty()) {
Button *button = memnew(Button);
favorite_nodes->add_child(button);
button->set_text(l);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 73523474ef..4569841af6 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -120,7 +120,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
undo_redo->commit_action();
} else if (p_id == BUTTON_WARNING) {
String config_err = n->get_configuration_warnings_as_string();
- if (config_err == String()) {
+ if (config_err.is_empty()) {
return;
}
config_err = config_err.word_wrap(80);
@@ -297,16 +297,16 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
String tooltip = String(p_node->get_name()) + "\n" + TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class();
- if (p_node->get_editor_description() != String()) {
+ if (!p_node->get_editor_description().is_empty()) {
tooltip += "\n\n" + p_node->get_editor_description();
}
item->set_tooltip(0, tooltip);
- } else if (p_node != get_scene_node() && p_node->get_scene_file_path() != "" && can_open_instance) {
+ } 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"));
String tooltip = String(p_node->get_name()) + "\n" + TTR("Instance:") + " " + p_node->get_scene_file_path() + "\n" + TTR("Type:") + " " + p_node->get_class();
- if (p_node->get_editor_description() != String()) {
+ if (!p_node->get_editor_description().is_empty()) {
tooltip += "\n\n" + p_node->get_editor_description();
}
@@ -318,7 +318,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
}
String tooltip = String(p_node->get_name()) + "\n" + TTR("Type:") + " " + type;
- if (p_node->get_editor_description() != String()) {
+ if (!p_node->get_editor_description().is_empty()) {
tooltip += "\n\n" + p_node->get_editor_description();
}
@@ -955,7 +955,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
Node *n = get_node(np);
if (n) {
// Only allow selection if not part of an instantiated scene.
- if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_scene_file_path() == String()) {
+ if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_scene_file_path().is_empty()) {
selected.push_back(n);
icons.push_back(next->get_icon(0));
}
@@ -1069,7 +1069,7 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
}
}
- return String(d["type"]) == "nodes" && filter == String();
+ return String(d["type"]) == "nodes" && filter.is_empty();
}
void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
@@ -1122,7 +1122,7 @@ void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
void SceneTreeEditor::_rmb_select(const Vector2 &p_pos) {
- emit_signal(SNAME("rmb_pressed"), tree->get_screen_transform().xform(p_pos));
+ emit_signal(SNAME("rmb_pressed"), tree->get_screen_position() + p_pos);
}
void SceneTreeEditor::update_warning() {
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index fb1575ad8c..0e96a1d247 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -101,7 +101,7 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
parent_name->set_text(p_base_name);
parent_name->deselect();
- if (p_base_path != "") {
+ if (!p_base_path.is_empty()) {
initial_bp = p_base_path.get_basename();
file_path->set_text(initial_bp + "." + ScriptServer::get_language(language_menu->get_selected())->get_extension());
current_language = language_menu->get_selected();
@@ -163,10 +163,10 @@ bool ScriptCreateDialog::_validate_class(const String &p_string) {
String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
String p = p_path.strip_edges();
- if (p == "") {
+ if (p.is_empty()) {
return TTR("Path is empty.");
}
- if (p.get_file().get_basename() == "") {
+ if (p.get_file().get_basename().is_empty()) {
return TTR("Filename is empty.");
}
@@ -227,7 +227,7 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
/* Let ScriptLanguage do custom validation */
String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
- if (path_error != "") {
+ if (!path_error.is_empty()) {
return path_error;
}
@@ -295,7 +295,7 @@ void ScriptCreateDialog::_create_new() {
String cname_param = _get_class_name();
Ref<Script> scr;
- if (script_template != "") {
+ if (!script_template.is_empty()) {
scr = ResourceLoader::load(script_template);
if (scr.is_null()) {
alert->set_text(vformat(TTR("Error loading template '%s'"), script_template));
@@ -358,7 +358,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
String selected_ext = "." + language->get_extension();
String path = file_path->get_text();
String extension = "";
- if (path != "") {
+ if (!path.is_empty()) {
if (path.find(".") != -1) {
extension = path.get_extension();
}
@@ -582,7 +582,7 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
is_new_script_created = true;
String path_error = _validate_path(p_path, false);
- if (path_error != "") {
+ if (!path_error.is_empty()) {
_msg_path_valid(false, path_error);
_update_dialog();
return;
@@ -907,8 +907,8 @@ ScriptCreateDialog::ScriptCreateDialog() {
get_ok_button()->set_text(TTR("Create"));
alert = memnew(AcceptDialog);
alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
- alert->get_label()->set_align(Label::ALIGN_CENTER);
- alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ alert->get_label()->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
add_child(alert);
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index e1229729ac..8e12cb76ef 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -148,7 +148,7 @@ void EditorSettingsDialog::unhandled_input(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("ui_undo", p_event)) {
String action = undo_redo->get_current_action_name();
- if (action != "") {
+ if (!action.is_empty()) {
EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
}
undo_redo->undo();
@@ -158,7 +158,7 @@ void EditorSettingsDialog::unhandled_input(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("ui_redo", p_event)) {
undo_redo->redo();
String action = undo_redo->get_current_action_name();
- if (action != "") {
+ if (!action.is_empty()) {
EditorNode::get_log()->add_message("Redo: " + action, EditorLog::MSG_TYPE_EDITOR);
}
handled = true;
@@ -622,7 +622,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
undo_redo = memnew(UndoRedo);
tabs = memnew(TabContainer);
- tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabs->connect("tab_changed", callable_mp(this, &EditorSettingsDialog::_tabs_tab_changed));
add_child(tabs);
diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp
index 23bdc06f95..302f7f78c5 100644
--- a/editor/shader_create_dialog.cpp
+++ b/editor/shader_create_dialog.cpp
@@ -220,7 +220,7 @@ void ShaderCreateDialog::_language_changed(int p_language) {
String path = file_path->get_text();
String extension = "";
- if (path != "") {
+ if (!path.is_empty()) {
if (path.find(".") != -1) {
extension = path.get_extension();
}
@@ -303,7 +303,7 @@ void ShaderCreateDialog::_path_changed(const String &p_path) {
is_new_shader_created = true;
String path_error = _validate_path(p_path);
- if (path_error != "") {
+ if (!path_error.is_empty()) {
_msg_path_valid(false, path_error);
_update_dialog();
return;
@@ -324,8 +324,8 @@ void ShaderCreateDialog::_path_submitted(const String &p_path) {
ok_pressed();
}
-void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_mode) {
- if (p_base_path != "") {
+void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_type, int p_preferred_mode) {
+ if (!p_base_path.is_empty()) {
initial_base_path = p_base_path.get_basename();
file_path->set_text(initial_base_path + "." + language_data[language_menu->get_selected()].default_extension);
current_language = language_menu->get_selected();
@@ -338,6 +338,11 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl
built_in_enabled = p_built_in_enabled;
load_enabled = p_load_enabled;
+ if (p_preferred_type > -1) {
+ language_menu->select(p_preferred_type);
+ _language_changed(p_preferred_type);
+ }
+
if (p_preferred_mode > -1) {
mode_menu->select(p_preferred_mode);
_mode_changed(p_preferred_mode);
@@ -350,10 +355,10 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl
String ShaderCreateDialog::_validate_path(const String &p_path) {
String p = p_path.strip_edges();
- if (p == "") {
+ if (p.is_empty()) {
return TTR("Path is empty.");
}
- if (p.get_file().get_basename() == "") {
+ if (p.get_file().get_basename().is_empty()) {
return TTR("Filename is empty.");
}
@@ -625,8 +630,8 @@ ShaderCreateDialog::ShaderCreateDialog() {
alert = memnew(AcceptDialog);
alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
- alert->get_label()->set_align(Label::ALIGN_CENTER);
- alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ alert->get_label()->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
add_child(alert);
diff --git a/editor/shader_create_dialog.h b/editor/shader_create_dialog.h
index be0a0cad06..cd20897ddb 100644
--- a/editor/shader_create_dialog.h
+++ b/editor/shader_create_dialog.h
@@ -108,7 +108,7 @@ protected:
static void _bind_methods();
public:
- void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, int p_preferred_mode = -1);
+ void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, int p_preferred_type = -1, int p_preferred_mode = -1);
ShaderCreateDialog();
};
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
index d504d3b137..31c1dc85a8 100644
--- a/editor/shader_globals_editor.cpp
+++ b/editor/shader_globals_editor.cpp
@@ -372,7 +372,7 @@ static Variant create_var(RS::GlobalVariableType p_type) {
void ShaderGlobalsEditor::_variable_added() {
String var = variable_name->get_text().strip_edges();
- if (var == "" || !var.is_valid_identifier()) {
+ if (var.is_empty() || !var.is_valid_identifier()) {
EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name."));
return;
}
diff --git a/gles3_builders.py b/gles3_builders.py
index acaff28685..5288e66cc2 100644
--- a/gles3_builders.py
+++ b/gles3_builders.py
@@ -267,13 +267,13 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n"
)
fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n"
+ "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={(GLfloat)p_vec2.x,(GLfloat)p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n"
)
fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint vec2[2]={p_vec2.x,p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n"
+ "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint vec2[2]={(GLint)p_vec2.x,(GLint)p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n"
)
fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n"
+ "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={(GLfloat)p_vec3.x,(GLfloat)p_vec3.y,(GLfloat)p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n"
@@ -291,22 +291,22 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
const Transform3D &tr = p_transform;
GLfloat matrix[16]={ /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
+ (GLfloat)tr.basis.elements[0][0],
+ (GLfloat)tr.basis.elements[1][0],
+ (GLfloat)tr.basis.elements[2][0],
+ (GLfloat)0,
+ (GLfloat)tr.basis.elements[0][1],
+ (GLfloat)tr.basis.elements[1][1],
+ (GLfloat)tr.basis.elements[2][1],
+ (GLfloat)0,
+ (GLfloat)tr.basis.elements[0][2],
+ (GLfloat)tr.basis.elements[1][2],
+ (GLfloat)tr.basis.elements[2][2],
+ (GLfloat)0,
+ (GLfloat)tr.origin.x,
+ (GLfloat)tr.origin.y,
+ (GLfloat)tr.origin.z,
+ (GLfloat)1
};
@@ -324,22 +324,22 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
const Transform2D &tr = p_transform;
GLfloat matrix[16]={ /* build a 16x16 matrix */
- tr.elements[0][0],
- tr.elements[0][1],
- 0,
- 0,
- tr.elements[1][0],
- tr.elements[1][1],
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- tr.elements[2][0],
- tr.elements[2][1],
- 0,
- 1
+ (GLfloat)tr.elements[0][0],
+ (GLfloat)tr.elements[0][1],
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)tr.elements[1][0],
+ (GLfloat)tr.elements[1][1],
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)0,
+ (GLfloat)1,
+ (GLfloat)0,
+ (GLfloat)tr.elements[2][0],
+ (GLfloat)tr.elements[2][1],
+ (GLfloat)0,
+ (GLfloat)1
};
diff --git a/main/SCsub b/main/SCsub
index 87d64e48f9..79dc4bff15 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -20,12 +20,13 @@ env_main.CommandNoCache(
env.Run(main_builders.make_splash, "Building splash screen header."),
)
-env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
-env_main.CommandNoCache(
- "#main/splash_editor.gen.h",
- "#main/splash_editor.png",
- env.Run(main_builders.make_splash_editor, "Building editor splash screen header."),
-)
+if not env_main["no_editor_splash"]:
+ env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
+ env_main.CommandNoCache(
+ "#main/splash_editor.gen.h",
+ "#main/splash_editor.png",
+ env.Run(main_builders.make_splash_editor, "Building editor splash screen header."),
+ )
env_main.Depends("#main/app_icon.gen.h", "#main/app_icon.png")
env_main.CommandNoCache(
diff --git a/main/main.cpp b/main/main.cpp
index b4fbc1929c..6cc877f8c2 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -56,7 +56,6 @@
#include "main/main_timer_sync.h"
#include "main/performance.h"
#include "main/splash.gen.h"
-#include "main/splash_editor.gen.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
#include "scene/main/scene_tree.h"
@@ -86,6 +85,9 @@
#include "editor/editor_settings.h"
#include "editor/progress_dialog.h"
#include "editor/project_manager.h"
+#ifndef NO_EDITOR_SPLASH
+#include "main/splash_editor.gen.h"
+#endif
#endif
#include "modules/modules_enabled.gen.h" // For mono.
@@ -421,7 +423,7 @@ Error Main::test_setup() {
register_server_types();
translation_server->setup(); //register translations, load them, etc.
- if (locale != "") {
+ if (!locale.is_empty()) {
translation_server->set_locale(locale);
}
translation_server->load_translations();
@@ -442,6 +444,9 @@ Error Main::test_setup() {
register_module_types();
register_driver_types();
+ // Theme needs modules to be initialized so that sub-resources can be loaded.
+ initialize_theme();
+
ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE);
TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(0));
@@ -1117,7 +1122,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
// Network file system needs to be configured before globals, since globals are based on the
// 'project.godot' file which will only be available through the network if this is enabled
FileAccessNetwork::configure();
- if (remotefs != "") {
+ if (!remotefs.is_empty()) {
file_access_network_client = memnew(FileAccessNetworkClient);
int port;
if (remotefs.find(":") != -1) {
@@ -1284,7 +1289,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
PROPERTY_HINT_ENUM, "vulkan,opengl3"));
// if not set on the command line
- if (rendering_driver == "") {
+ if (rendering_driver.is_empty()) {
rendering_driver = GLOBAL_GET("rendering/driver/driver_name");
}
@@ -1414,7 +1419,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->set_display_driver_id(display_driver_idx);
GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name());
- if (audio_driver == "") { // Specified in project.godot.
+ if (audio_driver.is_empty()) { // Specified in project.godot.
audio_driver = GLOBAL_GET("audio/driver/driver");
}
@@ -1605,9 +1610,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ProjectSettings::get_singleton()->set_custom_property_info("input_devices/pen_tablet/driver.windows", PropertyInfo(Variant::STRING, "input_devices/pen_tablet/driver.windows", PROPERTY_HINT_ENUM, "wintab,winink"));
}
- if (tablet_driver == "") { // specified in project.godot
+ if (tablet_driver.is_empty()) { // specified in project.godot
tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver");
- if (tablet_driver == "") {
+ if (tablet_driver.is_empty()) {
tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0);
}
}
@@ -1619,7 +1624,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
}
}
- if (DisplayServer::get_singleton()->tablet_get_current_driver() == "") {
+ if (DisplayServer::get_singleton()->tablet_get_current_driver().is_empty()) {
DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0));
}
@@ -1712,7 +1717,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Ref<Image> boot_logo;
if (boot_logo_image) {
- if (boot_logo_path != String()) {
+ if (!boot_logo_path.is_empty()) {
boot_logo.instantiate();
Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo);
if (load_err) {
@@ -1806,7 +1811,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
MAIN_PRINT("Main: Load Translations and Remaps");
translation_server->setup(); //register translations, load them, etc.
- if (locale != "") {
+ if (!locale.is_empty()) {
translation_server->set_locale(locale);
}
translation_server->load_translations();
@@ -1828,11 +1833,11 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
/* Determine text driver */
- if (text_driver == "") {
+ if (text_driver.is_empty()) {
text_driver = GLOBAL_GET("internationalization/rendering/text_driver");
}
- if (text_driver != "") {
+ if (!text_driver.is_empty()) {
/* Load user selected text server. */
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) {
@@ -1882,6 +1887,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
register_platform_apis();
register_module_types();
+ // Theme needs modules to be initialized so that sub-resources can be loaded.
+ initialize_theme();
+
GLOBAL_DEF("display/mouse_cursor/custom_image", String());
GLOBAL_DEF("display/mouse_cursor/custom_image_hotspot", Vector2());
GLOBAL_DEF("display/mouse_cursor/tooltip_position_offset", Point2(10, 10));
@@ -1978,7 +1986,7 @@ bool Main::start() {
} else if (args[i] == "-p" || args[i] == "--project-manager") {
project_manager = true;
#endif
- } else if (args[i].length() && args[i][0] != '-' && positional_arg == "") {
+ } else if (args[i].length() && args[i][0] != '-' && positional_arg.is_empty()) {
positional_arg = args[i];
if (args[i].ends_with(".scn") ||
@@ -2037,7 +2045,7 @@ bool Main::start() {
}
#ifdef TOOLS_ENABLED
- if (doc_tool_path != "") {
+ if (!doc_tool_path.is_empty()) {
// Needed to instance editor-only classes for their default values
Engine::get_singleton()->set_editor_hint(true);
@@ -2116,12 +2124,12 @@ bool Main::start() {
}
#endif
- if (script == "" && game_path == "" && String(GLOBAL_GET("application/run/main_scene")) != "") {
+ if (script.is_empty() && game_path.is_empty() && String(GLOBAL_GET("application/run/main_scene")) != "") {
game_path = GLOBAL_GET("application/run/main_scene");
}
#ifdef TOOLS_ENABLED
- if (!editor && !project_manager && !cmdline_tool && script == "" && game_path == "") {
+ if (!editor && !project_manager && !cmdline_tool && script.is_empty() && game_path.is_empty()) {
// If we end up here, it means we didn't manage to detect what we want to run.
// Let's throw an error gently. The code leading to this is pretty brittle so
// this might end up triggered by valid usage, in which case we'll have to
@@ -2137,7 +2145,7 @@ bool Main::start() {
}
String main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "SceneTree");
- if (script != "") {
+ if (!script.is_empty()) {
Ref<Script> script_res = ResourceLoader::load(script);
ERR_FAIL_COND_V_MSG(script_res.is_null(), false, "Can't load script: " + script);
@@ -2186,7 +2194,7 @@ bool Main::start() {
}
}
- if (!main_loop && main_loop_type == "") {
+ if (!main_loop && main_loop_type.is_empty()) {
main_loop_type = "SceneTree";
}
@@ -2227,7 +2235,7 @@ bool Main::start() {
ResourceSaver::add_custom_savers();
if (!project_manager && !editor) { // game
- if (game_path != "" || script != "") {
+ if (!game_path.is_empty() || !script.is_empty()) {
//autoload
OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
@@ -2294,7 +2302,7 @@ bool Main::start() {
editor_node = memnew(EditorNode);
sml->get_root()->add_child(editor_node);
- if (_export_preset != "") {
+ if (!_export_preset.is_empty()) {
editor_node->export_preset(_export_preset, positional_arg, export_debug, export_pack_only);
game_path = ""; // Do not load anything.
}
@@ -2409,7 +2417,7 @@ bool Main::start() {
#endif
String local_game_path;
- if (game_path != "" && !project_manager) {
+ if (!game_path.is_empty() && !project_manager) {
local_game_path = game_path.replace("\\", "/");
if (!local_game_path.begins_with("res://")) {
@@ -2465,7 +2473,7 @@ bool Main::start() {
// Load SSL Certificates from Project Settings (or builtin).
Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificate_bundle_override", ""));
- if (game_path != "") {
+ if (!game_path.is_empty()) {
Node *scene = nullptr;
Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
if (scenedata.is_valid()) {
@@ -2477,7 +2485,7 @@ bool Main::start() {
#ifdef OSX_ENABLED
String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()");
- if (mac_iconpath != "") {
+ if (!mac_iconpath.is_empty()) {
DisplayServer::get_singleton()->set_native_icon(mac_iconpath);
hasicon = true;
}
@@ -2485,14 +2493,14 @@ bool Main::start() {
#ifdef WINDOWS_ENABLED
String win_iconpath = GLOBAL_DEF("application/config/windows_native_icon", "Variant()");
- if (win_iconpath != "") {
+ if (!win_iconpath.is_empty()) {
DisplayServer::get_singleton()->set_native_icon(win_iconpath);
hasicon = true;
}
#endif
String iconpath = GLOBAL_DEF("application/config/icon", "Variant()");
- if ((iconpath != "") && (!hasicon)) {
+ if ((!iconpath.is_empty()) && (!hasicon)) {
Ref<Image> icon;
icon.instantiate();
if (ImageLoader::load_image(iconpath, icon) == OK) {
diff --git a/main/splash_editor.png b/main/splash_editor.png
deleted file mode 100644
index 49af9fde22..0000000000
--- a/main/splash_editor.png
+++ /dev/null
Binary files differ
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 1f962772e7..edb2bcb4c7 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -107,7 +107,14 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo
PhysicsDirectSpaceState3D::ShapeResult &result = m_results[count];
- result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) {
+ result.shape = convexResult.m_localShapeInfo->m_triangleIndex;
+ } else {
+ result.shape = 0;
+ }
+
result.rid = gObj->get_self();
result.collider_id = gObj->get_instance_id();
result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id);
@@ -171,11 +178,14 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
}
btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- if (convexResult.m_localShapeInfo) {
- m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) {
+ m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex;
} else {
m_shapeId = 0;
}
+
return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
}
@@ -219,10 +229,22 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
CollisionObjectBullet *colObj;
if (m_self_object == colObj0Wrap->getCollisionObject()) {
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
- result.shape = cp.m_index1;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) {
+ result.shape = cp.m_index1;
+ } else {
+ result.shape = 0;
+ }
} else {
colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
- result.shape = cp.m_index0;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) {
+ result.shape = cp.m_index0;
+ } else {
+ result.shape = 0;
+ }
}
result.collider_id = colObj->get_instance_id();
@@ -311,14 +333,26 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
CollisionObjectBullet *colObj;
if (m_self_object == colObj0Wrap->getCollisionObject()) {
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
- m_result->shape = cp.m_index1;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) {
+ m_result->shape = cp.m_index1;
+ } else {
+ m_result->shape = 0;
+ }
B_TO_G(cp.getPositionWorldOnB(), m_result->point);
B_TO_G(cp.m_normalWorldOnB, m_result->normal);
m_rest_info_bt_point = cp.getPositionWorldOnB();
m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
} else {
colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
- m_result->shape = cp.m_index0;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) {
+ m_result->shape = cp.m_index0;
+ } else {
+ m_result->shape = 0;
+ }
B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal);
m_rest_info_bt_point = cp.getPositionWorldOnA();
m_rest_info_collision_object = colObj0Wrap->getCollisionObject();
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 96a649d77a..3dfa21aec8 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -70,8 +70,10 @@ public:
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
- if (rayResult.m_localShapeInfo) {
- m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart == -1) {
+ m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex;
} else {
m_shapeId = 0;
}
diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp
index 86baec4244..26c9ef8d54 100644
--- a/modules/fbx/data/fbx_material.cpp
+++ b/modules/fbx/data/fbx_material.cpp
@@ -60,7 +60,7 @@ String find_file(const String &p_base, const String &p_file_to_find) {
dir.list_dir_begin();
String n = dir.get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n == "." || n == "..") {
n = dir.get_next();
continue;
@@ -68,7 +68,7 @@ String find_file(const String &p_base, const String &p_file_to_find) {
if (dir.current_is_dir()) {
// Don't use `path_to` or the returned path will be wrong.
const String f = find_file(p_base + "/" + n, p_file_to_find);
- if (f != "") {
+ if (!f.is_empty()) {
return f;
}
} else if (n == p_file_to_find) {
@@ -119,7 +119,7 @@ String FBXMaterial::find_texture_path_by_filename(const String p_filename, const
dir.open("res://");
dir.list_dir_begin();
String n = dir.get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n == "." || n == "..") {
n = dir.get_next();
continue;
@@ -136,7 +136,7 @@ String FBXMaterial::find_texture_path_by_filename(const String p_filename, const
lower_n.find("picture") >= 0) {
// Don't use `path_to` or the returned path will be wrong.
const String f = find_file(String("res://") + n, p_filename);
- if (f != "") {
+ if (!f.is_empty()) {
return f;
}
}
diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
index 2cc25a0690..2bb634ea56 100644
--- a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
+++ b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
@@ -368,7 +368,7 @@ MeshGeometry::MappingData<T> MeshGeometry::resolve_vertex_data_array(
// UVIndex, MaterialIndex, NormalIndex, etc..
std::string indexDataElementName;
- if (indexOverride != "") {
+ if (!indexOverride.empty()) {
// Colors should become ColorIndex
indexDataElementName = indexOverride;
} else {
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 9dad13a615..df3c37f730 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -110,7 +110,7 @@ void GDNativeLibraryEditor::_update_tree() {
TreeItem *new_arch = tree->create_item(platform);
new_arch->set_text(0, TTR("Double click to create a new entry"));
- new_arch->set_text_align(0, TreeItem::ALIGN_CENTER);
+ new_arch->set_text_alignment(0, HORIZONTAL_ALIGNMENT_CENTER);
new_arch->set_custom_color(0, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
new_arch->set_expand_right(0, true);
new_arch->set_metadata(1, E->key());
@@ -335,7 +335,7 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
hbox->add_child(label);
filter = memnew(MenuButton);
filter->set_h_size_flags(SIZE_EXPAND_FILL);
- filter->set_text_align(filter->ALIGN_LEFT);
+ filter->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
hbox->add_child(filter);
PopupMenu *filter_list = filter->get_popup();
filter_list->set_hide_on_checkable_item_selection(false);
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 598f7c7ad0..ae16c22849 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -397,7 +397,7 @@ List<ClassAPI> generate_c_api_classes() {
arg_type = "Variant";
} else if (arg_info.type == Variant::OBJECT) {
arg_type = arg_info.class_name;
- if (arg_type == "") {
+ if (arg_type.is_empty()) {
arg_type = Variant::get_type_name(arg_info.type);
}
} else {
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 368eb67fa6..075977b60f 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -682,7 +682,7 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
ERR_CONTINUE(info.type < 0 || info.type >= Variant::VARIANT_MAX);
info.name = d["name"];
- ERR_CONTINUE(info.name == "");
+ ERR_CONTINUE(info.name.is_empty());
if (d.has("hint")) {
info.hint = PropertyHint(d["hint"].operator int64_t());
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index 04a293ddbd..5bda9e1d53 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -232,8 +232,7 @@ bool PluginScript::instance_has(const Object *p_this) const {
}
bool PluginScript::has_source_code() const {
- bool has = _source != "";
- return has;
+ return !_source.is_empty();
}
String PluginScript::get_source_code() const {
@@ -257,11 +256,11 @@ Error PluginScript::reload(bool p_keep_state) {
_valid = false;
String basedir = _path;
- if (basedir == "") {
+ if (basedir.is_empty()) {
basedir = get_path();
}
- if (basedir != "") {
+ if (!basedir.is_empty()) {
basedir = basedir.get_base_dir();
}
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
index 7faacfdcb9..c4fbff69f0 100644
--- a/modules/gdnative/pluginscript/register_types.cpp
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -44,9 +44,9 @@
static List<PluginScriptLanguage *> pluginscript_languages;
static Error _check_language_desc(const godot_pluginscript_language_desc *desc) {
- ERR_FAIL_COND_V(!desc->name || desc->name == String(), ERR_BUG);
- ERR_FAIL_COND_V(!desc->type || desc->type == String(), ERR_BUG);
- ERR_FAIL_COND_V(!desc->extension || desc->extension == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->name, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->type, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->extension, ERR_BUG);
ERR_FAIL_COND_V(!desc->recognized_extensions || !desc->recognized_extensions[0], ERR_BUG);
ERR_FAIL_COND_V(!desc->init, ERR_BUG);
ERR_FAIL_COND_V(!desc->finish, ERR_BUG);
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 9c8adb4cf1..33f4198ac1 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -4,10 +4,10 @@
Built-in GDScript functions.
</brief_description>
<description>
- List of core built-in GDScript functions. Math functions and other utilities. Everything else is provided by objects. (Keywords: builtin, built in, global functions.)
+ A list of GDScript-specific utility functions accessed in any script.
+ For the list of the global functions and constants see [@GlobalScope].
</description>
<tutorials>
- <link title="Random number generation">$DOCS_URL/tutorials/math/random_number_generation.html</link>
</tutorials>
<methods>
<method name="Color8">
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 6529154e5c..4f711dfd1e 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -413,7 +413,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
previous_column = j;
// ignore if just whitespace
- if (text != "") {
+ if (!text.is_empty()) {
previous_text = text;
}
}
@@ -509,7 +509,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
for (const String &comment : comments) {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
- add_color_region(beg, end, comment_color, end == "");
+ add_color_region(beg, end, comment_color, end.is_empty());
}
/* Strings */
@@ -519,7 +519,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
for (const String &string : strings) {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
- add_color_region(beg, end, string_color, end == "");
+ add_color_region(beg, end, string_color, end.is_empty());
}
const Ref<Script> script = _get_edited_resource();
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index b76c2c0437..4822e411ce 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -389,7 +389,7 @@ bool GDScript::instance_has(const Object *p_this) const {
}
bool GDScript::has_source_code() const {
- return source != "";
+ return !source.is_empty();
}
String GDScript::get_source_code() const {
@@ -458,7 +458,7 @@ void GDScript::_update_doc() {
doc.is_script_doc = true;
if (base.is_valid() && base->is_valid()) {
- if (base->doc.name != String()) {
+ if (!base->doc.name.is_empty()) {
doc.inherits = base->doc.name;
} else {
doc.inherits = base->get_instance_base_type();
@@ -472,7 +472,7 @@ void GDScript::_update_doc() {
doc.tutorials = doc_tutorials;
for (const KeyValue<String, DocData::EnumDoc> &E : doc_enums) {
- if (E.value.description != "") {
+ if (!E.value.description.is_empty()) {
doc.enums[E.key] = E.value.description;
}
}
@@ -616,11 +616,11 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
String basedir = path;
- if (basedir == "") {
+ if (basedir.is_empty()) {
basedir = get_path();
}
- if (basedir != "") {
+ if (!basedir.is_empty()) {
basedir = basedir.get_base_dir();
}
@@ -642,7 +642,7 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
path = c->extends_path;
if (path.is_relative_path()) {
String base = get_path();
- if (base == "" || base.is_relative_path()) {
+ if (base.is_empty() || base.is_relative_path()) {
ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data());
} else {
path = base.get_base_dir().plus_file(path);
@@ -656,7 +656,7 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
}
}
- if (path != "") {
+ if (!path.is_empty()) {
if (path != get_path()) {
Ref<GDScript> bf = ResourceLoader::load(path);
@@ -809,11 +809,11 @@ Error GDScript::reload(bool p_keep_state) {
String basedir = path;
- if (basedir == "") {
+ if (basedir.is_empty()) {
basedir = get_path();
}
- if (basedir != "") {
+ if (!basedir.is_empty()) {
basedir = basedir.get_base_dir();
}
@@ -1122,7 +1122,7 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript)
String class_name;
while (p_gdscript) {
- if (class_name == "") {
+ if (class_name.is_empty()) {
class_name = p_gdscript->get_script_class_name();
} else {
class_name = p_gdscript->get_script_class_name() + "." + class_name;
@@ -1433,7 +1433,7 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
pinfo.type = Variant::Type(d["type"].operator int());
ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX);
pinfo.name = d["name"];
- ERR_CONTINUE(pinfo.name == "");
+ ERR_CONTINUE(pinfo.name.is_empty());
if (d.has("hint")) {
pinfo.hint = PropertyHint(d["hint"].operator int());
}
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index bb0d9e9e9b..d0e85147f1 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -117,7 +117,7 @@ void GDScriptCache::remove_script(const String &p_path) {
Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) {
MutexLock lock(singleton->lock);
Ref<GDScriptParserRef> ref;
- if (p_owner != String()) {
+ if (!p_owner.is_empty()) {
singleton->dependencies[p_owner].insert(p_path);
}
if (singleton->parser_map.has(p_path)) {
@@ -163,7 +163,7 @@ String GDScriptCache::get_source_code(const String &p_path) {
Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) {
MutexLock lock(singleton->lock);
- if (p_owner != String()) {
+ if (!p_owner.is_empty()) {
singleton->dependencies[p_owner].insert(p_path);
}
if (singleton->full_gdscript_cache.has(p_path)) {
@@ -186,13 +186,21 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri
Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) {
MutexLock lock(singleton->lock);
- if (p_owner != String()) {
+ if (!p_owner.is_empty()) {
singleton->dependencies[p_owner].insert(p_path);
}
r_error = OK;
if (singleton->full_gdscript_cache.has(p_path)) {
- return singleton->full_gdscript_cache[p_path];
+ Ref<GDScript> script = singleton->full_gdscript_cache[p_path];
+#ifdef TOOLS_ENABLED
+ uint64_t mt = FileAccess::get_modified_time(p_path);
+ if (script->get_last_modified_time() == mt) {
+ return script;
+ }
+#else
+ return script;
+#endif //TOOLS_ENABLED
}
Ref<GDScript> script = get_shallow_script(p_path);
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index ab0fe5c37d..bba664c328 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -65,7 +65,7 @@ bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringNa
}
void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) {
- if (error != "") {
+ if (!error.is_empty()) {
return;
}
@@ -2020,7 +2020,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
if (EngineDebugger::is_active()) {
String signature;
// Path.
- if (p_script->get_path() != String()) {
+ if (!p_script->get_path().is_empty()) {
signature += p_script->get_path();
}
// Location.
@@ -2158,7 +2158,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->tool = parser->is_tool();
p_script->name = p_class->identifier ? p_class->identifier->name : "";
- if (p_script->name != "") {
+ if (!p_script->name.is_empty()) {
if (ClassDB::class_exists(p_script->name) && ClassDB::is_class_exposed(p_script->name)) {
_set_error("The class '" + p_script->name + "' shadows a native class", p_class);
return ERR_ALREADY_EXISTS;
@@ -2287,7 +2287,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->constants.insert(name, constant->initializer->reduced_value);
#ifdef TOOLS_ENABLED
p_script->member_lines[name] = constant->start_line;
- if (constant->doc_description != String()) {
+ if (!constant->doc_description.is_empty()) {
p_script->doc_constants[name] = constant->doc_description;
}
#endif
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 71d2699c2e..34fe2364cb 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -1365,7 +1365,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
String arg1 = args[0];
if (arg1.begins_with("/root/")) {
String which = arg1.get_slice("/", 2);
- if (which != "") {
+ if (!which.is_empty()) {
// Try singletons first
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(which)) {
r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]);
@@ -2753,7 +2753,7 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
}
String st = l.substr(tc, l.length()).strip_edges();
- if (st == "" || st.begins_with("#")) {
+ if (st.is_empty() || st.begins_with("#")) {
continue; //ignore!
}
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 9d076a8e4c..e1ed71a268 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -192,7 +192,7 @@ public:
GDScriptDataType() = default;
- GDScriptDataType &operator=(const GDScriptDataType &p_other) {
+ void operator=(const GDScriptDataType &p_other) {
kind = p_other.kind;
has_type = p_other.has_type;
builtin_type = p_other.builtin_type;
@@ -203,7 +203,6 @@ public:
if (p_other.has_container_element_type()) {
set_container_element_type(p_other.get_container_element_type());
}
- return *this;
}
GDScriptDataType(const GDScriptDataType &p_other) {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 41b2d2191c..98a93a1a53 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3100,7 +3100,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
if (!comments.has(p_line)) {
return;
}
- ERR_FAIL_COND(p_brief != "" || p_desc != "" || p_tutorials.size() != 0);
+ ERR_FAIL_COND(!p_brief.is_empty() || !p_desc.is_empty() || p_tutorials.size() != 0);
int line = p_line;
bool in_codeblock = false;
@@ -3132,7 +3132,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
String striped_line = doc_line.strip_edges();
// Set the read mode.
- if (striped_line.begins_with("@desc:") && p_desc == "") {
+ if (striped_line.begins_with("@desc:") && p_desc.is_empty()) {
mode = DESC;
striped_line = striped_line.trim_prefix("@desc:");
in_codeblock = _in_codeblock(doc_line, in_codeblock);
@@ -3413,7 +3413,7 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation)
Variant::construct(parameter.type, r, &(name), 1, error);
p_annotation->resolved_arguments.push_back(r);
if (error.error != Callable::CallError::CALL_OK) {
- push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
+ push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1);
return false;
}
@@ -3422,13 +3422,13 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation)
[[fallthrough]];
default: {
if (argument->type != Node::LITERAL) {
- push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
+ push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
return false;
}
Variant value = static_cast<LiteralNode *>(argument)->value;
if (!Variant::can_convert_strict(value.get_type(), parameter.type)) {
- push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
+ push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
return false;
}
Callable::CallError error;
@@ -3437,7 +3437,7 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation)
Variant::construct(parameter.type, r, &(args), 1, error);
p_annotation->resolved_arguments.push_back(r);
if (error.error != Callable::CallError::CALL_OK) {
- push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
+ push_error(vformat(R"(Expected %s as argument %d of annotation "%s".)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name));
p_annotation->resolved_arguments.remove_at(p_annotation->resolved_arguments.size() - 1);
return false;
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index af9b973ada..2f05b4b948 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -203,7 +203,7 @@ public:
return !(this->operator==(p_other));
}
- DataType &operator=(const DataType &p_other) {
+ void operator=(const DataType &p_other) {
kind = p_other.kind;
type_source = p_other.type_source;
is_constant = p_other.is_constant;
@@ -221,7 +221,6 @@ public:
if (p_other.has_container_element_type()) {
set_container_element_type(p_other.get_container_element_type());
}
- return *this;
}
DataType() = default;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 6dd8c3e0dd..be9e5df2b0 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -755,7 +755,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
String v = index->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(index) + "'";
@@ -785,7 +785,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
String v = index->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(index) + "'";
@@ -817,7 +817,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (oob) {
String v = index->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(index) + "'";
@@ -848,7 +848,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
String v = index->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(index) + "'";
@@ -884,7 +884,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
String v = key->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(key) + "'";
@@ -917,7 +917,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (oob) {
String v = index->operator String();
- if (v != "") {
+ if (!v.is_empty()) {
v = "'" + v + "'";
} else {
v = "of type '" + _get_var_type(index) + "'";
@@ -3295,20 +3295,20 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
//error
// function, file, line, error, explanation
String err_file;
- if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") {
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && !p_instance->script->path.is_empty()) {
err_file = p_instance->script->path;
} else if (script) {
err_file = script->path;
}
- if (err_file == "") {
+ if (err_file.is_empty()) {
err_file = "<built-in>";
}
String err_func = name;
- if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") {
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && !p_instance->script->name.is_empty()) {
err_func = p_instance->script->name + "." + err_func;
}
int err_line = line;
- if (err_text == "") {
+ if (err_text.is_empty()) {
err_text = "Internal script error! Opcode: " + itos(last_opcode) + " (please report).";
}
diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h
index f1413f0133..feee23dd13 100644
--- a/modules/gdscript/language_server/gdscript_language_server.h
+++ b/modules/gdscript/language_server/gdscript_language_server.h
@@ -45,7 +45,7 @@ class GDScriptLanguageServer : public EditorPlugin {
bool started = false;
bool use_thread = false;
String host = "127.0.0.1";
- int port = 6008;
+ int port = 6005;
static void thread_main(void *p_userdata);
private:
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 92ce71f395..d2e033d7de 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -428,9 +428,6 @@ GDScriptTextDocument::~GDScriptTextDocument() {
void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) {
String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path);
- if (!path.begins_with("res://")) {
- return;
- }
GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content);
EditorFileSystem::get_singleton()->update_file(path);
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 932bfb2caa..9be9cbc749 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -54,9 +54,13 @@ void GDScriptWorkspace::_bind_methods() {
}
void GDScriptWorkspace::apply_new_signal(Object *obj, String function, PackedStringArray args) {
- String function_signature = "func " + function;
Ref<Script> script = obj->get_script();
+ if (script->get_language()->get_name() != "GDScript") {
+ return;
+ }
+
+ String function_signature = "func " + function;
String source = script->get_source_code();
if (source.find(function_signature) != -1) {
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index d2e71efee7..21883b3c6e 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -267,7 +267,7 @@ bool GDScriptTestRunner::generate_class_index() {
String base_type;
String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(test.get_source_file(), &base_type);
- if (class_name == String()) {
+ if (class_name.is_empty()) {
continue;
}
ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false,
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index dd545ff431..69bf59f848 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -120,7 +120,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
preamble += "#define has_VK_KHR_multiview 1\n";
}
- if (preamble != "") {
+ if (!preamble.empty()) {
shader.setPreamble(preamble.c_str());
}
diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/gltf_animation.h
index be0ed2d4c6..763494cb8d 100644
--- a/modules/gltf/gltf_animation.h
+++ b/modules/gltf/gltf_animation.h
@@ -50,7 +50,7 @@ public:
template <class T>
struct Channel {
Interpolation interpolation;
- Vector<float> times;
+ Vector<real_t> times;
Vector<T> values;
};
@@ -58,7 +58,7 @@ public:
Channel<Vector3> position_track;
Channel<Quaternion> rotation_track;
Channel<Vector3> scale_track;
- Vector<Channel<float>> weight_tracks;
+ Vector<Channel<real_t>> weight_tracks;
};
public:
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index f3317aeada..bdba5130ec 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -192,7 +192,7 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &
uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time;
float elapsed_sec = double(elapsed) / 1000000.0;
elapsed_sec = Math::snapped(elapsed_sec, 0.01f);
- print_line("glTF: Export time elapsed seconds " + rtos(elapsed_sec).pad_decimals(2));
+ print_verbose("glTF: Export time elapsed seconds " + rtos(elapsed_sec).pad_decimals(2));
return OK;
}
@@ -4804,7 +4804,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
bool last = false;
Vector<real_t> weight_track;
while (true) {
- float weight = _interpolate_track<float>(track.weight_tracks[track_idx].times,
+ float weight = _interpolate_track<real_t>(track.weight_tracks[track_idx].times,
track.weight_tracks[track_idx].values,
time,
track.weight_tracks[track_idx].interpolation);
@@ -4828,7 +4828,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
int32_t weight_tracks_size = track.weight_tracks.size();
all_track_values.resize(weight_tracks_size * values_size);
for (int k = 0; k < track.weight_tracks.size(); k++) {
- Vector<float> wdata = track.weight_tracks[k].values;
+ Vector<real_t> wdata = track.weight_tracks[k].values;
for (int l = 0; l < wdata.size(); l++) {
int32_t index = l * weight_tracks_size + k;
ERR_BREAK(index >= all_track_values.size());
@@ -4979,10 +4979,10 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
const int wlen = weights.size() / wc;
for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea
- GLTFAnimation::Channel<float> cf;
+ GLTFAnimation::Channel<real_t> cf;
cf.interpolation = interp;
cf.times = Variant(times);
- Vector<float> wdata;
+ Vector<real_t> wdata;
wdata.resize(wlen);
for (int l = 0; l < wlen; l++) {
wdata.write[l] = weights[l * wc + k];
@@ -5772,7 +5772,7 @@ struct EditorSceneFormatImporterGLTFInterpolate<Quaternion> {
};
template <class T>
-T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
+T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
ERR_FAIL_COND_V(!p_values.size(), T());
if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) {
ERR_PRINT_ONCE("The interpolated values are not corresponding to its times.");
@@ -6052,7 +6052,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap,
double time = 0.0;
bool last = false;
while (true) {
- float blend = _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
+ real_t blend = _interpolate_track<real_t>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
animation->blend_shape_track_insert_key(track_idx, time, blend);
if (last) {
break;
@@ -6246,7 +6246,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
}
Animation::TrackType track_type = p_animation->track_get_type(p_track_i);
int32_t key_count = p_animation->track_get_key_count(p_track_i);
- Vector<float> times;
+ Vector<real_t> times;
times.resize(key_count);
String path = p_animation->track_get_path(p_track_i);
for (int32_t key_i = 0; key_i < key_count; key_i++) {
@@ -6352,7 +6352,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
if (path.find("/scale") != -1) {
const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS;
if (!p_track.scale_track.times.size()) {
- Vector<float> new_times;
+ Vector<real_t> new_times;
new_times.resize(keys);
for (int32_t key_i = 0; key_i < keys; key_i++) {
new_times.write[key_i] = key_i / BAKE_FPS;
@@ -6382,7 +6382,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
} else if (path.find("/position") != -1) {
const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS;
if (!p_track.position_track.times.size()) {
- Vector<float> new_times;
+ Vector<real_t> new_times;
new_times.resize(keys);
for (int32_t key_i = 0; key_i < keys; key_i++) {
new_times.write[key_i] = key_i / BAKE_FPS;
@@ -6503,7 +6503,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
NodePath shape_path = String(path) + ":" + shape_name;
int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE);
if (shape_track_i == -1) {
- GLTFAnimation::Channel<float> weight;
+ GLTFAnimation::Channel<real_t> weight;
weight.interpolation = GLTFAnimation::INTERP_LINEAR;
weight.times.push_back(0.0f);
weight.times.push_back(0.0f);
@@ -6522,7 +6522,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE;
}
int32_t key_count = animation->track_get_key_count(shape_track_i);
- GLTFAnimation::Channel<float> weight;
+ GLTFAnimation::Channel<real_t> weight;
weight.interpolation = gltf_interpolation;
weight.times.resize(key_count);
for (int32_t time_i = 0; time_i < key_count; time_i++) {
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 27a1f64bca..f8d9521733 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -293,7 +293,7 @@ private:
Node3D *_generate_spatial(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index);
void _assign_scene_names(Ref<GLTFState> state);
template <class T>
- T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values,
+ T _interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values,
const float p_time,
const GLTFAnimation::Interpolation p_interp);
GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> state,
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index d827ce2fb0..c2169c6335 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -885,11 +885,11 @@ void GridMapEditor::update_palette() {
String name = mesh_library->get_item_name(id);
Ref<Texture2D> preview = mesh_library->get_item_preview(id);
- if (name == "") {
+ if (name.is_empty()) {
name = "#" + itos(id);
}
- if (filter != "" && !filter.is_subsequence_ofi(name)) {
+ if (!filter.is_empty() && !filter.is_subsequence_ofi(name)) {
continue;
}
@@ -1163,7 +1163,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
spatial_editor_hb = memnew(HBoxContainer);
spatial_editor_hb->set_h_size_flags(SIZE_EXPAND_FILL);
- spatial_editor_hb->set_alignment(BoxContainer::ALIGN_END);
+ spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_END);
Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb);
spin_box_label = memnew(Label);
@@ -1280,8 +1280,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
info_message = memnew(Label);
info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
- info_message->set_valign(Label::VALIGN_CENTER);
- info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index 32a31aa764..ea28d0c0c8 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -41,7 +41,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
while (true) {
String line = f->get_line();
ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED);
- if (line == "") { // empty line indicates end of header
+ if (line.is_empty()) { // empty line indicates end of header
break;
}
if (line.begins_with("FORMAT=")) { // leave option to implement other commands
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 2522f1bb11..9d985e16d4 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -310,7 +310,7 @@ void CryptoMbedTLS::load_default_certificates(String p_path) {
default_certs = memnew(X509CertificateMbedTLS);
ERR_FAIL_COND(default_certs == nullptr);
- if (p_path != "") {
+ if (!p_path.is_empty()) {
// Use certs defined in project settings.
default_certs->load(p_path);
}
diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp
index 49e9f5f97e..17406b7263 100644
--- a/modules/minimp3/audio_stream_mp3.cpp
+++ b/modules/minimp3/audio_stream_mp3.cpp
@@ -125,7 +125,7 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() {
Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() {
Ref<AudioStreamPlaybackMP3> mp3s;
- ERR_FAIL_COND_V_MSG(data == nullptr, mp3s,
+ ERR_FAIL_COND_V_MSG(data.is_empty(), mp3s,
"This AudioStreamMP3 does not have an audio file assigned "
"to it. AudioStreamMP3 should not be created from the "
"inspector or with `.new()`. Instead, load an audio file.");
@@ -134,7 +134,7 @@ Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() {
mp3s->mp3_stream = Ref<AudioStreamMP3>(this);
mp3s->mp3d = (mp3dec_ex_t *)memalloc(sizeof(mp3dec_ex_t));
- int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, (const uint8_t *)data, data_len, MP3D_SEEK_TO_SAMPLE);
+ int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, data.ptr(), data_len, MP3D_SEEK_TO_SAMPLE);
mp3s->frames_mixed = 0;
mp3s->active = false;
@@ -152,11 +152,7 @@ String AudioStreamMP3::get_stream_name() const {
}
void AudioStreamMP3::clear_data() {
- if (data) {
- memfree(data);
- data = nullptr;
- data_len = 0;
- }
+ data.clear();
}
void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
@@ -165,7 +161,7 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
mp3dec_ex_t mp3d;
int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE);
- ERR_FAIL_COND(err != 0);
+ ERR_FAIL_COND_MSG(err || mp3d.info.hz == 0, "Failed to decode mp3 file. Make sure it is a valid mp3 audio file.");
channels = mp3d.info.channels;
sample_rate = mp3d.info.hz;
@@ -175,23 +171,13 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
clear_data();
- data = memalloc(src_data_len);
- memcpy(data, src_datar, src_data_len);
+ data.resize(src_data_len);
+ memcpy(data.ptrw(), src_datar, src_data_len);
data_len = src_data_len;
}
Vector<uint8_t> AudioStreamMP3::get_data() const {
- Vector<uint8_t> vdata;
-
- if (data_len && data) {
- vdata.resize(data_len);
- {
- uint8_t *w = vdata.ptrw();
- memcpy(w, data, data_len);
- }
- }
-
- return vdata;
+ return data;
}
void AudioStreamMP3::set_loop(bool p_enable) {
@@ -229,8 +215,8 @@ void AudioStreamMP3::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamMP3::get_loop_offset);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_loop", "has_loop");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_loop_offset", "get_loop_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset");
}
AudioStreamMP3::AudioStreamMP3() {
diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h
index 3c8bdd8c53..e3adfe683b 100644
--- a/modules/minimp3/audio_stream_mp3.h
+++ b/modules/minimp3/audio_stream_mp3.h
@@ -75,7 +75,7 @@ class AudioStreamMP3 : public AudioStream {
friend class AudioStreamPlaybackMP3;
- void *data = nullptr;
+ PackedByteArray data;
uint32_t data_len = 0;
float sample_rate = 1.0;
diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
index 18a77c8b8d..df099f2c98 100644
--- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml
+++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
@@ -37,6 +37,6 @@
<member name="oversample" type="float" setter="set_oversample" getter="get_oversample" default="1.5">
The oversample setting. Because of the lens distortion we have to render our buffers at a higher resolution then the screen can natively handle. A value between 1.5 and 2.0 often provides good results but at the cost of performance.
</member>
- <member name="xr_play_area_mode" type="int" setter="set_play_area_mode" getter="get_play_area_mode" override="true" enum="XRInterface.PlayAreaMode" default="1" />
+ <member name="xr_play_area_mode" type="int" setter="set_play_area_mode" getter="get_play_area_mode" overrides="XRInterface" enum="XRInterface.PlayAreaMode" default="1" />
</members>
</class>
diff --git a/modules/mono/SdkPackageVersions.props b/modules/mono/SdkPackageVersions.props
index df3ebe581c..bdec051625 100644
--- a/modules/mono/SdkPackageVersions.props
+++ b/modules/mono/SdkPackageVersions.props
@@ -1,6 +1,7 @@
<Project>
<PropertyGroup>
- <PackageVersion_Godot_NET_Sdk>4.0.0-dev5</PackageVersion_Godot_NET_Sdk>
- <PackageVersion_Godot_SourceGenerators>4.0.0-dev2</PackageVersion_Godot_SourceGenerators>
+ <PackageFloatingVersion_Godot>4.0.*-*</PackageFloatingVersion_Godot>
+ <PackageVersion_Godot_NET_Sdk>4.0.0-dev6</PackageVersion_Godot_NET_Sdk>
+ <PackageVersion_Godot_SourceGenerators>4.0.0-dev3</PackageVersion_Godot_SourceGenerators>
</PropertyGroup>
</Project>
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 544f2a7584..0ceb45d425 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -788,11 +788,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
- String appname = ProjectSettings::get_singleton()->get("application/config/name");
- String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.is_empty()) {
- appname_safe = "UnnamedProject";
- }
+ String appname_safe = ProjectSettings::get_singleton()->get_safe_project_name();
appname_safe += ".dll";
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
index 92e299d2f3..397ede9644 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
@@ -17,6 +17,6 @@
<!-- C# source generators -->
<ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' ">
- <PackageReference Include="Godot.SourceGenerators" Version="$(PackageVersion_Godot_SourceGenerators)" />
+ <PackageReference Include="Godot.SourceGenerators" Version="$(PackageFloatingVersion_Godot)" />
</ItemGroup>
</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs
new file mode 100644
index 0000000000..2ddb8880c2
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs
@@ -0,0 +1,16 @@
+namespace Godot.SourceGenerators.Sample
+{
+ partial class Generic<T> : Godot.Object
+ {
+ }
+
+ // Generic again but different generic parameters
+ partial class Generic<T, R> : Godot.Object
+ {
+ }
+
+ // Generic again but without generic parameters
+ partial class Generic : Godot.Object
+ {
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
index a51728e221..fa65595290 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
@@ -97,9 +97,13 @@ namespace Godot.SourceGenerators
string.Empty;
bool hasNamespace = classNs.Length != 0;
- string uniqueName = hasNamespace ?
- classNs + "." + className + "_ScriptPath_Generated" :
- className + "_ScriptPath_Generated";
+ var uniqueName = new StringBuilder();
+ if (hasNamespace)
+ uniqueName.Append($"{classNs}.");
+ uniqueName.Append(className);
+ if (symbol.IsGenericType)
+ uniqueName.Append($"Of{string.Join(string.Empty, symbol.TypeParameters)}");
+ uniqueName.Append("_ScriptPath_Generated");
var source = new StringBuilder();
@@ -121,6 +125,8 @@ namespace Godot.SourceGenerators
source.Append(attributes);
source.Append("\n partial class ");
source.Append(className);
+ if (symbol.IsGenericType)
+ source.Append($"<{string.Join(", ", symbol.TypeParameters)}>");
source.Append("\n{\n}\n");
if (hasNamespace)
@@ -128,7 +134,7 @@ namespace Godot.SourceGenerators
source.Append("\n}\n");
}
- context.AddSource(uniqueName, SourceText.From(source.ToString(), Encoding.UTF8));
+ context.AddSource(uniqueName.ToString(), SourceText.From(source.ToString(), Encoding.UTF8));
}
private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
@@ -145,12 +151,15 @@ namespace Godot.SourceGenerators
foreach (var godotClass in godotClasses)
{
var qualifiedName = godotClass.Key.ToDisplayString(
- NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat);
+ NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat
+ .WithGenericsOptions(SymbolDisplayGenericsOptions.None));
if (!first)
sourceBuilder.Append(", ");
first = false;
sourceBuilder.Append("typeof(");
sourceBuilder.Append(qualifiedName);
+ if (godotClass.Key.IsGenericType)
+ sourceBuilder.Append($"<{new string(',', godotClass.Key.TypeParameters.Count() - 1)}>");
sourceBuilder.Append(")");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index b53347fc4c..56fca6b5cb 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -119,7 +119,7 @@ namespace GodotTools.Build
private void IssueActivated(int idx)
{
- if (idx < 0 || idx >= _issuesList.GetItemCount())
+ if (idx < 0 || idx >= _issuesList.ItemCount)
throw new IndexOutOfRangeException("Item list index out of range");
// Get correct issue idx from issue list
@@ -193,7 +193,7 @@ namespace GodotTools.Build
string itemText = lineBreakIdx == -1 ? text : text.Substring(0, lineBreakIdx);
_issuesList.AddItem(itemText, issue.Warning ? warningIcon : errorIcon);
- int index = _issuesList.GetItemCount() - 1;
+ int index = _issuesList.ItemCount - 1;
_issuesList.SetItemTooltip(index, tooltip);
_issuesList.SetItemMetadata(index, i);
}
@@ -207,7 +207,7 @@ namespace GodotTools.Build
_issuesList.Clear();
- var issue = new BuildIssue {Message = cause, Warning = false};
+ var issue = new BuildIssue { Message = cause, Warning = false };
ErrorCount += 1;
_issues.Add(issue);
@@ -348,7 +348,7 @@ namespace GodotTools.Build
label: "Copy Error".TTR(), (int)IssuesContextMenuOption.Copy);
}
- if (_issuesListContextMenu.GetItemCount() > 0)
+ if (_issuesListContextMenu.ItemCount > 0)
{
_issuesListContextMenu.Position = (Vector2i)(_issuesList.RectGlobalPosition + atPosition);
_issuesListContextMenu.Popup();
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 51a27ee934..a7879e96c8 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -598,7 +598,7 @@ class BindingsGenerator {
private:
NameCache(const NameCache &);
- NameCache &operator=(const NameCache &);
+ void operator=(const NameCache &);
};
NameCache name_cache;
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 7433c865f5..61d0890288 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -155,7 +155,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
dir_access->list_dir_begin();
String filename = dir_access->get_next();
- while (filename != "") {
+ while (!filename.is_empty()) {
if (filename == "." || filename == "..") {
filename = dir_access->get_next();
continue;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index bfbf1a097e..656796c5c7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -209,27 +209,6 @@ namespace Godot
}
}
- /// <summary>
- /// Returns the <see cref="Basis"/>'s rotation in the form of a
- /// <see cref="Quaternion"/>. See <see cref="GetEuler"/> if you
- /// need Euler angles, but keep in mind quaternions should generally
- /// be preferred to Euler angles.
- /// </summary>
- /// <returns>The basis rotation.</returns>
- public Quaternion GetRotationQuaternion()
- {
- Basis orthonormalizedBasis = Orthonormalized();
- real_t det = orthonormalizedBasis.Determinant();
- if (det < 0)
- {
- // Ensure that the determinant is 1, such that result is a proper
- // rotation matrix which can be represented by Euler angles.
- orthonormalizedBasis = orthonormalizedBasis.Scaled(-Vector3.One);
- }
-
- return orthonormalizedBasis.Quaternion();
- }
-
internal void SetQuaternionScale(Quaternion quaternion, Vector3 scale)
{
SetDiagonal(scale);
@@ -272,8 +251,8 @@ namespace Godot
/// The returned vector contains the rotation angles in
/// the format (X angle, Y angle, Z angle).
///
- /// Consider using the <see cref="Quaternion()"/> method instead, which
- /// returns a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles.
+ /// Consider using the <see cref="GetRotationQuaternion"/> method instead, which
+ /// returns a <see cref="Quaternion"/> quaternion instead of Euler angles.
/// </summary>
/// <returns>A <see cref="Vector3"/> representing the basis rotation in Euler angles.</returns>
public Vector3 GetEuler()
@@ -309,6 +288,85 @@ namespace Godot
}
/// <summary>
+ /// Returns the basis's rotation in the form of a quaternion.
+ /// See <see cref="GetEuler()"/> if you need Euler angles, but keep in
+ /// mind that quaternions should generally be preferred to Euler angles.
+ /// </summary>
+ /// <returns>A <see cref="Quaternion"/> representing the basis's rotation.</returns>
+ internal Quaternion GetQuaternion()
+ {
+ real_t trace = Row0[0] + Row1[1] + Row2[2];
+
+ if (trace > 0.0f)
+ {
+ real_t s = Mathf.Sqrt(trace + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quaternion(
+ (Row2[1] - Row1[2]) * inv_s,
+ (Row0[2] - Row2[0]) * inv_s,
+ (Row1[0] - Row0[1]) * inv_s,
+ s * 0.25f
+ );
+ }
+
+ if (Row0[0] > Row1[1] && Row0[0] > Row2[2])
+ {
+ real_t s = Mathf.Sqrt(Row0[0] - Row1[1] - Row2[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quaternion(
+ s * 0.25f,
+ (Row0[1] + Row1[0]) * inv_s,
+ (Row0[2] + Row2[0]) * inv_s,
+ (Row2[1] - Row1[2]) * inv_s
+ );
+ }
+
+ if (Row1[1] > Row2[2])
+ {
+ real_t s = Mathf.Sqrt(-Row0[0] + Row1[1] - Row2[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quaternion(
+ (Row0[1] + Row1[0]) * inv_s,
+ s * 0.25f,
+ (Row1[2] + Row2[1]) * inv_s,
+ (Row0[2] - Row2[0]) * inv_s
+ );
+ }
+ else
+ {
+ real_t s = Mathf.Sqrt(-Row0[0] - Row1[1] + Row2[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quaternion(
+ (Row0[2] + Row2[0]) * inv_s,
+ (Row1[2] + Row2[1]) * inv_s,
+ s * 0.25f,
+ (Row1[0] - Row0[1]) * inv_s
+ );
+ }
+ }
+
+ /// <summary>
+ /// Returns the <see cref="Basis"/>'s rotation in the form of a
+ /// <see cref="Quaternion"/>. See <see cref="GetEuler"/> if you
+ /// need Euler angles, but keep in mind quaternions should generally
+ /// be preferred to Euler angles.
+ /// </summary>
+ /// <returns>The basis rotation.</returns>
+ public Quaternion GetRotationQuaternion()
+ {
+ Basis orthonormalizedBasis = Orthonormalized();
+ real_t det = orthonormalizedBasis.Determinant();
+ if (det < 0)
+ {
+ // Ensure that the determinant is 1, such that result is a proper
+ // rotation matrix which can be represented by Euler angles.
+ orthonormalizedBasis = orthonormalizedBasis.Scaled(-Vector3.One);
+ }
+
+ return orthonormalizedBasis.GetQuaternion();
+ }
+
+ /// <summary>
/// Get rows by index. Rows are not very useful for user code,
/// but are more efficient for some internal calculations.
/// </summary>
@@ -600,64 +658,6 @@ namespace Godot
);
}
- /// <summary>
- /// Returns the basis's rotation in the form of a quaternion.
- /// See <see cref="GetEuler()"/> if you need Euler angles, but keep in
- /// mind that quaternions should generally be preferred to Euler angles.
- /// </summary>
- /// <returns>A <see cref="Godot.Quaternion"/> representing the basis's rotation.</returns>
- public Quaternion Quaternion()
- {
- real_t trace = Row0[0] + Row1[1] + Row2[2];
-
- if (trace > 0.0f)
- {
- real_t s = Mathf.Sqrt(trace + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quaternion(
- (Row2[1] - Row1[2]) * inv_s,
- (Row0[2] - Row2[0]) * inv_s,
- (Row1[0] - Row0[1]) * inv_s,
- s * 0.25f
- );
- }
-
- if (Row0[0] > Row1[1] && Row0[0] > Row2[2])
- {
- real_t s = Mathf.Sqrt(Row0[0] - Row1[1] - Row2[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quaternion(
- s * 0.25f,
- (Row0[1] + Row1[0]) * inv_s,
- (Row0[2] + Row2[0]) * inv_s,
- (Row2[1] - Row1[2]) * inv_s
- );
- }
-
- if (Row1[1] > Row2[2])
- {
- real_t s = Mathf.Sqrt(-Row0[0] + Row1[1] - Row2[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quaternion(
- (Row0[1] + Row1[0]) * inv_s,
- s * 0.25f,
- (Row1[2] + Row2[1]) * inv_s,
- (Row0[2] - Row2[0]) * inv_s
- );
- }
- else
- {
- real_t s = Mathf.Sqrt(-Row0[0] - Row1[1] + Row2[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quaternion(
- (Row0[2] + Row2[0]) * inv_s,
- (Row1[2] + Row2[1]) * inv_s,
- s * 0.25f,
- (Row1[0] - Row0[1]) * inv_s
- );
- }
- }
-
private static readonly Basis[] _orthoBases = {
new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
@@ -745,7 +745,7 @@ namespace Godot
/// given in the vector format as (X angle, Y angle, Z angle).
///
/// Consider using the <see cref="Basis(Quaternion)"/> constructor instead, which
- /// uses a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles.
+ /// uses a <see cref="Quaternion"/> quaternion instead of Euler angles.
/// </summary>
/// <param name="eulerYXZ">The Euler angles to create the basis from.</param>
public Basis(Vector3 eulerYXZ)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index a3afc83222..c664463e86 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -127,7 +127,7 @@ namespace Godot
/// </code>
/// </example>
/// <param name="linear">The linear energy to convert.</param>
- /// <returns>Audio as decibels</returns>
+ /// <returns>Audio as decibels.</returns>
public static real_t Linear2Db(real_t linear)
{
return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
index 3051bcedc7..ee4d0eed08 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
@@ -80,6 +80,18 @@ namespace Godot
private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
/// <summary>
+ /// Returns the generic type definition of <paramref name="type"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the given <paramref name="type"/> is not a generic type.
+ /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
+ /// </exception>
+ private static void GetGenericTypeDefinition(Type type, out Type genericTypeDefinition)
+ {
+ genericTypeDefinition = type.GetGenericTypeDefinition();
+ }
+
+ /// <summary>
/// Gets the element type for the given <paramref name="arrayType"/>.
/// </summary>
/// <param name="arrayType">Type for the generic array.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index fbc8ff64a6..bfe9600084 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -624,7 +624,7 @@ namespace Godot
/// </summary>
/// <param name="s">The value to snap.</param>
/// <param name="step">The step size to snap to.</param>
- /// <returns></returns>
+ /// <returns>The snapped value.</returns>
public static real_t Snapped(real_t s, real_t step)
{
if (step != 0f)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
index 9bb73ce7dd..f15d01b34b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
@@ -44,7 +44,7 @@ namespace Godot
/// <summary>
/// Returns the amount of digits after the decimal place.
/// </summary>
- /// <param name="s">The input <see cref="decimal"/> value.</param>
+ /// <param name="s">The input <see langword="decimal"/> value.</param>
/// <returns>The amount of digits.</returns>
public static int DecimalCount(decimal s)
{
@@ -54,7 +54,7 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> upward (towards positive infinity).
///
- /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <c>int</c>.
+ /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to ceil.</param>
/// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
@@ -66,7 +66,7 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> downward (towards negative infinity).
///
- /// This is the same as <see cref="Floor(real_t)"/>, but returns an <c>int</c>.
+ /// This is the same as <see cref="Floor(real_t)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to floor.</param>
/// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
@@ -78,7 +78,7 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> to the nearest whole number.
///
- /// This is the same as <see cref="Round(real_t)"/>, but returns an <c>int</c>.
+ /// This is the same as <see cref="Round(real_t)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to round.</param>
/// <returns>The rounded number.</returns>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
index f53b5dc904..40fb5f8788 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
@@ -122,7 +122,7 @@ namespace Godot
/// "/root/Level/Path2D"
/// </code>
/// </example>
- /// <param name="path"></param>
+ /// <param name="path">A string that represents a path in a scene tree.</param>
public NodePath(string path)
{
ptr = godot_icall_NodePath_Ctor(path);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
index dfb8e87bce..e38dca414f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
@@ -377,7 +377,7 @@ namespace Godot
/// <param name="basis">The <see cref="Basis"/> to construct from.</param>
public Quaternion(Basis basis)
{
- this = basis.Quaternion();
+ this = basis.GetQuaternion();
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index d9ee684c5b..68e6422c19 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -415,6 +415,10 @@ namespace Godot
/// <summary>
/// Find the first occurrence of a substring. Optionally, the search starting position can be passed.
/// </summary>
+ /// <seealso cref="Find(string, char, int, bool)"/>
+ /// <seealso cref="FindLast(string, string, bool)"/>
+ /// <seealso cref="FindLast(string, string, int, bool)"/>
+ /// <seealso cref="FindN(string, string, int)"/>
/// <param name="instance">The string that will be searched.</param>
/// <param name="what">The substring to find.</param>
/// <param name="from">The search starting position.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 6f1d9574a8..8e253388bf 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -23,7 +23,6 @@ namespace Godot
/// <summary>
/// The basis matrix's X vector (column 0). Equivalent to array index <c>[0]</c>.
/// </summary>
- /// <value></value>
public Vector2 x;
/// <summary>
@@ -420,12 +419,12 @@ namespace Godot
/// Constructs a transformation matrix from the given components.
/// Arguments are named such that xy is equal to calling x.y
/// </summary>
- /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c></param>
- /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c></param>
- /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c></param>
- /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c></param>
- /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c></param>
- /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c></param>
+ /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c>.</param>
+ /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c>.</param>
+ /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c>.</param>
+ /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c>.</param>
+ /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c>.</param>
+ /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c>.</param>
public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy)
{
x = new Vector2(xx, xy);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index 4bb8308c12..5d9aabdd2f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -166,7 +166,7 @@ namespace Godot
/// Operations take place in global space.
/// </summary>
/// <param name="target">The object to look at.</param>
- /// <param name="up">The relative up direction</param>
+ /// <param name="up">The relative up direction.</param>
/// <returns>The resulting transform.</returns>
public Transform3D LookingAt(Vector3 target, Vector3 up)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 0c3331900a..1f5282e88f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -17,7 +17,7 @@ namespace Godot
{
/// <summary>
/// Enumerated index values for the axes.
- /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>.
+ /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
/// </summary>
public enum Axis
{
@@ -184,13 +184,13 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product value.</returns>
- public real_t Cross(Vector2 b)
+ public real_t Cross(Vector2 with)
{
- return (x * b.y) - (y * b.x);
+ return (x * with.y) - (y * with.x);
}
/// <summary>
@@ -222,13 +222,13 @@ namespace Godot
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
+ /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
- public Vector2 DirectionTo(Vector2 b)
+ /// <param name="to">The other vector to point towards.</param>
+ /// <returns>The direction from this vector to <paramref name="to"/>.</returns>
+ public Vector2 DirectionTo(Vector2 to)
{
- return new Vector2(b.x - x, b.y - y).Normalized();
+ return new Vector2(to.x - x, to.y - y).Normalized();
}
/// <summary>
@@ -365,21 +365,21 @@ namespace Godot
}
/// <summary>
- /// Returns the axis of the vector's largest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
/// If both components are equal, this method returns <see cref="Axis.X"/>.
/// </summary>
- /// <returns>The index of the largest axis.</returns>
- public Axis MaxAxis()
+ /// <returns>The index of the highest axis.</returns>
+ public Axis MaxAxisIndex()
{
return x < y ? Axis.Y : Axis.X;
}
/// <summary>
- /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
/// If both components are equal, this method returns <see cref="Axis.Y"/>.
/// </summary>
- /// <returns>The index of the smallest axis.</returns>
- public Axis MinAxis()
+ /// <returns>The index of the lowest axis.</returns>
+ public Axis MinAxisIndex()
{
return x < y ? Axis.X : Axis.Y;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index 6cac16d53b..9b51de5c8c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -17,7 +17,7 @@ namespace Godot
{
/// <summary>
/// Enumerated index values for the axes.
- /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>.
+ /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
/// </summary>
public enum Axis
{
@@ -149,45 +149,45 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product vector.</returns>
- public int Cross(Vector2i b)
+ public int Cross(Vector2i with)
{
- return x * b.y - y * b.x;
+ return x * with.y - y * with.x;
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public int DistanceSquaredTo(Vector2i b)
+ public int DistanceSquaredTo(Vector2i to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector2i b)
+ public real_t DistanceTo(Vector2i to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public int Dot(Vector2i b)
+ public int Dot(Vector2i with)
{
- return x * b.x + y * b.y;
+ return x * with.x + y * with.y;
}
/// <summary>
@@ -218,21 +218,21 @@ namespace Godot
}
/// <summary>
- /// Returns the axis of the vector's largest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
/// If both components are equal, this method returns <see cref="Axis.X"/>.
/// </summary>
- /// <returns>The index of the largest axis.</returns>
- public Axis MaxAxis()
+ /// <returns>The index of the highest axis.</returns>
+ public Axis MaxAxisIndex()
{
return x < y ? Axis.Y : Axis.X;
}
/// <summary>
- /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
/// If both components are equal, this method returns <see cref="Axis.Y"/>.
/// </summary>
- /// <returns>The index of the smallest axis.</returns>
- public Axis MinAxis()
+ /// <returns>The index of the lowest axis.</returns>
+ public Axis MinAxisIndex()
{
return x < y ? Axis.X : Axis.Y;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 63d9be0a6d..433a5d9dc9 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -17,7 +17,7 @@ namespace Godot
{
/// <summary>
/// Enumerated index values for the axes.
- /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>.
+ /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
/// </summary>
public enum Axis
{
@@ -170,17 +170,17 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product vector.</returns>
- public Vector3 Cross(Vector3 b)
+ public Vector3 Cross(Vector3 with)
{
return new Vector3
(
- (y * b.z) - (z * b.y),
- (z * b.x) - (x * b.z),
- (x * b.y) - (y * b.x)
+ (y * with.z) - (z * with.y),
+ (z * with.x) - (x * with.z),
+ (x * with.y) - (y * with.x)
);
}
@@ -212,46 +212,46 @@ namespace Godot
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
+ /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
- public Vector3 DirectionTo(Vector3 b)
+ /// <param name="to">The other vector to point towards.</param>
+ /// <returns>The direction from this vector to <paramref name="to"/>.</returns>
+ public Vector3 DirectionTo(Vector3 to)
{
- return new Vector3(b.x - x, b.y - y, b.z - z).Normalized();
+ return new Vector3(to.x - x, to.y - y, to.z - z).Normalized();
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public real_t DistanceSquaredTo(Vector3 b)
+ public real_t DistanceSquaredTo(Vector3 to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
/// <seealso cref="DistanceSquaredTo(Vector3)"/>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector3 b)
+ public real_t DistanceTo(Vector3 to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public real_t Dot(Vector3 b)
+ public real_t Dot(Vector3 with)
{
- return (x * b.x) + (y * b.y) + (z * b.z);
+ return (x * with.x) + (y * with.y) + (z * with.z);
}
/// <summary>
@@ -364,21 +364,21 @@ namespace Godot
}
/// <summary>
- /// Returns the axis of the vector's largest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
/// If all components are equal, this method returns <see cref="Axis.X"/>.
/// </summary>
- /// <returns>The index of the largest axis.</returns>
- public Axis MaxAxis()
+ /// <returns>The index of the highest axis.</returns>
+ public Axis MaxAxisIndex()
{
return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X);
}
/// <summary>
- /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
/// If all components are equal, this method returns <see cref="Axis.Z"/>.
/// </summary>
- /// <returns>The index of the smallest axis.</returns>
- public Axis MinAxis()
+ /// <returns>The index of the lowest axis.</returns>
+ public Axis MinAxisIndex()
{
return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z);
}
@@ -412,16 +412,16 @@ namespace Godot
}
/// <summary>
- /// Returns the outer product with <paramref name="b"/>.
+ /// Returns the outer product with <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>A <see cref="Basis"/> representing the outer product matrix.</returns>
- public Basis Outer(Vector3 b)
+ public Basis Outer(Vector3 with)
{
return new Basis(
- x * b.x, x * b.y, x * b.z,
- y * b.x, y * b.y, y * b.z,
- z * b.x, z * b.y, z * b.z
+ x * with.x, x * with.y, x * with.z,
+ y * with.x, y * with.y, y * with.z,
+ z * with.x, z * with.y, z * with.z
);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index 474876fc91..eb06d2b87e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -17,7 +17,7 @@ namespace Godot
{
/// <summary>
/// Enumerated index values for the axes.
- /// Returned by <see cref="MaxAxis"/> and <see cref="MinAxis"/>.
+ /// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
/// </summary>
public enum Axis
{
@@ -124,36 +124,36 @@ namespace Godot
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public int DistanceSquaredTo(Vector3i b)
+ public int DistanceSquaredTo(Vector3i to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
/// <seealso cref="DistanceSquaredTo(Vector3i)"/>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector3i b)
+ public real_t DistanceTo(Vector3i to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public int Dot(Vector3i b)
+ public int Dot(Vector3i with)
{
- return x * b.x + y * b.y + z * b.z;
+ return x * with.x + y * with.y + z * with.z;
}
/// <summary>
@@ -186,21 +186,21 @@ namespace Godot
}
/// <summary>
- /// Returns the axis of the vector's largest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
/// If all components are equal, this method returns <see cref="Axis.X"/>.
/// </summary>
- /// <returns>The index of the largest axis.</returns>
- public Axis MaxAxis()
+ /// <returns>The index of the highest axis.</returns>
+ public Axis MaxAxisIndex()
{
return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X);
}
/// <summary>
- /// Returns the axis of the vector's smallest value. See <see cref="Axis"/>.
+ /// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
/// If all components are equal, this method returns <see cref="Axis.Z"/>.
/// </summary>
- /// <returns>The index of the smallest axis.</returns>
- public Axis MinAxis()
+ /// <returns>The index of the lowest axis.</returns>
+ public Axis MinAxisIndex()
{
return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z);
}
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 24bd1ed492..2b4cc7fcc3 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -229,9 +229,6 @@ private:
#endif
}
- _GodotSharpDirs(const _GodotSharpDirs &);
- _GodotSharpDirs &operator=(const _GodotSharpDirs &);
-
public:
static _GodotSharpDirs &get_singleton() {
static _GodotSharpDirs singleton;
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index d0e51d159f..a18a4ce646 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -56,13 +56,12 @@ struct MonoGCHandleData {
void release();
- MonoGCHandleData &operator=(const MonoGCHandleData &p_other) {
+ void operator=(const MonoGCHandleData &p_other) {
#ifdef DEBUG_ENABLED
CRASH_COND(!is_released());
#endif
handle = p_other.handle;
type = p_other.type;
- return *this;
}
MonoGCHandleData(const MonoGCHandleData &) = default;
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index 2bf55493e0..60277e0652 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -177,6 +177,8 @@ void CachedData::clear_godot_api_cache() {
methodthunk_MarshalUtils_TypeIsGenericICollection.nullify();
methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify();
+ methodthunk_MarshalUtils_GetGenericTypeDefinition.nullify();
+
methodthunk_MarshalUtils_ArrayGetElementType.nullify();
methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify();
@@ -299,6 +301,8 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GetGenericTypeDefinition, GODOT_API_CLASS(MarshalUtils)->get_method("GetGenericTypeDefinition", 2));
+
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3));
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 4b4688b4d9..5101907bd6 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -148,6 +148,8 @@ struct CachedData {
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection;
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary;
+ GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GetGenericTypeDefinition;
+
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes;
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 4f4480fa49..520568071e 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -464,9 +464,18 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
return delegates_list;
}
+ // If the class is generic we must use the generic type definition.
+ MonoClass *klass = mono_class;
+ if (mono_type_get_type(get_mono_type()) == MONO_TYPE_GENERICINST) {
+ MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), get_mono_type());
+ GDMonoUtils::Marshal::get_generic_type_definition(reftype, &reftype);
+ MonoType *type = mono_reflection_type_get_type(reftype);
+ klass = mono_class_from_mono_type(type);
+ }
+
void *iter = nullptr;
MonoClass *raw_class = nullptr;
- while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) {
+ while ((raw_class = mono_class_get_nested_types(klass, &iter)) != nullptr) {
if (mono_class_is_delegate(raw_class)) {
StringName name = String::utf8(mono_class_get_name(raw_class));
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 179bbfb40c..bcdcd6623b 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -121,12 +121,10 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
ERR_FAIL_COND(da->list_dir_begin() != OK);
- String current;
- while ((current = da->get_next()).length()) {
- if (da->current_is_dir()) {
- continue;
- }
- if (!current.ends_with(".txt")) {
+ String current = da->get_next();
+ while (!current.is_empty()) {
+ if (da->current_is_dir() || !current.ends_with(".txt")) {
+ current = da->get_next();
continue;
}
@@ -135,6 +133,7 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
if (OS::get_singleton()->get_unix_time() - modified_time > MAX_SECS) {
da->remove(current);
}
+ current = da->get_next();
}
da->list_dir_end();
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 09aa9ad948..505c637af9 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -614,6 +614,12 @@ bool type_is_generic_idictionary(MonoReflectionType *p_reftype) {
return (bool)res;
}
+void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype) {
+ MonoException *exc = nullptr;
+ CACHED_METHOD_THUNK(MarshalUtils, GetGenericTypeDefinition).invoke(p_reftype, r_generic_reftype, &exc);
+ UNHANDLED_EXCEPTION(exc);
+}
+
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
MonoException *exc = nullptr;
CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 773501e93d..3162ef198d 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -62,6 +62,8 @@ bool type_is_generic_ienumerable(MonoReflectionType *p_reftype);
bool type_is_generic_icollection(MonoReflectionType *p_reftype);
bool type_is_generic_idictionary(MonoReflectionType *p_reftype);
+void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype);
+
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype);
void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 05e040b518..0bce0fc9f0 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -36,6 +36,7 @@
#include "core/os/thread.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/capsule_shape_3d.h"
@@ -63,17 +64,17 @@
NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr;
-void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
- p_verticies.push_back(p_vec3.x);
- p_verticies.push_back(p_vec3.y);
- p_verticies.push_back(p_vec3.z);
+void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices) {
+ p_vertices.push_back(p_vec3.x);
+ p_vertices.push_back(p_vec3.y);
+ p_vertices.push_back(p_vec3.z);
}
-void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int current_vertex_count;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
- current_vertex_count = p_verticies.size() / 3;
+ current_vertex_count = p_vertices.size() / 3;
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
@@ -100,7 +101,7 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
const int *ir = mesh_indices.ptr();
for (int j = 0; j < mesh_vertices.size(); j++) {
- _add_vertex(p_xform.xform(vr[j]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j]), p_vertices);
}
for (int j = 0; j < face_count; j++) {
@@ -112,9 +113,9 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
} else {
face_count = mesh_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 1));
@@ -124,14 +125,14 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
}
}
-void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int face_count = p_faces.size() / 3;
- int current_vertex_count = p_verticies.size() / 3;
+ int current_vertex_count = p_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_verticies);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 2));
@@ -139,12 +140,27 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons
}
}
-void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_vertices, p_indices);
+ }
+ }
+
+ if (Object::cast_to<MultiMeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ MultiMeshInstance3D *multimesh_instance = Object::cast_to<MultiMeshInstance3D>(p_node);
+ Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh();
+ Ref<Mesh> mesh = multimesh->get_mesh();
+ if (mesh.is_valid()) {
+ int n = multimesh->get_visible_instance_count();
+ if (n == -1) {
+ n = multimesh->get_instance_count();
+ }
+ for (int i = 0; i < n; i++) {
+ _add_mesh(mesh, p_accumulated_transform * multimesh->get_instance_transform(i), p_vertices, p_indices);
+ }
}
}
@@ -155,7 +171,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (!meshes.is_empty()) {
Ref<Mesh> mesh = meshes[1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_vertices, p_indices);
}
}
}
@@ -213,7 +229,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
ConcavePolygonShape3D *concave_polygon = Object::cast_to<ConcavePolygonShape3D>(*s);
if (concave_polygon) {
- _add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices);
+ _add_faces(concave_polygon->get_faces(), transform, p_vertices, p_indices);
}
ConvexPolygonShape3D *convex_polygon = Object::cast_to<ConvexPolygonShape3D>(*s);
@@ -236,12 +252,12 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
}
}
- _add_faces(faces, transform, p_verticies, p_indices);
+ _add_faces(faces, transform, p_vertices, p_indices);
}
}
if (mesh.is_valid()) {
- _add_mesh(mesh, transform, p_verticies, p_indices);
+ _add_mesh(mesh, transform, p_vertices, p_indices);
}
}
}
@@ -256,7 +272,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
}
}
}
@@ -269,7 +285,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (p_recurse_children) {
for (int i = 0; i < p_node->get_child_count(); i++) {
- _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
+ _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
}
}
}
diff --git a/modules/navigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h
index 78f1329e3f..dac844c68e 100644
--- a/modules/navigation/navigation_mesh_generator.h
+++ b/modules/navigation/navigation_mesh_generator.h
@@ -49,10 +49,10 @@ class NavigationMeshGenerator : public Object {
protected:
static void _bind_methods();
- static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
- static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
+ static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices);
+ static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
static void _build_recast_navigation_mesh(
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index f480c86088..e2908a8a66 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -3144,7 +3144,7 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te
return true;
}
-bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3174,7 +3174,7 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con
return true;
}
-bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3242,56 +3242,56 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
@@ -3433,56 +3433,56 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) {
if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -new_sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = new_sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -new_sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = new_sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
@@ -4263,7 +4263,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
}
hb_buffer_set_script(p_sd->hb_buffer, p_script);
- if (p_sd->spans[p_span].language != String()) {
+ if (!p_sd->spans[p_span].language.is_empty()) {
hb_language_t lang = hb_language_from_string(p_sd->spans[p_span].language.ascii().get_data(), -1);
hb_buffer_set_language(p_sd->hb_buffer, lang);
}
@@ -4579,56 +4579,56 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
@@ -4971,12 +4971,12 @@ void TextServerAdvanced::_insert_num_systems_lang() {
}
String TextServerAdvanced::format_number(const String &p_string, const String &p_language) const {
- const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
for (int i = 0; i < num_systems.size(); i++) {
if (num_systems[i].lang.has(lang)) {
- if (num_systems[i].digits == String()) {
+ if (num_systems[i].digits.is_empty()) {
return p_string;
}
res.replace("e", num_systems[i].exp);
@@ -4996,12 +4996,12 @@ String TextServerAdvanced::format_number(const String &p_string, const String &p
}
String TextServerAdvanced::parse_number(const String &p_string, const String &p_language) const {
- const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
for (int i = 0; i < num_systems.size(); i++) {
if (num_systems[i].lang.has(lang)) {
- if (num_systems[i].digits == String()) {
+ if (num_systems[i].digits.is_empty()) {
return p_string;
}
res.replace(num_systems[i].exp, "e");
@@ -5024,11 +5024,11 @@ String TextServerAdvanced::parse_number(const String &p_string, const String &p_
}
String TextServerAdvanced::percent_sign(const String &p_language) const {
- const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
for (int i = 0; i < num_systems.size(); i++) {
if (num_systems[i].lang.has(lang)) {
- if (num_systems[i].percent_sign == String()) {
+ if (num_systems[i].percent_sign.is_empty()) {
return "%";
}
return num_systems[i].percent_sign;
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 5eaff67a6e..414db8c7ea 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -476,8 +476,8 @@ public:
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 5c06051211..97a53143cf 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -2247,7 +2247,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
return true;
}
-bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2278,7 +2278,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con
return true;
}
-bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2346,56 +2346,56 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
@@ -2498,56 +2498,56 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) {
if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -new_sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = new_sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -new_sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = new_sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
@@ -3052,56 +3052,56 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.y = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.y = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.y = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.y -= E.value.rect.size.y;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.y -= E.value.rect.size.y / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
full_ascent = MAX(full_ascent, -E.value.rect.position.y);
full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
} else {
- switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
- case INLINE_ALIGN_TO_TOP: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
E.value.rect.position.x = -sd->ascent;
} break;
- case INLINE_ALIGN_TO_CENTER: {
+ case INLINE_ALIGNMENT_TO_CENTER: {
E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
} break;
- case INLINE_ALIGN_TO_BASELINE: {
+ case INLINE_ALIGNMENT_TO_BASELINE: {
E.value.rect.position.x = 0;
} break;
- case INLINE_ALIGN_TO_BOTTOM: {
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
E.value.rect.position.x = sd->descent;
} break;
}
- switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) {
- case INLINE_ALIGN_BOTTOM_TO: {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
E.value.rect.position.x -= E.value.rect.size.x;
} break;
- case INLINE_ALIGN_CENTER_TO: {
+ case INLINE_ALIGNMENT_CENTER_TO: {
E.value.rect.position.x -= E.value.rect.size.x / 2;
} break;
- case INLINE_ALIGN_TOP_TO: {
+ case INLINE_ALIGNMENT_TOP_TO: {
// NOP
} break;
}
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index 67b08d1eac..f2b33c2afb 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -387,8 +387,8 @@ public:
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp
index 13dd1f7bc7..9deea79ea6 100644
--- a/modules/visual_script/editor/visual_script_editor.cpp
+++ b/modules/visual_script/editor/visual_script_editor.cpp
@@ -779,7 +779,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
for (int i = 0; i < node->get_output_sequence_port_count(); i++) {
Label *text2 = memnew(Label);
text2->set_text(node->get_output_sequence_port_text(i));
- text2->set_align(Label::ALIGN_RIGHT);
+ text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
gnode->add_child(text2);
gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
slot_idx++;
@@ -900,7 +900,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (i < mixed_seq_ports) {
Label *text2 = memnew(Label);
text2->set_text(node->get_output_sequence_port_text(i));
- text2->set_align(Label::ALIGN_RIGHT);
+ text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
hbc->add_child(text2);
}
@@ -1328,7 +1328,7 @@ void VisualScriptEditor::_create_function_dialog() {
}
void VisualScriptEditor::_create_function() {
- String name = _validate_name((func_name_box->get_text() == "") ? "new_func" : func_name_box->get_text());
+ String name = _validate_name((func_name_box->get_text().is_empty()) ? "new_func" : func_name_box->get_text());
selected = name;
Vector2 pos = _get_available_pos();
@@ -1506,7 +1506,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
} else if (ti->get_parent() == root->get_first_child()) {
selected = ti->get_text(0);
- function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10));
+ function_name_edit->set_position(get_screen_position() + get_local_mouse_position() - Vector2(60, -10));
function_name_edit->popup();
function_name_box->set_text(selected);
function_name_box->select_all();
@@ -1974,7 +1974,7 @@ void VisualScriptEditor::input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> key = p_event;
if (key.is_valid() && !key->is_pressed()) {
- mouse_up_position = Input::get_singleton()->get_mouse_position();
+ mouse_up_position = get_screen_position() + get_local_mouse_position();
}
}
@@ -1984,7 +1984,7 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MouseButton::RIGHT) {
saved_position = graph->get_local_mouse_position();
- Point2 gpos = Input::get_singleton()->get_mouse_position();
+ Point2 gpos = get_screen_position() + get_local_mouse_position();
_generic_search(script->get_instance_base_type(), gpos);
}
}
@@ -2094,7 +2094,7 @@ Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
String type = it->get_metadata(0);
- if (type == String()) {
+ if (type.is_empty()) {
return Variant();
}
@@ -2622,7 +2622,7 @@ String VisualScriptEditor::get_name() {
name = TTR("[unsaved]");
} else if (script->is_built_in()) {
const String &script_name = script->get_name();
- if (script_name != "") {
+ if (!script_name.is_empty()) {
// If the built-in script has a custom resource name defined,
// display the built-in script name as follows: `ResourceName (scene_file.tscn)`
name = vformat("%s (%s)", script_name, name.get_slice("::", 0));
@@ -2842,7 +2842,7 @@ void VisualScriptEditor::clear_edit_menu() {
void VisualScriptEditor::_change_base_type_callback() {
String bt = select_base_type->get_selected_type();
- ERR_FAIL_COND(bt == String());
+ ERR_FAIL_COND(bt.is_empty());
undo_redo->create_action(TTR("Change Base Type"));
undo_redo->add_do_method(script.ptr(), "set_instance_base_type", bt);
undo_redo->add_undo_method(script.ptr(), "set_instance_base_type", script->get_instance_base_type());
@@ -3213,7 +3213,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
if (tg.type == Variant::OBJECT) {
if (tg.script.is_valid()) {
new_connect_node_select->select_from_script(tg.script, "");
- } else if (type_string != String()) {
+ } else if (!type_string.is_empty()) {
new_connect_node_select->select_from_base_type(type_string);
} else {
new_connect_node_select->select_from_base_type(n->get_base_type());
@@ -3237,7 +3237,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
property_info = script->get_node(port_action_node)->get_output_value_port_info(port_action_output);
}
if (tg.type == Variant::OBJECT) {
- if (property_info.type == Variant::OBJECT && property_info.hint_string != String()) {
+ if (property_info.type == Variant::OBJECT && !property_info.hint_string.is_empty()) {
new_connect_node_select->select_from_action(property_info.hint_string);
} else {
new_connect_node_select->select_from_action("");
@@ -3462,7 +3462,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) {
vsfc->set_base_type(base_type);
}
if (p_text == "call" || p_text == "call_deferred") {
@@ -3497,7 +3497,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) {
vsp->set_base_type(base_type);
}
}
@@ -3526,7 +3526,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
} else if (script->get_node(port_action_node).is_valid()) {
PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
- if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) {
vsp->set_base_type(base_type);
}
}
@@ -3704,7 +3704,7 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
Variant::construct(pinfo.type, existing, &existingp, 1, ce);
}
- default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_global_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y));
+ default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_screen_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y));
default_value_edit->reset_size();
if (pinfo.type == Variant::NODE_PATH) {
@@ -4160,10 +4160,10 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
ERR_FAIL_COND(!ti);
member_popup->clear();
- member_popup->set_position(members->get_global_position() + p_pos);
+ member_popup->set_position(members->get_screen_position() + p_pos);
member_popup->reset_size();
- function_name_edit->set_position(members->get_global_position() + p_pos);
+ function_name_edit->set_position(members->get_screen_position() + p_pos);
function_name_edit->reset_size();
TreeItem *root = members->get_root();
@@ -4476,8 +4476,8 @@ VisualScriptEditor::VisualScriptEditor() {
select_func_text = memnew(Label);
select_func_text->set_text(TTR("Select or create a function to edit its graph."));
- select_func_text->set_align(Label::ALIGN_CENTER);
- select_func_text->set_valign(Label::VALIGN_CENTER);
+ select_func_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ select_func_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
select_func_text->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(select_func_text);
@@ -4485,8 +4485,8 @@ VisualScriptEditor::VisualScriptEditor() {
hint_text->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -100);
hint_text->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0);
hint_text->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0);
- hint_text->set_align(Label::ALIGN_CENTER);
- hint_text->set_valign(Label::VALIGN_CENTER);
+ hint_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ hint_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
graph->add_child(hint_text);
hint_text_timer = memnew(Timer);
diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp
index 02307b712c..9fa35d4453 100644
--- a/modules/visual_script/editor/visual_script_property_selector.cpp
+++ b/modules/visual_script/editor/visual_script_property_selector.cpp
@@ -175,7 +175,7 @@ void VisualScriptPropertySelector::_update_search() {
String set_text = set_text_raw.capitalize();
String input = search_box->get_text().capitalize();
- if (input == String() || get_text_raw.findn(input) != -1 || get_text.findn(input) != -1) {
+ if (input.is_empty() || get_text_raw.findn(input) != -1 || get_text.findn(input) != -1) {
TreeItem *item = search_options->create_item(category ? category : root);
item->set_text(0, get_text);
item->set_metadata(0, F.name);
@@ -188,7 +188,7 @@ void VisualScriptPropertySelector::_update_search() {
item->set_metadata(2, connecting);
}
- if (input == String() || set_text_raw.findn(input) != -1 || set_text.findn(input) != -1) {
+ if (input.is_empty() || set_text_raw.findn(input) != -1 || set_text.findn(input) != -1) {
TreeItem *item = search_options->create_item(category ? category : root);
item->set_text(0, set_text);
item->set_metadata(0, F.name);
@@ -252,7 +252,7 @@ void VisualScriptPropertySelector::_update_search() {
String desc_raw = mi.name + desc_arguments;
String desc = desc_raw.capitalize().replace("( ", "(");
- if (search_box->get_text() != String() &&
+ if (!search_box->get_text().is_empty() &&
name.findn(search_box->get_text()) == -1 &&
desc.findn(search_box->get_text()) == -1 &&
desc_raw.findn(search_box->get_text()) == -1) {
@@ -322,7 +322,7 @@ void VisualScriptPropertySelector::_update_search() {
}
void VisualScriptPropertySelector::create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text) {
- if (search_input == String() || text.findn(search_input) != -1) {
+ if (search_input.is_empty() || text.findn(search_input) != -1) {
TreeItem *item = search_options->create_item(root);
item->set_text(0, text);
item->set_icon(0, vbc->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")));
@@ -352,7 +352,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
bool in_filter = false;
Vector<String> tx_filters = search_box->get_text().split(" ");
for (int i = 0; i < tx_filters.size(); i++) {
- if (tx_filters[i] == "") {
+ if (tx_filters[i].is_empty()) {
in_filter = true;
} else {
in_filter = false;
@@ -451,7 +451,7 @@ void VisualScriptPropertySelector::_item_selected() {
String at_class = class_type;
- while (at_class != String()) {
+ while (!at_class.is_empty()) {
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
if (E) {
for (int i = 0; i < E->get().properties.size(); i++) {
@@ -465,7 +465,7 @@ void VisualScriptPropertySelector::_item_selected() {
}
at_class = class_type;
- while (at_class != String()) {
+ while (!at_class.is_empty()) {
Map<String, DocData::ClassDoc>::Element *C = dd->class_list.find(at_class);
if (C) {
for (int i = 0; i < C->get().methods.size(); i++) {
@@ -521,7 +521,7 @@ void VisualScriptPropertySelector::_item_selected() {
memdelete(names);
- if (text == String()) {
+ if (text.is_empty()) {
return;
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 34d8c0b1e6..63bd9bbee4 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1665,8 +1665,8 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
String err_func = p_method;
int err_line = current_node_id; // Not a line but it works as one.
- if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) {
- if (error_str != String()) {
+ if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str.is_empty())) {
+ if (!error_str.is_empty()) {
error_str += " ";
}
@@ -2379,7 +2379,7 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String
for (int i = 0; i < node->input_port_count; i++) {
String name = node->get_base_node()->get_input_value_port_info(i).name;
- if (name == String()) {
+ if (name.is_empty()) {
name = "in_" + itos(i);
}
@@ -2399,7 +2399,7 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String
for (int i = 0; i < node->output_port_count; i++) {
String name = node->get_base_node()->get_output_value_port_info(i).name;
- if (name == String()) {
+ if (name.is_empty()) {
name = "out_" + itos(i);
}
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 62a4f465cb..278d806595 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -724,7 +724,7 @@ String VisualScriptTypeCast::get_caption() const {
}
String VisualScriptTypeCast::get_text() const {
- if (script != String()) {
+ if (!script.is_empty()) {
return "Is " + script.get_file() + "?";
} else {
return "Is " + base_type + "?";
@@ -762,7 +762,7 @@ String VisualScriptTypeCast::get_base_script() const {
VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const {
TypeGuess tg;
tg.type = Variant::OBJECT;
- if (script != String()) {
+ if (!script.is_empty()) {
tg.script = ResourceLoader::load(script);
}
//if (!tg.script.is_valid()) {
@@ -793,7 +793,7 @@ public:
return 0;
}
- if (script != String()) {
+ if (!script.is_empty()) {
Ref<Script> obj_script = obj->get_script();
if (!obj_script.is_valid()) {
return 1; //well, definitely not the script because object we got has no script.
@@ -853,7 +853,7 @@ void VisualScriptTypeCast::_bind_methods() {
String script_ext_hint;
for (const String &E : script_extensions) {
- if (script_ext_hint != String()) {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "*." + E;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index a2ad38bf01..651464dfdb 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -370,7 +370,7 @@ void VisualScriptFunctionCall::_update_method_cache() {
} else if (call_mode == CALL_MODE_INSTANCE) {
type = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -539,7 +539,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
property.hint = PROPERTY_HINT_ENUM;
String sl;
for (const Engine::Singleton &E : names) {
- if (sl != String()) {
+ if (!sl.is_empty()) {
sl += ",";
}
sl += E.name;
@@ -580,7 +580,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE;
property.hint_string = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -684,7 +684,7 @@ void VisualScriptFunctionCall::_bind_methods() {
String script_ext_hint;
for (const String &E : script_extensions) {
- if (script_ext_hint != String()) {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "*." + E;
@@ -1161,7 +1161,7 @@ void VisualScriptPropertySet::_update_cache() {
}
} else if (call_mode == CALL_MODE_INSTANCE) {
type = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -1321,7 +1321,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
property.hint_string = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -1361,7 +1361,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = options;
property.type = Variant::STRING;
- if (options == "") {
+ if (options.is_empty()) {
property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index
}
}
@@ -1411,7 +1411,7 @@ void VisualScriptPropertySet::_bind_methods() {
String script_ext_hint;
for (const String &E : script_extensions) {
- if (script_ext_hint != String()) {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "*." + E;
@@ -1847,7 +1847,7 @@ void VisualScriptPropertyGet::_update_cache() {
}
} else if (call_mode == CALL_MODE_INSTANCE) {
type = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -2027,7 +2027,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
property.hint_string = base_type;
- if (base_script != String()) {
+ if (!base_script.is_empty()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
@@ -2066,7 +2066,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = options;
property.type = Variant::STRING;
- if (options == "") {
+ if (options.is_empty()) {
property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index
}
}
@@ -2113,7 +2113,7 @@ void VisualScriptPropertyGet::_bind_methods() {
String script_ext_hint;
for (const String &E : script_extensions) {
- if (script_ext_hint != String()) {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "." + E;
@@ -2324,7 +2324,7 @@ void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const {
String ml;
for (const StringName &E : sigs) {
- if (ml != String()) {
+ if (!ml.is_empty()) {
ml += ",";
}
ml += E;
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index b0af030981..bb4c83bd24 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -1307,7 +1307,7 @@ void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const {
String vhint;
for (const StringName &E : vars) {
- if (vhint != String()) {
+ if (!vhint.is_empty()) {
vhint += ",";
}
@@ -1417,7 +1417,7 @@ void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const {
String vhint;
for (const StringName &E : vars) {
- if (vhint != String()) {
+ if (!vhint.is_empty()) {
vhint += ",";
}
@@ -1615,7 +1615,7 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const {
pinfo.hint_string = preload->get_class();
if (preload->get_path().is_resource_file()) {
pinfo.name = preload->get_path();
- } else if (preload->get_name() != String()) {
+ } else if (!preload->get_name().is_empty()) {
pinfo.name = preload->get_name();
} else {
pinfo.name = preload->get_class();
@@ -1994,7 +1994,7 @@ void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const
property.hint_string = "";
for (const String &E : constants) {
- if (property.hint_string != String()) {
+ if (!property.hint_string.is_empty()) {
property.hint_string += ",";
}
property.hint_string += E;
@@ -2132,7 +2132,7 @@ void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) c
}
property.hint_string = "";
for (const StringName &E : constants) {
- if (property.hint_string != String()) {
+ if (!property.hint_string.is_empty()) {
property.hint_string += ",";
}
property.hint_string += String(E);
@@ -2363,7 +2363,7 @@ void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) con
continue; //skip these, too simple named
}
- if (cc != String()) {
+ if (!cc.is_empty()) {
cc += ",";
}
cc += E.name;
@@ -3147,7 +3147,7 @@ String VisualScriptSubCall::get_caption() const {
String VisualScriptSubCall::get_text() const {
Ref<Script> script = get_script();
if (script.is_valid()) {
- if (script->get_name() != String()) {
+ if (!script->get_name().is_empty()) {
return script->get_name();
}
if (script->get_path().is_resource_file()) {
@@ -3786,7 +3786,7 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
al.sort();
for (int i = 0; i < al.size(); i++) {
- if (actions != String()) {
+ if (!actions.is_empty()) {
actions += ",";
}
actions += al[i];
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index 4b89c9ccd0..c5d17e5a11 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -449,7 +449,7 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
String ml;
for (const String &E : mstring) {
- if (ml != String()) {
+ if (!ml.is_empty()) {
ml += ",";
}
ml += E;
diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp
index d248433d82..78a5fa50d8 100644
--- a/modules/websocket/editor_debugger_server_websocket.cpp
+++ b/modules/websocket/editor_debugger_server_websocket.cpp
@@ -31,6 +31,8 @@
#include "editor_debugger_server_websocket.h"
#include "core/config/project_settings.h"
+#include "editor/editor_log.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "modules/websocket/remote_debugger_peer_websocket.h"
@@ -48,19 +50,47 @@ void EditorDebuggerServerWebSocket::poll() {
server->poll();
}
+String EditorDebuggerServerWebSocket::get_uri() const {
+ return endpoint;
+}
+
Error EditorDebuggerServerWebSocket::start(const String &p_uri) {
+ // Default host and port
+ String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host");
int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
- String bind_host = EditorSettings::get_singleton()->get("network/debug/remote_host");
+
+ // Optionally override
if (!p_uri.is_empty() && p_uri != "ws://") {
String scheme, path;
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
}
+
+ // Set up the server
server->set_bind_ip(bind_host);
Vector<String> compatible_protocols;
compatible_protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer.
- return server->listen(bind_port, compatible_protocols);
+
+ // Try listening on ports
+ const int max_attempts = 5;
+ for (int attempt = 1;; ++attempt) {
+ const Error err = server->listen(bind_port, compatible_protocols);
+ if (err == OK) {
+ break;
+ }
+ if (attempt >= max_attempts) {
+ EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR);
+ return err;
+ }
+ int last_port = bind_port++;
+ EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING);
+ }
+
+ // Endpoint that the client should connect to
+ endpoint = vformat("ws://%s:%d", bind_host, bind_port);
+
+ return OK;
}
void EditorDebuggerServerWebSocket::stop() {
diff --git a/modules/websocket/editor_debugger_server_websocket.h b/modules/websocket/editor_debugger_server_websocket.h
index 14ab0109b2..1e5ea66146 100644
--- a/modules/websocket/editor_debugger_server_websocket.h
+++ b/modules/websocket/editor_debugger_server_websocket.h
@@ -40,6 +40,7 @@ class EditorDebuggerServerWebSocket : public EditorDebuggerServer {
private:
Ref<WebSocketServer> server;
List<int> pending_peers;
+ String endpoint;
public:
static EditorDebuggerServer *create(const String &p_protocol);
@@ -47,12 +48,13 @@ public:
void _peer_connected(int p_peer, String p_protocol);
void _peer_disconnected(int p_peer, bool p_was_clean);
- void poll() override;
- Error start(const String &p_uri) override;
- void stop() override;
- bool is_active() const override;
- bool is_connection_available() const override;
- Ref<RemoteDebuggerPeer> take_connection() override;
+ virtual void poll() override;
+ virtual String get_uri() const override;
+ virtual Error start(const String &p_uri = "") override;
+ virtual void stop() override;
+ virtual bool is_active() const override;
+ virtual bool is_connection_available() const override;
+ virtual Ref<RemoteDebuggerPeer> take_connection() override;
EditorDebuggerServerWebSocket();
~EditorDebuggerServerWebSocket();
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 514b2d055f..a3d0d3554f 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -83,11 +83,11 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols, St
break;
}
// Found a protocol
- if (protocol != "") {
+ if (!protocol.is_empty()) {
break;
}
}
- if (protocol == "") { // Invalid protocol(s) requested
+ if (protocol.is_empty()) { // Invalid protocol(s) requested
return false;
}
} else if (p_protocols.size() > 0) { // No protocol requested, but we need one
@@ -138,7 +138,7 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uin
s += "Upgrade: websocket\r\n";
s += "Connection: Upgrade\r\n";
s += "Sec-WebSocket-Accept: " + WSLPeer::compute_key_response(key) + "\r\n";
- if (protocol != "") {
+ if (!protocol.is_empty()) {
s += "Sec-WebSocket-Protocol: " + protocol + "\r\n";
}
s += "\r\n";
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 0eeee8215d..d2726b8652 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -102,7 +102,7 @@ String DirAccessJAndroid::get_drive(int p_drive) {
Error DirAccessJAndroid::change_dir(String p_dir) {
JNIEnv *env = get_jni_env();
- if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == ""))
+ if (p_dir.is_empty() || p_dir == "." || (p_dir == ".." && current_dir.is_empty()))
return OK;
String new_dir;
@@ -114,7 +114,7 @@ Error DirAccessJAndroid::change_dir(String p_dir) {
new_dir = p_dir.substr(1, p_dir.length());
else if (p_dir.begins_with("res://"))
new_dir = p_dir.substr(6, p_dir.length());
- else if (current_dir == "")
+ else if (current_dir.is_empty())
new_dir = p_dir;
else
new_dir = current_dir.plus_file(p_dir);
@@ -141,7 +141,7 @@ String DirAccessJAndroid::get_current_dir(bool p_include_drive) {
bool DirAccessJAndroid::file_exists(String p_file) {
String sd;
- if (current_dir == "")
+ if (current_dir.is_empty())
sd = p_file;
else
sd = current_dir.plus_file(p_file);
@@ -158,7 +158,7 @@ bool DirAccessJAndroid::dir_exists(String p_dir) {
String sd;
- if (current_dir == "")
+ if (current_dir.is_empty())
sd = p_dir;
else {
if (p_dir.is_relative_path())
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index c5d3cbd966..70b36f2350 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -224,6 +224,10 @@ static const int EXPORT_FORMAT_AAB = 1;
static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
+static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
+static const int DEFAULT_TARGET_SDK_VERSION = 30; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
+const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION);
+
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
@@ -303,7 +307,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
}
- if (d.description == "") {
+ if (d.description.is_empty()) {
//in the oven, request!
args.clear();
args.push_back("-s");
@@ -352,7 +356,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
d.name = vendor + " " + device;
- if (device == String()) {
+ if (device.is_empty()) {
continue;
}
}
@@ -390,13 +394,13 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
String EditorExportPlatformAndroid::get_project_name(const String &p_name) const {
String aname;
- if (p_name != "") {
+ if (!p_name.is_empty()) {
aname = p_name;
} else {
aname = ProjectSettings::get_singleton()->get("application/config/name");
}
- if (aname == "") {
+ if (aname.is_empty()) {
aname = VERSION_NAME;
}
@@ -420,7 +424,7 @@ String EditorExportPlatformAndroid::get_package_name(const String &p_package) co
first = false;
}
}
- if (name == "") {
+ if (name.is_empty()) {
name = "noname";
}
@@ -577,7 +581,7 @@ Vector<String> EditorExportPlatformAndroid::list_gdap_files(const String &p_path
da->list_dir_begin();
while (true) {
String file = da->get_next();
- if (file == "") {
+ if (file.is_empty()) {
break;
}
@@ -832,10 +836,13 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
int xr_mode_index = p_preset->get("xr_features/xr_mode");
+ int hand_tracking_index = p_preset->get("xr_features/hand_tracking");
+ int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency");
bool backup_allowed = p_preset->get("user_data_backup/allow");
bool classify_as_game = p_preset->get("package/classify_as_game");
bool retain_data_on_uninstall = p_preset->get("package/retain_data_on_uninstall");
+ bool exclude_from_recents = p_preset->get("package/exclude_from_recents");
Vector<String> perms;
// Write permissions into the perms variable.
@@ -949,6 +956,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
encode_uint32(screen_orientation, &p_manifest.write[iofs + 16]);
}
+ if (tname == "activity" && attrname == "excludeFromRecents") {
+ encode_uint32(exclude_from_recents, &p_manifest.write[iofs + 16]);
+ }
+
if (tname == "supports-screens") {
if (attrname == "smallScreens") {
encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
@@ -978,6 +989,18 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
}
}
+ if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") {
+ if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) {
+ string_table.write[attr_value] = "com.oculus.handtracking.frequency";
+ }
+ }
+
+ if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") {
+ if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) {
+ string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH");
+ }
+ }
+
iofs += 20;
}
@@ -999,7 +1022,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
feature_versions.push_back(1);
// Check for hand tracking
- int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
feature_names.push_back("oculus.software.handtracking");
feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED);
@@ -1679,11 +1701,15 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/min_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_MIN_SDK_VERSION));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/target_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_TARGET_SDK_VERSION));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/classify_as_game"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/retain_data_on_uninstall"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/exclude_from_recents"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
@@ -1691,9 +1717,10 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), XR_MODE_REGULAR));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_HAND_TRACKING_NONE));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking_frequency", PROPERTY_HINT_ENUM, "Low,High"), XR_HAND_TRACKING_FREQUENCY_LOW));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_PASSTHROUGH_NONE));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
@@ -2002,10 +2029,11 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
+ const bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
// Look for export templates (first official, and if defined custom templates).
- if (!bool(p_preset->get("custom_template/use_custom_build"))) {
+ if (!custom_build_enabled) {
String template_err;
bool dvalid = false;
bool rvalid = false;
@@ -2080,7 +2108,7 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
}
String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
- if (sdk_path == "") {
+ if (sdk_path.is_empty()) {
err += TTR("A valid Android SDK path is required in Editor Settings.") + "\n";
valid = false;
} else {
@@ -2127,7 +2155,7 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
if (apk_expansion) {
String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
- if (apk_expansion_pkey == "") {
+ if (apk_expansion_pkey.is_empty()) {
valid = false;
err += TTR("Invalid public key for APK expansion.") + "\n";
@@ -2143,14 +2171,13 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
}
String etc_error = test_etc2();
- if (etc_error != String()) {
+ if (!etc_error.is_empty()) {
valid = false;
err += etc_error;
}
// Ensure that `Use Custom Build` is enabled if a plugin is selected.
String enabled_plugins_names = PluginConfigAndroid::get_plugins_names(get_enabled_plugins(p_preset));
- bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
if (!enabled_plugins_names.is_empty() && !custom_build_enabled) {
valid = false;
err += TTR("\"Use Custom Build\" must be enabled to use the plugins.");
@@ -2176,12 +2203,34 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
}
if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
- !bool(p_preset->get("custom_template/use_custom_build"))) {
+ !custom_build_enabled) {
valid = false;
err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
err += "\n";
}
+ // Check the min sdk version
+ int min_sdk_version = p_preset->get("version/min_sdk");
+ if (min_sdk_version != DEFAULT_MIN_SDK_VERSION && !custom_build_enabled) {
+ valid = false;
+ err += TTR("Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+
+ // Check the target sdk version
+ int target_sdk_version = p_preset->get("version/target_sdk");
+ if (target_sdk_version != DEFAULT_TARGET_SDK_VERSION && !custom_build_enabled) {
+ valid = false;
+ err += TTR("Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+
+ if (target_sdk_version < min_sdk_version) {
+ valid = false;
+ err += TTR("\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version.");
+ err += "\n";
+ }
+
r_error = err;
return valid;
}
@@ -2559,6 +2608,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String package_name = get_package_name(p_preset->get("package/unique_name"));
String version_code = itos(p_preset->get("version/code"));
String version_name = p_preset->get("version/name");
+ String min_sdk_version = itos(p_preset->get("version/min_sdk"));
+ String target_sdk_version = itos(p_preset->get("version/target_sdk"));
String enabled_abi_string = String("|").join(enabled_abis);
String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
@@ -2588,6 +2639,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code.
cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name.
+ cmdline.push_back("-Pexport_version_min_sdk=" + min_sdk_version); // argument to specify the min sdk.
+ cmdline.push_back("-Pexport_version_target_sdk=" + target_sdk_version); // argument to specify the target sdk.
cmdline.push_back("-Pexport_enabled_abis=" + enabled_abi_string); // argument to specify enabled ABIs.
cmdline.push_back("-Pplugins_local_binaries=" + local_plugins_binaries); // argument to specify the list of plugins local dependencies.
cmdline.push_back("-Pplugins_remote_binaries=" + remote_plugins_binaries); // argument to specify the list of plugins remote dependencies.
@@ -2680,13 +2733,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
src_apk = p_preset->get("custom_template/release");
}
src_apk = src_apk.strip_edges();
- if (src_apk == "") {
+ if (src_apk.is_empty()) {
if (p_debug) {
src_apk = find_export_template("android_debug.apk");
} else {
src_apk = find_export_template("android_release.apk");
}
- if (src_apk == "") {
+ if (src_apk.is_empty()) {
EditorNode::add_io_error(vformat(TTR("Package not found: %s"), src_apk));
return ERR_FILE_NOT_FOUND;
}
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 658c0ecd0a..27c84baa44 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -161,7 +161,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
da->list_dir_begin();
while (true) {
String file = da->get_next();
- if (file == "") {
+ if (file.is_empty()) {
break;
}
if (!file.begins_with("values-")) {
@@ -252,8 +252,10 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation"))));
String manifest_activity_text = vformat(
" <activity android:name=\"com.godot.game.GodotApp\" "
- "tools:replace=\"android:screenOrientation\" "
+ "tools:replace=\"android:screenOrientation,android:excludeFromRecents\" "
+ "android:excludeFromRecents=\"%s\" "
"android:screenOrientation=\"%s\">\n",
+ bool_to_string(p_preset->get("package/exclude_from_recents")),
orientation);
if (uses_xr) {
manifest_activity_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"true\" />\n";
@@ -275,7 +277,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
" android:hasFragileUserData=\"%s\"\n"
" android:requestLegacyExternalStorage=\"%s\"\n"
" tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"
- " tools:ignore=\"GoogleAppIndexingWarning\">\n\n",
+ " tools:ignore=\"GoogleAppIndexingWarning\">\n\n"
+ " <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n"
+ " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n",
bool_to_string(p_preset->get("user_data_backup/allow")),
bool_to_string(p_preset->get("package/classify_as_game")),
bool_to_string(p_preset->get("package/retain_data_on_uninstall")),
@@ -283,6 +287,15 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
if (uses_xr) {
manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
+
+ bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE;
+ if (hand_tracking_enabled) {
+ int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency");
+ String hand_tracking_frequency = hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH";
+ manifest_application_text += vformat(
+ " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.frequency\" android:value=\"%s\" />\n",
+ hand_tracking_frequency);
+ }
}
manifest_application_text += _get_activity_tag(p_preset);
manifest_application_text += " </application>\n";
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index db05c7534c..3c440f3e29 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -54,6 +54,10 @@ static const int XR_HAND_TRACKING_NONE = 0;
static const int XR_HAND_TRACKING_OPTIONAL = 1;
static const int XR_HAND_TRACKING_REQUIRED = 2;
+// Supported XR hand tracking frequencies.
+static const int XR_HAND_TRACKING_FREQUENCY_LOW = 0;
+static const int XR_HAND_TRACKING_FREQUENCY_HIGH = 1;
+
// Supported XR passthrough modes.
static const int XR_PASSTHROUGH_NONE = 0;
static const int XR_PASSTHROUGH_OPTIONAL = 1;
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 9ae6367b42..3924aacccd 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -38,11 +38,19 @@
android:name="xr_mode_metadata_name"
android:value="xr_mode_metadata_value" />
+ <!-- XR hand tracking metadata -->
+ <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
+ <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. -->
+ <meta-data
+ android:name="xr_hand_tracking_metadata_name"
+ android:value="xr_hand_tracking_metadata_value"/>
+
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleTask"
+ android:excludeFromRecents="false"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index a391a3ca9a..5d1a9d7b99 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -91,8 +91,8 @@ android {
applicationId getExportPackageName()
versionCode getExportVersionCode()
versionName getExportVersionName()
- minSdkVersion versions.minSdk
- targetSdkVersion versions.targetSdk
+ minSdkVersion getExportMinSdkVersion()
+ targetSdkVersion getExportTargetSdkVersion()
}
lintOptions {
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 2a2850df0f..32e03998da 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,8 +1,8 @@
ext.versions = [
androidGradlePlugin: '7.0.3',
compileSdk : 30,
- minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' value
- targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' value
+ minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
+ targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
buildTools : '30.0.3',
kotlinVersion : '1.5.10',
fragmentVersion : '1.3.6',
@@ -48,6 +48,30 @@ ext.getExportVersionName = { ->
return versionName
}
+ext.getExportMinSdkVersion = { ->
+ String minSdkVersion = project.hasProperty("export_version_min_sdk") ? project.property("export_version_min_sdk") : ""
+ if (minSdkVersion == null || minSdkVersion.isEmpty()) {
+ minSdkVersion = "$versions.minSdk"
+ }
+ try {
+ return Integer.parseInt(minSdkVersion)
+ } catch (NumberFormatException ignored) {
+ return versions.minSdk
+ }
+}
+
+ext.getExportTargetSdkVersion = { ->
+ String targetSdkVersion = project.hasProperty("export_version_target_sdk") ? project.property("export_version_target_sdk") : ""
+ if (targetSdkVersion == null || targetSdkVersion.isEmpty()) {
+ targetSdkVersion = "$versions.targetSdk"
+ }
+ try {
+ return Integer.parseInt(targetSdkVersion)
+ } catch (NumberFormatException ignored) {
+ return versions.targetSdk
+ }
+}
+
ext.getGodotEditorVersion = { ->
String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : ""
if (editorVersion == null || editorVersion.isEmpty()) {
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 0e5e10bc0a..ffd69a56b9 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -198,7 +198,7 @@ String OS_Android::get_resource_dir() const {
String OS_Android::get_locale() const {
String locale = godot_io_java->get_locale();
- if (locale != "") {
+ if (!locale.is_empty()) {
return locale;
}
@@ -207,7 +207,7 @@ String OS_Android::get_locale() const {
String OS_Android::get_model_name() const {
String model = godot_io_java->get_model();
- if (model != "")
+ if (!model.is_empty())
return model;
return OS_Unix::get_model_name();
@@ -218,11 +218,11 @@ String OS_Android::get_data_path() const {
}
String OS_Android::get_user_data_dir() const {
- if (data_dir_cache != String())
+ if (!data_dir_cache.is_empty())
return data_dir_cache;
String data_dir = godot_io_java->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
data_dir_cache = _remove_symlink(data_dir);
return data_dir_cache;
}
@@ -230,11 +230,11 @@ String OS_Android::get_user_data_dir() const {
}
String OS_Android::get_cache_path() const {
- if (cache_dir_cache != String())
+ if (!cache_dir_cache.is_empty())
return cache_dir_cache;
String cache_dir = godot_io_java->get_cache_dir();
- if (cache_dir != "") {
+ if (!cache_dir.is_empty()) {
cache_dir_cache = _remove_symlink(cache_dir);
return cache_dir_cache;
}
@@ -243,7 +243,7 @@ String OS_Android::get_cache_path() const {
String OS_Android::get_unique_id() const {
String unique_id = godot_io_java->get_unique_id();
- if (unique_id != "")
+ if (!unique_id.is_empty())
return unique_id;
return OS::get_unique_id();
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 7450215cfb..247b456b26 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -728,10 +728,10 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp
Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata) {
Vector<String> dirs;
- String path;
String current_dir = p_da->get_current_dir();
p_da->list_dir_begin();
- while ((path = p_da->get_next()).length() != 0) {
+ String path = p_da->get_next();
+ while (!path.is_empty()) {
if (p_da->current_is_dir()) {
if (path != "." && path != "..") {
dirs.push_back(path);
@@ -743,6 +743,7 @@ Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler
return err;
}
}
+ path = p_da->get_next();
}
p_da->list_dir_end();
@@ -1362,10 +1363,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
src_pkg_name = p_preset->get("custom_template/release");
}
- if (src_pkg_name == "") {
+ if (src_pkg_name.is_empty()) {
String err;
src_pkg_name = find_export_template("iphone.zip", &err);
- if (src_pkg_name == "") {
+ if (src_pkg_name.is_empty()) {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
@@ -1766,7 +1767,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
}
String etc_error = test_etc2_or_pvrtc();
- if (etc_error != String()) {
+ if (!etc_error.is_empty()) {
valid = false;
err += etc_error;
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index fa9e6eed15..8d9ba82fd4 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -28,11 +28,11 @@ if env["javascript_eval"]:
sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"])
for lib in sys_env["JS_LIBS"]:
- sys_env.Append(LINKFLAGS=["--js-library", lib])
+ sys_env.Append(LINKFLAGS=["--js-library", lib.abspath])
for js in env["JS_PRE"]:
- sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path])
+ sys_env.Append(LINKFLAGS=["--pre-js", js.abspath])
for ext in env["JS_EXTERNS"]:
- sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path
+ sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.abspath
build = []
if env["gdnative_enabled"]:
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 018dd3b664..9733435584 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -380,7 +380,7 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p
if (p_preset->get("vram_texture_compression/for_mobile")) {
String etc_error = test_etc2();
- if (etc_error != String()) {
+ if (!etc_error.is_empty()) {
valid = false;
err += etc_error;
}
@@ -415,7 +415,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
// Find the correct template
String template_path = p_debug ? custom_debug : custom_release;
template_path = template_path.strip_edges();
- if (template_path == String()) {
+ if (template_path.is_empty()) {
ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
template_path = find_export_template(_get_template_name(mode, p_debug));
}
@@ -424,7 +424,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return ERR_FILE_BAD_PATH;
}
- if (template_path != String() && !FileAccess::exists(template_path)) {
+ if (!template_path.is_empty() && !FileAccess::exists(template_path)) {
EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js
index d85d0d5335..f403e85a30 100644
--- a/platform/javascript/js/libs/library_godot_input.js
+++ b/platform/javascript/js/libs/library_godot_input.js
@@ -262,7 +262,7 @@ const GodotInputDragDrop = {
const DROP = `/tmp/drop-${parseInt(Math.random() * (1 << 30), 10)}/`;
const drops = [];
const files = [];
- FS.mkdir(DROP);
+ FS.mkdir(DROP.slice(0, -1)); // Without trailing slash
GodotInputDragDrop.pending_files.forEach((elem) => {
const path = elem['path'];
GodotFS.copy_to_fs(DROP + path, elem['data']);
@@ -393,7 +393,9 @@ const GodotInput = {
const rect = canvas.getBoundingClientRect();
const pos = GodotInput.computePosition(evt, rect);
const modifiers = GodotInput.getModifiers(evt);
- if (p_pressed && document.activeElement !== GodotConfig.canvas) {
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (p_pressed) {
GodotConfig.canvas.focus();
}
if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) {
@@ -412,7 +414,9 @@ const GodotInput = {
const func = GodotRuntime.get_func(callback);
const canvas = GodotConfig.canvas;
function touch_cb(type, evt) {
- if (type === 0 && document.activeElement !== GodotConfig.canvas) {
+ // Since the event is consumed, focus manually.
+ // NOTE: The iframe container may not have focus yet, so focus even when already active.
+ if (type === 0) {
GodotConfig.canvas.focus();
}
const rect = canvas.getBoundingClientRect();
@@ -420,9 +424,9 @@ const GodotInput = {
for (let i = 0; i < touches.length; i++) {
const touch = touches[i];
const pos = GodotInput.computePosition(touch, rect);
- GodotRuntime.setHeapValue(coords + (i * 2), pos[0], 'double');
- GodotRuntime.setHeapValue(coords + (i * 2 + 8), pos[1], 'double');
- GodotRuntime.setHeapValue(ids + i, touch.identifier, 'i32');
+ GodotRuntime.setHeapValue(coords + (i * 2) * 8, pos[0], 'double');
+ GodotRuntime.setHeapValue(coords + (i * 2 + 1) * 8, pos[1], 'double');
+ GodotRuntime.setHeapValue(ids + i * 4, touch.identifier, 'i32');
}
func(type, touches.length);
if (evt.cancelable) {
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 69474c6dec..c39b5cb784 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -419,7 +419,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
String mnt = get_mountpoint(p_path);
// If there is a directory "[Mountpoint]/.Trash-[UID], use it as the trash can.
- if (mnt != "") {
+ if (!mnt.is_empty()) {
String path(mnt + "/.Trash-" + itos(getuid()));
struct stat s;
if (!stat(path.utf8().get_data(), &s)) {
@@ -428,7 +428,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
}
// Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash" as the trash can.
- if (trash_path == "") {
+ if (trash_path.is_empty()) {
char *dhome = getenv("XDG_DATA_HOME");
if (dhome) {
trash_path = String(dhome) + "/Trash";
@@ -436,7 +436,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
}
// Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash" as the trash can.
- if (trash_path == "") {
+ if (trash_path.is_empty()) {
char *home = getenv("HOME");
if (home) {
trash_path = String(home) + "/.local/share/Trash";
@@ -444,7 +444,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
}
// Issue an error if none of the previous locations is appropriate for the trash can.
- ERR_FAIL_COND_V_MSG(trash_path == "", FAILED, "Could not determine the trash can location");
+ ERR_FAIL_COND_V_MSG(trash_path.is_empty(), FAILED, "Could not determine the trash can location");
// Create needed directories for decided trash can location.
{
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index a88f7bb332..8126510245 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -481,10 +481,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
src_pkg_name = p_preset->get("custom_template/release");
}
- if (src_pkg_name == "") {
+ if (src_pkg_name.is_empty()) {
String err;
src_pkg_name = find_export_template("osx.zip", &err);
- if (src_pkg_name == "") {
+ if (src_pkg_name.is_empty()) {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
@@ -607,7 +607,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
iconpath = ProjectSettings::get_singleton()->get("application/config/icon");
}
- if (iconpath != "") {
+ if (!iconpath.is_empty()) {
if (iconpath.get_extension() == "icns") {
FileAccess *icon = FileAccess::open(iconpath, FileAccess::READ);
if (icon) {
@@ -695,7 +695,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String ent_path = p_preset->get("codesign/entitlements/custom_file");
String hlp_ent_path = EditorPaths::get_singleton()->get_cache_dir().plus_file(pkg_name + "_helper.entitlements");
- if (sign_enabled && (ent_path == "")) {
+ if (sign_enabled && (ent_path.is_empty())) {
ent_path = EditorPaths::get_singleton()->get_cache_dir().plus_file(pkg_name + ".entitlements");
FileAccess *ent_f = FileAccess::open(ent_path, FileAccess::WRITE);
@@ -960,9 +960,10 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
DirAccessRef da = DirAccess::open(dir);
da->list_dir_begin();
- String f;
- while ((f = da->get_next()) != "") {
+ String f = da->get_next();
+ while (!f.is_empty()) {
if (f == "." || f == "..") {
+ f = da->get_next();
continue;
}
if (da->is_link(f)) {
@@ -1065,6 +1066,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
zipCloseFileInZip(p_zip);
}
+ f = da->get_next();
}
da->list_dir_end();
}
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 45a81be80a..39608bdea8 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -178,7 +178,7 @@
class OSXTerminalLogger : public StdLogger {
public:
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR) {
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) {
if (!should_log(true)) {
return;
}
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index 192814efe4..31a6889543 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -257,7 +257,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
Platform arch = (Platform)(int)p_preset->get("architecture/target");
- if (src_appx == "") {
+ if (src_appx.is_empty()) {
String err, infix;
switch (arch) {
case ARM: {
@@ -275,7 +275,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
} else {
src_appx = find_export_template("uwp" + infix + "release.zip", &err);
}
- if (src_appx == "") {
+ if (src_appx.is_empty()) {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
@@ -431,7 +431,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
#ifdef WINDOWS_ENABLED
// Sign with signtool
String signtool_path = EditorSettings::get_singleton()->get("export/uwp/signtool");
- if (signtool_path == String()) {
+ if (signtool_path.is_empty()) {
return OK;
}
@@ -452,7 +452,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
cert_alg = p_preset->get("signing/algorithm");
}
- if (cert_path == String()) {
+ if (cert_path.is_empty()) {
return OK; // Certificate missing, don't try to sign
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 9fe15366f4..2878981078 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -1565,7 +1565,7 @@ String DisplayServerWindows::keyboard_get_layout_name(int p_index) const {
GetKeyboardLayoutList(layout_count, layouts);
String ret = _get_full_layout_name_from_registry(layouts[p_index]); // Try reading full name from Windows registry, fallback to locale name if failed (e.g. on Wine).
- if (ret == String()) {
+ if (ret.is_empty()) {
WCHAR buf[LOCALE_NAME_MAX_LENGTH];
memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(WCHAR));
LCIDToLocaleName(MAKELCID(LOWORD(layouts[p_index]), SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 165e86c066..5a1cdb0962 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -82,7 +82,7 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
- if (rcedit_path == String()) {
+ if (rcedit_path.is_empty()) {
return;
}
@@ -95,12 +95,12 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
// On non-Windows we need WINE to run rcedit
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
- if (wine_path != String() && !FileAccess::exists(wine_path)) {
+ if (!wine_path.is_empty() && !FileAccess::exists(wine_path)) {
ERR_PRINT("Could not find wine executable at " + wine_path + ", no icon or app information data will be included.");
return;
}
- if (wine_path == String()) {
+ if (wine_path.is_empty()) {
wine_path = "wine"; // try to run wine from PATH
}
#endif
@@ -117,39 +117,39 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
List<String> args;
args.push_back(p_path);
- if (icon_path != String()) {
+ if (!icon_path.is_empty()) {
args.push_back("--set-icon");
args.push_back(icon_path);
}
- if (file_verion != String()) {
+ if (!file_verion.is_empty()) {
args.push_back("--set-file-version");
args.push_back(file_verion);
}
- if (product_version != String()) {
+ if (!product_version.is_empty()) {
args.push_back("--set-product-version");
args.push_back(product_version);
}
- if (company_name != String()) {
+ if (!company_name.is_empty()) {
args.push_back("--set-version-string");
args.push_back("CompanyName");
args.push_back(company_name);
}
- if (product_name != String()) {
+ if (!product_name.is_empty()) {
args.push_back("--set-version-string");
args.push_back("ProductName");
args.push_back(product_name);
}
- if (file_description != String()) {
+ if (!file_description.is_empty()) {
args.push_back("--set-version-string");
args.push_back("FileDescription");
args.push_back(file_description);
}
- if (copyright != String()) {
+ if (!copyright.is_empty()) {
args.push_back("--set-version-string");
args.push_back("LegalCopyright");
args.push_back(copyright);
}
- if (trademarks != String()) {
+ if (!trademarks.is_empty()) {
args.push_back("--set-version-string");
args.push_back("LegalTrademarks");
args.push_back(trademarks);
@@ -169,20 +169,20 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#ifdef WINDOWS_ENABLED
String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool");
- if (signtool_path != String() && !FileAccess::exists(signtool_path)) {
+ if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting.");
return ERR_FILE_NOT_FOUND;
}
- if (signtool_path == String()) {
+ if (signtool_path.is_empty()) {
signtool_path = "signtool"; // try to run signtool from PATH
}
#else
String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode");
- if (signtool_path != String() && !FileAccess::exists(signtool_path)) {
+ if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
ERR_PRINT("Could not find osslsigncode executable at " + signtool_path + ", aborting.");
return ERR_FILE_NOT_FOUND;
}
- if (signtool_path == String()) {
+ if (signtool_path.is_empty()) {
signtool_path = "osslsigncode"; // try to run signtool from PATH
}
#endif
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index d8d4e92d9d..d2cf9a62ee 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -447,7 +447,12 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS;
+#ifndef DEBUG_ENABLED
+ dwCreationFlags |= CREATE_NO_WINDOW;
+#endif
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
WaitForSingleObject(pi.pi.hProcess, INFINITE);
@@ -475,7 +480,12 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS;
+#ifndef DEBUG_ENABLED
+ dwCreationFlags |= CREATE_NO_WINDOW;
+#endif
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
ProcessID pid = pi.pi.dwProcessId;
@@ -596,7 +606,7 @@ String OS_Windows::get_locale() const {
wl++;
}
- if (neutral != "")
+ if (!neutral.is_empty())
return String(neutral).replace("-", "_");
return "en";
@@ -747,11 +757,11 @@ String OS_Windows::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
String OS_Windows::get_user_data_dir() const {
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
- if (appname != "") {
+ if (!appname.is_empty()) {
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
if (use_custom_dir) {
String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
- if (custom_dir == "") {
+ if (custom_dir.is_empty()) {
custom_dir = appname;
}
return get_data_path().plus_file(custom_dir).replace("\\", "/");
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index e54a61fdfd..d4148630f0 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -71,7 +71,7 @@ void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_er
#endif
}
-void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h
index aacfe5869e..86b65ae30a 100644
--- a/platform/windows/windows_terminal_logger.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -37,8 +37,8 @@
class WindowsTerminalLogger : public StdLogger {
public:
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) override;
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override;
virtual ~WindowsTerminalLogger();
};
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index fad4784d51..4fc5c4c21f 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -122,13 +122,13 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
}
property.hint_string += String(E->get());
- if (animation == E) {
+ if (animation == E->get()) {
current_found = true;
}
}
if (!current_found) {
- if (property.hint_string == String()) {
+ if (property.hint_string.is_empty()) {
property.hint_string = String(animation);
} else {
property.hint_string = String(animation) + "," + property.hint_string;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index bf5671be19..b6902686fe 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -176,7 +176,7 @@ Transform2D Camera2D::get_camera_transform() {
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom);
- if (!limit_smoothing_enabled) {
+ if (!smoothing_enabled || !limit_smoothing_enabled) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
screen_rect.position.x = limit[SIDE_LEFT];
}
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 6b1750f9e9..3bc212ffca 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -743,7 +743,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
real_t angle1_rad = direction.angle() + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
- p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf());
+ p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf());
real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
p.rotation = Math::deg2rad(base_angle);
@@ -904,7 +904,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.rotation = Math::deg2rad(base_angle); //angle
- p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed));
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed));
}
//apply color
//apply hue rotation
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index f1f4d1b769..4384ec8141 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -170,6 +170,13 @@ void GPUParticles2D::set_trail_section_subdivisions(int p_subdivisions) {
update();
}
+#ifdef TOOLS_ENABLED
+void GPUParticles2D::set_show_visibility_rect(bool p_show_visibility_rect) {
+ show_visibility_rect = p_show_visibility_rect;
+ update();
+}
+#endif
+
bool GPUParticles2D::is_trail_enabled() const {
return trail_enabled;
}
@@ -452,7 +459,7 @@ void GPUParticles2D::_notification(int p_what) {
RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid);
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
+ if (show_visibility_rect) {
draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false);
}
#endif
@@ -588,6 +595,9 @@ GPUParticles2D::GPUParticles2D() {
set_speed_scale(1);
set_fixed_fps(30);
set_collision_base_size(collision_base_size);
+#ifdef TOOLS_ENABLED
+ show_visibility_rect = false;
+#endif
}
GPUParticles2D::~GPUParticles2D() {
diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h
index d7eee461b4..a9e66b3051 100644
--- a/scene/2d/gpu_particles_2d.h
+++ b/scene/2d/gpu_particles_2d.h
@@ -58,7 +58,9 @@ private:
bool local_coords;
int fixed_fps;
bool fractional_delta;
-
+#ifdef TOOLS_ENABLED
+ bool show_visibility_rect;
+#endif
Ref<Material> process_material;
DrawOrder draw_order;
@@ -81,7 +83,6 @@ protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
-
void _update_collision_size();
public:
@@ -102,6 +103,10 @@ public:
void set_trail_sections(int p_sections);
void set_trail_section_subdivisions(int p_subdivisions);
+#ifdef TOOLS_ENABLED
+ void set_show_visibility_rect(bool p_show_visibility_rect);
+#endif
+
bool is_emitting() const;
int get_amount() const;
double get_lifetime() const;
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index ed30e871d7..40211f2a9b 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -100,16 +100,18 @@ void Path2D::_notification(int p_what) {
#endif
const Color color = Color(0.5, 0.6, 1.0, 0.7);
- for (int i = 0; i < curve->get_point_count(); i++) {
- Vector2 prev_p = curve->get_point_position(i);
+ _cached_draw_pts.resize(curve->get_point_count() * 8);
+ int count = 0;
- for (int j = 1; j <= 8; j++) {
- real_t frac = j / 8.0;
+ for (int i = 0; i < curve->get_point_count(); i++) {
+ for (int j = 0; j < 8; j++) {
+ real_t frac = j * (1.0 / 8.0);
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width);
- prev_p = p;
+ _cached_draw_pts.set(count++, p);
}
}
+
+ draw_polyline(_cached_draw_pts, color, line_width, true);
}
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 3b12f025fc..7e8478283f 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -38,6 +38,7 @@ class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);
Ref<Curve2D> curve;
+ Vector<Vector2> _cached_draw_pts;
void _curve_changed();
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index efe23c6102..bdcab49e4e 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -391,7 +391,13 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space());
for (Camera3D *camera : cameras) {
+ if (!camera) {
+ continue;
+ }
Viewport *vp = camera->get_viewport();
+ if (!vp) {
+ continue;
+ }
if (!vp->is_audio_listener_3d()) {
continue;
}
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index cfe538398d..905a137001 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -765,7 +765,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
- p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf());
+ p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf());
} else {
//initiate velocity spread in 3D
real_t angle1_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread);
@@ -789,7 +789,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
binormal.normalize();
Vector3 normal = binormal.cross(direction_nrm);
spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;
- p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], float(Math::randf()));
+ p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf());
}
real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
@@ -895,53 +895,53 @@ void CPUParticles3D::_particles_process(double p_delta) {
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;
- real_t tex_linear_velocity = 0.0;
+ real_t tex_linear_velocity = 1.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
- real_t tex_orbit_velocity = 0.0;
+ real_t tex_orbit_velocity = 1.0;
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}
- real_t tex_angular_velocity = 0.0;
+ real_t tex_angular_velocity = 1.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
- real_t tex_linear_accel = 0.0;
+ real_t tex_linear_accel = 1.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
- real_t tex_tangential_accel = 0.0;
+ real_t tex_tangential_accel = 1.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
- real_t tex_radial_accel = 0.0;
+ real_t tex_radial_accel = 1.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
- real_t tex_damping = 0.0;
+ real_t tex_damping = 1.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
- real_t tex_angle = 0.0;
+ real_t tex_angle = 1.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
- real_t tex_anim_speed = 0.0;
+ real_t tex_anim_speed = 1.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
- real_t tex_anim_offset = 0.0;
+ real_t tex_anim_offset = 1.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
@@ -998,7 +998,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.custom[0] = Math::deg2rad(base_angle); //angle
- p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle
}
//apply color
//apply hue rotation
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
index 2235de1599..adb532145b 100644
--- a/scene/3d/gpu_particles_collision_3d.cpp
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -62,68 +62,68 @@ GPUParticlesCollision3D::~GPUParticlesCollision3D() {
/////////////////////////////////
-void GPUParticlesCollisionSphere::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesCollisionSphere::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesCollisionSphere::get_radius);
+void GPUParticlesCollisionSphere3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesCollisionSphere3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesCollisionSphere3D::get_radius);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius");
}
-void GPUParticlesCollisionSphere::set_radius(real_t p_radius) {
+void GPUParticlesCollisionSphere3D::set_radius(real_t p_radius) {
radius = p_radius;
RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
update_gizmos();
}
-real_t GPUParticlesCollisionSphere::get_radius() const {
+real_t GPUParticlesCollisionSphere3D::get_radius() const {
return radius;
}
-AABB GPUParticlesCollisionSphere::get_aabb() const {
+AABB GPUParticlesCollisionSphere3D::get_aabb() const {
return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2));
}
-GPUParticlesCollisionSphere::GPUParticlesCollisionSphere() :
+GPUParticlesCollisionSphere3D::GPUParticlesCollisionSphere3D() :
GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE) {
}
-GPUParticlesCollisionSphere::~GPUParticlesCollisionSphere() {
+GPUParticlesCollisionSphere3D::~GPUParticlesCollisionSphere3D() {
}
///////////////////////////
-void GPUParticlesCollisionBox::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox::get_extents);
+void GPUParticlesCollisionBox3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox3D::get_extents);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
}
-void GPUParticlesCollisionBox::set_extents(const Vector3 &p_extents) {
+void GPUParticlesCollisionBox3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmos();
}
-Vector3 GPUParticlesCollisionBox::get_extents() const {
+Vector3 GPUParticlesCollisionBox3D::get_extents() const {
return extents;
}
-AABB GPUParticlesCollisionBox::get_aabb() const {
+AABB GPUParticlesCollisionBox3D::get_aabb() const {
return AABB(-extents, extents * 2);
}
-GPUParticlesCollisionBox::GPUParticlesCollisionBox() :
+GPUParticlesCollisionBox3D::GPUParticlesCollisionBox3D() :
GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_BOX_COLLIDE) {
}
-GPUParticlesCollisionBox::~GPUParticlesCollisionBox() {
+GPUParticlesCollisionBox3D::~GPUParticlesCollisionBox3D() {
}
///////////////////////////////
///////////////////////////
-void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) {
+void GPUParticlesCollisionSDF3D::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) {
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node);
if (mi && mi->is_visible_in_tree()) {
Ref<Mesh> mesh = mi->get_mesh();
@@ -172,7 +172,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node,
}
}
-uint32_t GPUParticlesCollisionSDF::_create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness) {
+uint32_t GPUParticlesCollisionSDF3D::_create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness) {
if (p_face_count == 1) {
return BVH::LEAF_BIT | p_faces[0].index;
}
@@ -220,7 +220,7 @@ static _FORCE_INLINE_ real_t Vector3_dot2(const Vector3 &p_vec3) {
return p_vec3.dot(p_vec3);
}
-void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance) {
+void GPUParticlesCollisionSDF3D::_find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance) {
if (p_bvh_cell & BVH::LEAF_BIT) {
p_bvh_cell &= BVH::LEAF_MASK; //remove bit
@@ -321,7 +321,7 @@ void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, cons
}
}
-void GPUParticlesCollisionSDF::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *params) {
+void GPUParticlesCollisionSDF3D::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *params) {
int32_t z_ofs = p_z * params->size.y * params->size.x;
for (int32_t y = 0; y < params->size.y; y++) {
int32_t y_ofs = z_ofs + y * params->size.x;
@@ -338,10 +338,10 @@ void GPUParticlesCollisionSDF::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *pa
}
}
-void GPUParticlesCollisionSDF::_compute_sdf(ComputeSDFParams *params) {
+void GPUParticlesCollisionSDF3D::_compute_sdf(ComputeSDFParams *params) {
ThreadWorkPool work_pool;
work_pool.init();
- work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF::_compute_sdf_z, params);
+ work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF3D::_compute_sdf_z, params);
while (!work_pool.is_done_dispatching()) {
OS::get_singleton()->delay_usec(10000);
bake_step_function(work_pool.get_work_index() * 100 / params->size.z, "Baking SDF");
@@ -350,7 +350,7 @@ void GPUParticlesCollisionSDF::_compute_sdf(ComputeSDFParams *params) {
work_pool.finish();
}
-Vector3i GPUParticlesCollisionSDF::get_estimated_cell_size() const {
+Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const {
static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
int subdiv = subdivs[get_resolution()];
@@ -365,7 +365,7 @@ Vector3i GPUParticlesCollisionSDF::get_estimated_cell_size() const {
return sdf_size;
}
-Ref<Image> GPUParticlesCollisionSDF::bake() {
+Ref<Image> GPUParticlesCollisionSDF3D::bake() {
static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 };
int subdiv = subdivs[get_resolution()];
@@ -501,18 +501,18 @@ Ref<Image> GPUParticlesCollisionSDF::bake() {
return ret;
}
-void GPUParticlesCollisionSDF::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF::get_extents);
+void GPUParticlesCollisionSDF3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents);
- ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF::set_resolution);
- ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF::get_resolution);
+ ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF3D::set_resolution);
+ ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF3D::get_resolution);
- ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesCollisionSDF::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesCollisionSDF::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesCollisionSDF3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesCollisionSDF3D::get_texture);
- ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF::set_thickness);
- ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF::get_thickness);
+ ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF3D::set_thickness);
+ ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF3D::get_thickness);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512"), "set_resolution", "get_resolution");
@@ -528,62 +528,62 @@ void GPUParticlesCollisionSDF::_bind_methods() {
BIND_ENUM_CONSTANT(RESOLUTION_MAX);
}
-void GPUParticlesCollisionSDF::set_thickness(float p_thickness) {
+void GPUParticlesCollisionSDF3D::set_thickness(float p_thickness) {
thickness = p_thickness;
}
-float GPUParticlesCollisionSDF::get_thickness() const {
+float GPUParticlesCollisionSDF3D::get_thickness() const {
return thickness;
}
-void GPUParticlesCollisionSDF::set_extents(const Vector3 &p_extents) {
+void GPUParticlesCollisionSDF3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmos();
}
-Vector3 GPUParticlesCollisionSDF::get_extents() const {
+Vector3 GPUParticlesCollisionSDF3D::get_extents() const {
return extents;
}
-void GPUParticlesCollisionSDF::set_resolution(Resolution p_resolution) {
+void GPUParticlesCollisionSDF3D::set_resolution(Resolution p_resolution) {
resolution = p_resolution;
update_gizmos();
}
-GPUParticlesCollisionSDF::Resolution GPUParticlesCollisionSDF::get_resolution() const {
+GPUParticlesCollisionSDF3D::Resolution GPUParticlesCollisionSDF3D::get_resolution() const {
return resolution;
}
-void GPUParticlesCollisionSDF::set_texture(const Ref<Texture3D> &p_texture) {
+void GPUParticlesCollisionSDF3D::set_texture(const Ref<Texture3D> &p_texture) {
texture = p_texture;
RID tex = texture.is_valid() ? texture->get_rid() : RID();
RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex);
}
-Ref<Texture3D> GPUParticlesCollisionSDF::get_texture() const {
+Ref<Texture3D> GPUParticlesCollisionSDF3D::get_texture() const {
return texture;
}
-AABB GPUParticlesCollisionSDF::get_aabb() const {
+AABB GPUParticlesCollisionSDF3D::get_aabb() const {
return AABB(-extents, extents * 2);
}
-GPUParticlesCollisionSDF::BakeBeginFunc GPUParticlesCollisionSDF::bake_begin_function = nullptr;
-GPUParticlesCollisionSDF::BakeStepFunc GPUParticlesCollisionSDF::bake_step_function = nullptr;
-GPUParticlesCollisionSDF::BakeEndFunc GPUParticlesCollisionSDF::bake_end_function = nullptr;
+GPUParticlesCollisionSDF3D::BakeBeginFunc GPUParticlesCollisionSDF3D::bake_begin_function = nullptr;
+GPUParticlesCollisionSDF3D::BakeStepFunc GPUParticlesCollisionSDF3D::bake_step_function = nullptr;
+GPUParticlesCollisionSDF3D::BakeEndFunc GPUParticlesCollisionSDF3D::bake_end_function = nullptr;
-GPUParticlesCollisionSDF::GPUParticlesCollisionSDF() :
+GPUParticlesCollisionSDF3D::GPUParticlesCollisionSDF3D() :
GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SDF_COLLIDE) {
}
-GPUParticlesCollisionSDF::~GPUParticlesCollisionSDF() {
+GPUParticlesCollisionSDF3D::~GPUParticlesCollisionSDF3D() {
}
////////////////////////////
////////////////////////////
-void GPUParticlesCollisionHeightField::_notification(int p_what) {
+void GPUParticlesCollisionHeightField3D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (update_mode == UPDATE_MODE_ALWAYS) {
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
@@ -628,21 +628,21 @@ void GPUParticlesCollisionHeightField::_notification(int p_what) {
}
}
-void GPUParticlesCollisionHeightField::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField::get_extents);
+void GPUParticlesCollisionHeightField3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField3D::get_extents);
- ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField::set_resolution);
- ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField::get_resolution);
+ ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField3D::set_resolution);
+ ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField3D::get_resolution);
- ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &GPUParticlesCollisionHeightField::set_update_mode);
- ClassDB::bind_method(D_METHOD("get_update_mode"), &GPUParticlesCollisionHeightField::get_update_mode);
+ ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &GPUParticlesCollisionHeightField3D::set_update_mode);
+ ClassDB::bind_method(D_METHOD("get_update_mode"), &GPUParticlesCollisionHeightField3D::get_update_mode);
- ClassDB::bind_method(D_METHOD("set_follow_camera_mode", "enabled"), &GPUParticlesCollisionHeightField::set_follow_camera_mode);
- ClassDB::bind_method(D_METHOD("is_follow_camera_mode_enabled"), &GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled);
+ ClassDB::bind_method(D_METHOD("set_follow_camera_mode", "enabled"), &GPUParticlesCollisionHeightField3D::set_follow_camera_mode);
+ ClassDB::bind_method(D_METHOD("is_follow_camera_mode_enabled"), &GPUParticlesCollisionHeightField3D::is_follow_camera_mode_enabled);
- ClassDB::bind_method(D_METHOD("set_follow_camera_push_ratio", "ratio"), &GPUParticlesCollisionHeightField::set_follow_camera_push_ratio);
- ClassDB::bind_method(D_METHOD("get_follow_camera_push_ratio"), &GPUParticlesCollisionHeightField::get_follow_camera_push_ratio);
+ ClassDB::bind_method(D_METHOD("set_follow_camera_push_ratio", "ratio"), &GPUParticlesCollisionHeightField3D::set_follow_camera_push_ratio);
+ ClassDB::bind_method(D_METHOD("get_follow_camera_push_ratio"), &GPUParticlesCollisionHeightField3D::get_follow_camera_push_ratio);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096,8192"), "set_resolution", "get_resolution");
@@ -663,63 +663,63 @@ void GPUParticlesCollisionHeightField::_bind_methods() {
BIND_ENUM_CONSTANT(UPDATE_MODE_ALWAYS);
}
-void GPUParticlesCollisionHeightField::set_follow_camera_push_ratio(float p_follow_camera_push_ratio) {
+void GPUParticlesCollisionHeightField3D::set_follow_camera_push_ratio(float p_follow_camera_push_ratio) {
follow_camera_push_ratio = p_follow_camera_push_ratio;
}
-float GPUParticlesCollisionHeightField::get_follow_camera_push_ratio() const {
+float GPUParticlesCollisionHeightField3D::get_follow_camera_push_ratio() const {
return follow_camera_push_ratio;
}
-void GPUParticlesCollisionHeightField::set_extents(const Vector3 &p_extents) {
+void GPUParticlesCollisionHeightField3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmos();
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
}
-Vector3 GPUParticlesCollisionHeightField::get_extents() const {
+Vector3 GPUParticlesCollisionHeightField3D::get_extents() const {
return extents;
}
-void GPUParticlesCollisionHeightField::set_resolution(Resolution p_resolution) {
+void GPUParticlesCollisionHeightField3D::set_resolution(Resolution p_resolution) {
resolution = p_resolution;
RS::get_singleton()->particles_collision_set_height_field_resolution(_get_collision(), RS::ParticlesCollisionHeightfieldResolution(resolution));
update_gizmos();
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
}
-GPUParticlesCollisionHeightField::Resolution GPUParticlesCollisionHeightField::get_resolution() const {
+GPUParticlesCollisionHeightField3D::Resolution GPUParticlesCollisionHeightField3D::get_resolution() const {
return resolution;
}
-void GPUParticlesCollisionHeightField::set_update_mode(UpdateMode p_update_mode) {
+void GPUParticlesCollisionHeightField3D::set_update_mode(UpdateMode p_update_mode) {
update_mode = p_update_mode;
set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS);
}
-GPUParticlesCollisionHeightField::UpdateMode GPUParticlesCollisionHeightField::get_update_mode() const {
+GPUParticlesCollisionHeightField3D::UpdateMode GPUParticlesCollisionHeightField3D::get_update_mode() const {
return update_mode;
}
-void GPUParticlesCollisionHeightField::set_follow_camera_mode(bool p_enabled) {
+void GPUParticlesCollisionHeightField3D::set_follow_camera_mode(bool p_enabled) {
follow_camera_mode = p_enabled;
set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS);
}
-bool GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled() const {
+bool GPUParticlesCollisionHeightField3D::is_follow_camera_mode_enabled() const {
return follow_camera_mode;
}
-AABB GPUParticlesCollisionHeightField::get_aabb() const {
+AABB GPUParticlesCollisionHeightField3D::get_aabb() const {
return AABB(-extents, extents * 2);
}
-GPUParticlesCollisionHeightField::GPUParticlesCollisionHeightField() :
+GPUParticlesCollisionHeightField3D::GPUParticlesCollisionHeightField3D() :
GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE) {
}
-GPUParticlesCollisionHeightField::~GPUParticlesCollisionHeightField() {
+GPUParticlesCollisionHeightField3D::~GPUParticlesCollisionHeightField3D() {
}
////////////////////////////
@@ -792,104 +792,104 @@ GPUParticlesAttractor3D::~GPUParticlesAttractor3D() {
/////////////////////////////////
-void GPUParticlesAttractorSphere::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesAttractorSphere::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesAttractorSphere::get_radius);
+void GPUParticlesAttractorSphere3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesAttractorSphere3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesAttractorSphere3D::get_radius);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius");
}
-void GPUParticlesAttractorSphere::set_radius(real_t p_radius) {
+void GPUParticlesAttractorSphere3D::set_radius(real_t p_radius) {
radius = p_radius;
RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
update_gizmos();
}
-real_t GPUParticlesAttractorSphere::get_radius() const {
+real_t GPUParticlesAttractorSphere3D::get_radius() const {
return radius;
}
-AABB GPUParticlesAttractorSphere::get_aabb() const {
+AABB GPUParticlesAttractorSphere3D::get_aabb() const {
return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2));
}
-GPUParticlesAttractorSphere::GPUParticlesAttractorSphere() :
+GPUParticlesAttractorSphere3D::GPUParticlesAttractorSphere3D() :
GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT) {
}
-GPUParticlesAttractorSphere::~GPUParticlesAttractorSphere() {
+GPUParticlesAttractorSphere3D::~GPUParticlesAttractorSphere3D() {
}
///////////////////////////
-void GPUParticlesAttractorBox::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox::get_extents);
+void GPUParticlesAttractorBox3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox3D::get_extents);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
}
-void GPUParticlesAttractorBox::set_extents(const Vector3 &p_extents) {
+void GPUParticlesAttractorBox3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmos();
}
-Vector3 GPUParticlesAttractorBox::get_extents() const {
+Vector3 GPUParticlesAttractorBox3D::get_extents() const {
return extents;
}
-AABB GPUParticlesAttractorBox::get_aabb() const {
+AABB GPUParticlesAttractorBox3D::get_aabb() const {
return AABB(-extents, extents * 2);
}
-GPUParticlesAttractorBox::GPUParticlesAttractorBox() :
+GPUParticlesAttractorBox3D::GPUParticlesAttractorBox3D() :
GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_BOX_ATTRACT) {
}
-GPUParticlesAttractorBox::~GPUParticlesAttractorBox() {
+GPUParticlesAttractorBox3D::~GPUParticlesAttractorBox3D() {
}
///////////////////////////
-void GPUParticlesAttractorVectorField::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField::get_extents);
+void GPUParticlesAttractorVectorField3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField3D::set_extents);
+ ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField3D::get_extents);
- ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField3D::get_texture);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
}
-void GPUParticlesAttractorVectorField::set_extents(const Vector3 &p_extents) {
+void GPUParticlesAttractorVectorField3D::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmos();
}
-Vector3 GPUParticlesAttractorVectorField::get_extents() const {
+Vector3 GPUParticlesAttractorVectorField3D::get_extents() const {
return extents;
}
-void GPUParticlesAttractorVectorField::set_texture(const Ref<Texture3D> &p_texture) {
+void GPUParticlesAttractorVectorField3D::set_texture(const Ref<Texture3D> &p_texture) {
texture = p_texture;
RID tex = texture.is_valid() ? texture->get_rid() : RID();
RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex);
}
-Ref<Texture3D> GPUParticlesAttractorVectorField::get_texture() const {
+Ref<Texture3D> GPUParticlesAttractorVectorField3D::get_texture() const {
return texture;
}
-AABB GPUParticlesAttractorVectorField::get_aabb() const {
+AABB GPUParticlesAttractorVectorField3D::get_aabb() const {
return AABB(-extents, extents * 2);
}
-GPUParticlesAttractorVectorField::GPUParticlesAttractorVectorField() :
+GPUParticlesAttractorVectorField3D::GPUParticlesAttractorVectorField3D() :
GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT) {
}
-GPUParticlesAttractorVectorField::~GPUParticlesAttractorVectorField() {
+GPUParticlesAttractorVectorField3D::~GPUParticlesAttractorVectorField3D() {
}
diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h
index fbf68ed6df..5568ecdfc1 100644
--- a/scene/3d/gpu_particles_collision_3d.h
+++ b/scene/3d/gpu_particles_collision_3d.h
@@ -55,8 +55,8 @@ public:
~GPUParticlesCollision3D();
};
-class GPUParticlesCollisionSphere : public GPUParticlesCollision3D {
- GDCLASS(GPUParticlesCollisionSphere, GPUParticlesCollision3D);
+class GPUParticlesCollisionSphere3D : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionSphere3D, GPUParticlesCollision3D);
real_t radius = 1.0;
@@ -69,12 +69,12 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesCollisionSphere();
- ~GPUParticlesCollisionSphere();
+ GPUParticlesCollisionSphere3D();
+ ~GPUParticlesCollisionSphere3D();
};
-class GPUParticlesCollisionBox : public GPUParticlesCollision3D {
- GDCLASS(GPUParticlesCollisionBox, GPUParticlesCollision3D);
+class GPUParticlesCollisionBox3D : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionBox3D, GPUParticlesCollision3D);
Vector3 extents = Vector3(1, 1, 1);
@@ -87,12 +87,12 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesCollisionBox();
- ~GPUParticlesCollisionBox();
+ GPUParticlesCollisionBox3D();
+ ~GPUParticlesCollisionBox3D();
};
-class GPUParticlesCollisionSDF : public GPUParticlesCollision3D {
- GDCLASS(GPUParticlesCollisionSDF, GPUParticlesCollision3D);
+class GPUParticlesCollisionSDF3D : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionSDF3D, GPUParticlesCollision3D);
public:
enum Resolution {
@@ -184,14 +184,14 @@ public:
static BakeStepFunc bake_step_function;
static BakeEndFunc bake_end_function;
- GPUParticlesCollisionSDF();
- ~GPUParticlesCollisionSDF();
+ GPUParticlesCollisionSDF3D();
+ ~GPUParticlesCollisionSDF3D();
};
-VARIANT_ENUM_CAST(GPUParticlesCollisionSDF::Resolution)
+VARIANT_ENUM_CAST(GPUParticlesCollisionSDF3D::Resolution)
-class GPUParticlesCollisionHeightField : public GPUParticlesCollision3D {
- GDCLASS(GPUParticlesCollisionHeightField, GPUParticlesCollision3D);
+class GPUParticlesCollisionHeightField3D : public GPUParticlesCollision3D {
+ GDCLASS(GPUParticlesCollisionHeightField3D, GPUParticlesCollision3D);
public:
enum Resolution {
@@ -239,12 +239,12 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesCollisionHeightField();
- ~GPUParticlesCollisionHeightField();
+ GPUParticlesCollisionHeightField3D();
+ ~GPUParticlesCollisionHeightField3D();
};
-VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::Resolution)
-VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::UpdateMode)
+VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::Resolution)
+VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::UpdateMode)
class GPUParticlesAttractor3D : public VisualInstance3D {
GDCLASS(GPUParticlesAttractor3D, VisualInstance3D);
@@ -279,8 +279,8 @@ public:
~GPUParticlesAttractor3D();
};
-class GPUParticlesAttractorSphere : public GPUParticlesAttractor3D {
- GDCLASS(GPUParticlesAttractorSphere, GPUParticlesAttractor3D);
+class GPUParticlesAttractorSphere3D : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorSphere3D, GPUParticlesAttractor3D);
real_t radius = 1.0;
@@ -293,12 +293,12 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesAttractorSphere();
- ~GPUParticlesAttractorSphere();
+ GPUParticlesAttractorSphere3D();
+ ~GPUParticlesAttractorSphere3D();
};
-class GPUParticlesAttractorBox : public GPUParticlesAttractor3D {
- GDCLASS(GPUParticlesAttractorBox, GPUParticlesAttractor3D);
+class GPUParticlesAttractorBox3D : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorBox3D, GPUParticlesAttractor3D);
Vector3 extents = Vector3(1, 1, 1);
@@ -311,12 +311,12 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesAttractorBox();
- ~GPUParticlesAttractorBox();
+ GPUParticlesAttractorBox3D();
+ ~GPUParticlesAttractorBox3D();
};
-class GPUParticlesAttractorVectorField : public GPUParticlesAttractor3D {
- GDCLASS(GPUParticlesAttractorVectorField, GPUParticlesAttractor3D);
+class GPUParticlesAttractorVectorField3D : public GPUParticlesAttractor3D {
+ GDCLASS(GPUParticlesAttractorVectorField3D, GPUParticlesAttractor3D);
Vector3 extents = Vector3(1, 1, 1);
Ref<Texture3D> texture;
@@ -333,8 +333,8 @@ public:
virtual AABB get_aabb() const override;
- GPUParticlesAttractorVectorField();
- ~GPUParticlesAttractorVectorField();
+ GPUParticlesAttractorVectorField3D();
+ ~GPUParticlesAttractorVectorField3D();
};
#endif // GPU_PARTICLES_COLLISION_3D_H
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 1b5d4ad243..910cf3a37d 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -614,7 +614,7 @@ void LightmapGI::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, f
}
LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) {
- if (p_image_data_path == "") {
+ if (p_image_data_path.is_empty()) {
if (get_light_data().is_null()) {
return BAKE_ERROR_NO_SAVE_PATH;
}
diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp
index aeac430cd9..ac22239d70 100644
--- a/scene/3d/occluder_instance_3d.cpp
+++ b/scene/3d/occluder_instance_3d.cpp
@@ -291,7 +291,7 @@ void OccluderInstance3D::_bake_node(Node *p_node, PackedVector3Array &r_vertices
}
OccluderInstance3D::BakeError OccluderInstance3D::bake(Node *p_from_node, String p_occluder_path) {
- if (p_occluder_path == "") {
+ if (p_occluder_path.is_empty()) {
if (get_occluder().is_null()) {
return BAKE_ERROR_NO_SAVE_PATH;
}
diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp
deleted file mode 100644
index 23df00c1f6..0000000000
--- a/scene/3d/proximity_group_3d.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*************************************************************************/
-/* proximity_group_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "proximity_group_3d.h"
-
-#include "core/math/math_funcs.h"
-
-void ProximityGroup3D::_clear_groups() {
- Map<StringName, uint32_t>::Element *E;
- const int size = 16;
-
- do {
- StringName remove_list[size];
- E = groups.front();
- int num = 0;
- while (E && num < size) {
- if (E->get() != group_version) {
- remove_list[num++] = E->key();
- }
-
- E = E->next();
- }
- for (int i = 0; i < num; i++) {
- groups.erase(remove_list[i]);
- }
- } while (E);
-}
-
-void ProximityGroup3D::_update_groups() {
- if (grid_radius == Vector3(0, 0, 0)) {
- return;
- }
-
- ++group_version;
-
- Vector3 pos = get_global_transform().get_origin();
- Vector3 vcell = pos / cell_size;
- int cell[3] = { Math::fast_ftoi(vcell.x), Math::fast_ftoi(vcell.y), Math::fast_ftoi(vcell.z) };
-
- _add_groups(cell, group_name, 0);
-
- _clear_groups();
-}
-
-void ProximityGroup3D::_add_groups(int *p_cell, String p_base, int p_depth) {
- p_base = p_base + "|";
- if (grid_radius[p_depth] == 0) {
- if (p_depth == 2) {
- _new_group(p_base);
- } else {
- _add_groups(p_cell, p_base, p_depth + 1);
- }
- }
-
- int start = p_cell[p_depth] - grid_radius[p_depth];
- int end = p_cell[p_depth] + grid_radius[p_depth];
-
- for (int i = start; i <= end; i++) {
- String gname = p_base + itos(i);
- if (p_depth == 2) {
- _new_group(gname);
- } else {
- _add_groups(p_cell, gname, p_depth + 1);
- }
- }
-}
-
-void ProximityGroup3D::_new_group(StringName p_name) {
- const Map<StringName, uint32_t>::Element *E = groups.find(p_name);
- if (!E) {
- add_to_group(p_name);
- }
-
- groups[p_name] = group_version;
-}
-
-void ProximityGroup3D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_EXIT_TREE:
- ++group_version;
- _clear_groups();
- break;
- case NOTIFICATION_TRANSFORM_CHANGED:
- _update_groups();
- break;
- }
-}
-
-void ProximityGroup3D::broadcast(String p_method, Variant p_parameters) {
- Map<StringName, uint32_t>::Element *E;
- E = groups.front();
- while (E) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_method, p_parameters);
- E = E->next();
- }
-}
-
-void ProximityGroup3D::_proximity_group_broadcast(String p_method, Variant p_parameters) {
- if (dispatch_mode == MODE_PROXY) {
- ERR_FAIL_COND(!is_inside_tree());
- get_parent()->call(p_method, p_parameters);
- } else {
- emit_signal(SNAME("broadcast"), p_method, p_parameters);
- }
-}
-
-void ProximityGroup3D::set_group_name(const String &p_group_name) {
- group_name = p_group_name;
-}
-
-String ProximityGroup3D::get_group_name() const {
- return group_name;
-}
-
-void ProximityGroup3D::set_dispatch_mode(DispatchMode p_mode) {
- dispatch_mode = p_mode;
-}
-
-ProximityGroup3D::DispatchMode ProximityGroup3D::get_dispatch_mode() const {
- return dispatch_mode;
-}
-
-void ProximityGroup3D::set_grid_radius(const Vector3 &p_radius) {
- grid_radius = p_radius;
-}
-
-Vector3 ProximityGroup3D::get_grid_radius() const {
- return grid_radius;
-}
-
-void ProximityGroup3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_group_name", "name"), &ProximityGroup3D::set_group_name);
- ClassDB::bind_method(D_METHOD("get_group_name"), &ProximityGroup3D::get_group_name);
- ClassDB::bind_method(D_METHOD("set_dispatch_mode", "mode"), &ProximityGroup3D::set_dispatch_mode);
- ClassDB::bind_method(D_METHOD("get_dispatch_mode"), &ProximityGroup3D::get_dispatch_mode);
- ClassDB::bind_method(D_METHOD("set_grid_radius", "radius"), &ProximityGroup3D::set_grid_radius);
- ClassDB::bind_method(D_METHOD("get_grid_radius"), &ProximityGroup3D::get_grid_radius);
-
- ClassDB::bind_method(D_METHOD("broadcast", "method", "parameters"), &ProximityGroup3D::broadcast);
-
- ClassDB::bind_method(D_METHOD("_proximity_group_broadcast", "method", "parameters"), &ProximityGroup3D::_proximity_group_broadcast);
-
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "group_name"), "set_group_name", "get_group_name");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dispatch_mode", PROPERTY_HINT_ENUM, "Proxy,Signal"), "set_dispatch_mode", "get_dispatch_mode");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "grid_radius"), "set_grid_radius", "get_grid_radius");
-
- ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "method"), PropertyInfo(Variant::ARRAY, "parameters")));
-
- BIND_ENUM_CONSTANT(MODE_PROXY);
- BIND_ENUM_CONSTANT(MODE_SIGNAL);
-}
-
-ProximityGroup3D::ProximityGroup3D() {
- set_notify_transform(true);
-}
diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h
deleted file mode 100644
index e45adc3040..0000000000
--- a/scene/3d/proximity_group_3d.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************************************/
-/* proximity_group_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef PROXIMITY_GROUP_H
-#define PROXIMITY_GROUP_H
-
-#include "node_3d.h"
-
-class ProximityGroup3D : public Node3D {
- GDCLASS(ProximityGroup3D, Node3D);
-
-public:
- enum DispatchMode {
- MODE_PROXY,
- MODE_SIGNAL,
- };
-
-private:
- Map<StringName, uint32_t> groups;
-
- String group_name;
- DispatchMode dispatch_mode = MODE_PROXY;
- Vector3 grid_radius = Vector3(1, 1, 1);
-
- real_t cell_size = 1.0;
- uint32_t group_version = 0;
-
- void _clear_groups();
- void _update_groups();
- void _add_groups(int *p_cell, String p_base, int p_depth);
- void _new_group(StringName p_name);
-
- void _proximity_group_broadcast(String p_method, Variant p_parameters);
-
-protected:
- void _notification(int p_what);
-
- static void _bind_methods();
-
-public:
- void set_group_name(const String &p_group_name);
- String get_group_name() const;
-
- void set_dispatch_mode(DispatchMode p_mode);
- DispatchMode get_dispatch_mode() const;
-
- void set_grid_radius(const Vector3 &p_radius);
- Vector3 get_grid_radius() const;
-
- void broadcast(String p_method, Variant p_parameters);
-
- ProximityGroup3D();
- ~ProximityGroup3D() {}
-};
-
-VARIANT_ENUM_CAST(ProximityGroup3D::DispatchMode);
-
-#endif // PROXIMITY_GROUP_H
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 04b5b88ef8..85ef532459 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -506,7 +506,7 @@ int Skeleton3D::get_bone_axis_forward_enum(int p_bone) {
// Skeleton creation api
void Skeleton3D::add_bone(const String &p_name) {
- ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1);
+ ERR_FAIL_COND(p_name.is_empty() || p_name.find(":") != -1 || p_name.find("/") != -1);
for (int i = 0; i < bones.size(); i++) {
ERR_FAIL_COND(bones[i].name == p_name);
diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp
index 5546b88fb1..d9907430fc 100644
--- a/scene/3d/soft_dynamic_body_3d.cpp
+++ b/scene/3d/soft_dynamic_body_3d.cpp
@@ -100,12 +100,11 @@ SoftDynamicBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
offset = obj_tocopy.offset;
}
-SoftDynamicBody3D::PinnedPoint &SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
+void SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
point_index = obj.point_index;
spatial_attachment_path = obj.spatial_attachment_path;
spatial_attachment = obj.spatial_attachment;
offset = obj.offset;
- return *this;
}
void SoftDynamicBody3D::_update_pickable() {
diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h
index 57e116aa05..daef9acac0 100644
--- a/scene/3d/soft_dynamic_body_3d.h
+++ b/scene/3d/soft_dynamic_body_3d.h
@@ -80,7 +80,7 @@ public:
PinnedPoint();
PinnedPoint(const PinnedPoint &obj_tocopy);
- PinnedPoint &operator=(const PinnedPoint &obj);
+ void operator=(const PinnedPoint &obj);
};
private:
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 90af70e7c2..09f0187147 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -625,6 +625,7 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
texture->connect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
}
_queue_update();
+ emit_signal(SceneStringNames::get_singleton()->texture_changed);
}
Ref<Texture2D> Sprite3D::get_texture() const {
@@ -780,6 +781,7 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_SIGNAL(MethodInfo("frame_changed"));
+ ADD_SIGNAL(MethodInfo("texture_changed"));
}
Sprite3D::Sprite3D() {
@@ -996,13 +998,13 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
}
property.hint_string += String(E->get());
- if (animation == E) {
+ if (animation == E->get()) {
current_found = true;
}
}
if (!current_found) {
- if (property.hint_string == String()) {
+ if (property.hint_string.is_empty()) {
property.hint_string = String(animation);
} else {
property.hint_string = String(animation) + "," + property.hint_string;
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index 26fa43b969..4eeb987dde 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -133,8 +133,8 @@ Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
TypedArray<String> WorldEnvironment::get_configuration_warnings() const {
TypedArray<String> warnings = Node::get_configuration_warnings();
- if (!environment.is_valid()) {
- warnings.push_back(TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect."));
+ if (!environment.is_valid() && !camera_effects.is_valid()) {
+ warnings.push_back(TTR("To have any visible effect, WorldEnvironment requires its \"Environment\" property to contain an Environment, its \"Camera Effects\" property to contain a CameraEffects resource, or both."));
}
if (!is_inside_tree()) {
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index d6c5d0b51c..8f644face5 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -57,7 +57,7 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
}
anims += String(names[i]);
}
- if (anims != String()) {
+ if (!anims.is_empty()) {
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = anims;
}
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index c8fa8bf395..31a1d4d64c 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -52,7 +52,7 @@ void AnimationNodeStateMachineTransition::set_advance_condition(const StringName
String cs = p_condition;
ERR_FAIL_COND(cs.find("/") != -1 || cs.find(":") != -1);
advance_condition = p_condition;
- if (cs != String()) {
+ if (!cs.is_empty()) {
advance_condition_name = "conditions/" + cs;
} else {
advance_condition_name = StringName();
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 93339711bd..c4cb800c24 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -736,7 +736,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
ba->bezier_accum = bezier;
ba->accum_pass = accum_pass;
} else {
- ba->bezier_accum = Math::lerp(ba->bezier_accum, bezier, p_interp);
+ ba->bezier_accum = Math::lerp(ba->bezier_accum, (float)bezier, p_interp);
}
} break;
@@ -1416,7 +1416,7 @@ bool AnimationPlayer::is_playing() const {
}
void AnimationPlayer::set_current_animation(const String &p_anim) {
- if (p_anim == "[stop]" || p_anim == "") {
+ if (p_anim == "[stop]" || p_anim.is_empty()) {
stop();
} else if (!is_playing() || playback.assigned != p_anim) {
play(p_anim);
@@ -1754,7 +1754,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o
Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) {
ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>());
- Ref<Animation> reset_anim = animation_set["RESET"].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>());
Node *root_node = get_node_or_null(root);
@@ -1762,8 +1762,8 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) {
AnimationPlayer *aux_player = memnew(AnimationPlayer);
EditorNode::get_singleton()->add_child(aux_player);
- aux_player->add_animation("RESET", reset_anim);
- aux_player->set_assigned_animation("RESET");
+ aux_player->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim);
+ aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET);
// Forcing the use of the original root because the scene where original player belongs may be not the active one
Node *root = get_node(get_root());
Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root);
@@ -1785,7 +1785,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) {
}
bool AnimationPlayer::can_apply_reset() const {
- return has_animation("RESET") && playback.assigned != StringName("RESET");
+ return has_animation(SceneStringNames::get_singleton()->RESET) && playback.assigned != SceneStringNames::get_singleton()->RESET;
}
#endif
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index ea04918988..1b07c086c0 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -198,7 +198,7 @@ private:
struct PlaybackData {
AnimationData *from = nullptr;
- float pos = 0.0;
+ double pos = 0.0;
float speed_scale = 1.0;
};
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 57c615a6ab..1d4b5ebf06 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -138,7 +138,7 @@ real_t AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode
void AnimationNode::make_invalid(const String &p_reason) {
ERR_FAIL_COND(!state);
state->valid = false;
- if (state->invalid_reasons != String()) {
+ if (!state->invalid_reasons.is_empty()) {
state->invalid_reasons += "\n";
}
state->invalid_reasons += String::utf8("• ") + p_reason;
@@ -1239,8 +1239,7 @@ void AnimationTree::_process_graph(real_t p_delta) {
continue;
}
- t->value = Math::lerp(t->value, value, blend);
-
+ t->value = Math::lerp(t->value, value, (float)blend);
#endif // _3D_DISABLED
} break;
case Animation::TYPE_VALUE: {
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index 3c8949ddfb..e1594384d5 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -226,7 +226,7 @@ void SceneDebugger::add_to_cache(const String &p_filename, Node *p_node) {
return;
}
- if (EngineDebugger::get_script_debugger() && p_filename != String()) {
+ if (EngineDebugger::get_script_debugger() && !p_filename.is_empty()) {
debugger->live_scene_edit_cache[p_filename].insert(p_node);
}
}
@@ -367,7 +367,7 @@ void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) {
PropertyHint hint = pi.hint;
String hint_string = pi.hint_string;
- if (!res.is_null()) {
+ if (!res.is_null() && !res->get_path().is_empty()) {
var = res->get_path();
} else { //only send information that can be sent..
int len = 0; //test how big is this to encode
diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp
index fb6fa9dec9..9526c5e793 100644
--- a/scene/gui/aspect_ratio_container.cpp
+++ b/scene/gui/aspect_ratio_container.cpp
@@ -60,12 +60,12 @@ void AspectRatioContainer::set_stretch_mode(StretchMode p_mode) {
queue_sort();
}
-void AspectRatioContainer::set_alignment_horizontal(AlignMode p_alignment_horizontal) {
+void AspectRatioContainer::set_alignment_horizontal(AlignmentMode p_alignment_horizontal) {
alignment_horizontal = p_alignment_horizontal;
queue_sort();
}
-void AspectRatioContainer::set_alignment_vertical(AlignMode p_alignment_vertical) {
+void AspectRatioContainer::set_alignment_vertical(AlignmentMode p_alignment_vertical) {
alignment_vertical = p_alignment_vertical;
queue_sort();
}
@@ -107,25 +107,25 @@ void AspectRatioContainer::_notification(int p_what) {
float align_x = 0.5;
switch (alignment_horizontal) {
- case ALIGN_BEGIN: {
+ case ALIGNMENT_BEGIN: {
align_x = 0.0;
} break;
- case ALIGN_CENTER: {
+ case ALIGNMENT_CENTER: {
align_x = 0.5;
} break;
- case ALIGN_END: {
+ case ALIGNMENT_END: {
align_x = 1.0;
} break;
}
float align_y = 0.5;
switch (alignment_vertical) {
- case ALIGN_BEGIN: {
+ case ALIGNMENT_BEGIN: {
align_y = 0.0;
} break;
- case ALIGN_CENTER: {
+ case ALIGNMENT_CENTER: {
align_y = 0.5;
} break;
- case ALIGN_END: {
+ case ALIGNMENT_END: {
align_y = 1.0;
} break;
}
@@ -166,7 +166,7 @@ void AspectRatioContainer::_bind_methods() {
BIND_ENUM_CONSTANT(STRETCH_FIT);
BIND_ENUM_CONSTANT(STRETCH_COVER);
- BIND_ENUM_CONSTANT(ALIGN_BEGIN);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_END);
+ BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN);
+ BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
+ BIND_ENUM_CONSTANT(ALIGNMENT_END);
}
diff --git a/scene/gui/aspect_ratio_container.h b/scene/gui/aspect_ratio_container.h
index c95c6a7274..3cdfc75734 100644
--- a/scene/gui/aspect_ratio_container.h
+++ b/scene/gui/aspect_ratio_container.h
@@ -48,17 +48,17 @@ public:
STRETCH_FIT,
STRETCH_COVER,
};
- enum AlignMode {
- ALIGN_BEGIN,
- ALIGN_CENTER,
- ALIGN_END,
+ enum AlignmentMode {
+ ALIGNMENT_BEGIN,
+ ALIGNMENT_CENTER,
+ ALIGNMENT_END,
};
private:
float ratio = 1.0;
StretchMode stretch_mode = STRETCH_FIT;
- AlignMode alignment_horizontal = ALIGN_CENTER;
- AlignMode alignment_vertical = ALIGN_CENTER;
+ AlignmentMode alignment_horizontal = ALIGNMENT_CENTER;
+ AlignmentMode alignment_vertical = ALIGNMENT_CENTER;
public:
void set_ratio(float p_ratio);
@@ -67,14 +67,14 @@ public:
void set_stretch_mode(StretchMode p_mode);
StretchMode get_stretch_mode() const { return stretch_mode; }
- void set_alignment_horizontal(AlignMode p_alignment_horizontal);
- AlignMode get_alignment_horizontal() const { return alignment_horizontal; }
+ void set_alignment_horizontal(AlignmentMode p_alignment_horizontal);
+ AlignmentMode get_alignment_horizontal() const { return alignment_horizontal; }
- void set_alignment_vertical(AlignMode p_alignment_vertical);
- AlignMode get_alignment_vertical() const { return alignment_vertical; }
+ void set_alignment_vertical(AlignmentMode p_alignment_vertical);
+ AlignmentMode get_alignment_vertical() const { return alignment_vertical; }
};
VARIANT_ENUM_CAST(AspectRatioContainer::StretchMode);
-VARIANT_ENUM_CAST(AspectRatioContainer::AlignMode);
+VARIANT_ENUM_CAST(AspectRatioContainer::AlignmentMode);
#endif // ASPECT_RATIO_CONTAINER_H
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 9f712ed478..f4de48689e 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -355,7 +355,7 @@ String BaseButton::get_tooltip(const Point2 &p_pos) const {
String tooltip = Control::get_tooltip(p_pos);
if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->has_valid_event()) {
String text = shortcut->get_name() + " (" + shortcut->get_as_text() + ")";
- if (tooltip != String() && shortcut->get_name().nocasecmp_to(tooltip) != 0) {
+ if (!tooltip.is_empty() && shortcut->get_name().nocasecmp_to(tooltip) != 0) {
text += "\n" + tooltip;
}
tooltip = text;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index cb9f13e970..fc05d51937 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -154,29 +154,29 @@ void BoxContainer::_resort() {
int ofs = 0;
if (!has_stretched) {
if (!vertical) {
- switch (align) {
- case ALIGN_BEGIN:
+ switch (alignment) {
+ case ALIGNMENT_BEGIN:
if (rtl) {
ofs = stretch_diff;
}
break;
- case ALIGN_CENTER:
+ case ALIGNMENT_CENTER:
ofs = stretch_diff / 2;
break;
- case ALIGN_END:
+ case ALIGNMENT_END:
if (!rtl) {
ofs = stretch_diff;
}
break;
}
} else {
- switch (align) {
- case ALIGN_BEGIN:
+ switch (alignment) {
+ case ALIGNMENT_BEGIN:
break;
- case ALIGN_CENTER:
+ case ALIGNMENT_CENTER:
ofs = stretch_diff / 2;
break;
- case ALIGN_END:
+ case ALIGNMENT_END:
ofs = stretch_diff;
break;
}
@@ -295,7 +295,7 @@ void BoxContainer::_notification(int p_what) {
_resort();
} break;
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
} break;
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
@@ -304,13 +304,13 @@ void BoxContainer::_notification(int p_what) {
}
}
-void BoxContainer::set_alignment(AlignMode p_align) {
- align = p_align;
+void BoxContainer::set_alignment(AlignmentMode p_alignment) {
+ alignment = p_alignment;
_resort();
}
-BoxContainer::AlignMode BoxContainer::get_alignment() const {
- return align;
+BoxContainer::AlignmentMode BoxContainer::get_alignment() const {
+ return alignment;
}
Control *BoxContainer::add_spacer(bool p_begin) {
@@ -340,9 +340,9 @@ void BoxContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment);
ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &BoxContainer::set_alignment);
- BIND_ENUM_CONSTANT(ALIGN_BEGIN);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_END);
+ BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN);
+ BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
+ BIND_ENUM_CONSTANT(ALIGNMENT_END);
ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment", "get_alignment");
}
diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h
index 23feea565c..9bb26ec32c 100644
--- a/scene/gui/box_container.h
+++ b/scene/gui/box_container.h
@@ -37,15 +37,15 @@ class BoxContainer : public Container {
GDCLASS(BoxContainer, Container);
public:
- enum AlignMode {
- ALIGN_BEGIN,
- ALIGN_CENTER,
- ALIGN_END
+ enum AlignmentMode {
+ ALIGNMENT_BEGIN,
+ ALIGNMENT_CENTER,
+ ALIGNMENT_END
};
private:
bool vertical = false;
- AlignMode align = ALIGN_BEGIN;
+ AlignmentMode alignment = ALIGNMENT_BEGIN;
void _resort();
@@ -57,8 +57,8 @@ protected:
public:
Control *add_spacer(bool p_begin = false);
- void set_alignment(AlignMode p_align);
- AlignMode get_alignment() const;
+ void set_alignment(AlignmentMode p_alignment);
+ AlignmentMode get_alignment() const;
virtual Size2 get_minimum_size() const override;
@@ -84,6 +84,6 @@ public:
BoxContainer(true) {}
};
-VARIANT_ENUM_CAST(BoxContainer::AlignMode);
+VARIANT_ENUM_CAST(BoxContainer::AlignmentMode);
#endif // BOX_CONTAINER_H
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 9818c8f0cc..8bb41e7abf 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -50,9 +50,9 @@ Size2 Button::get_minimum_size() const {
if (!_icon.is_null()) {
minsize.height = MAX(minsize.height, _icon->get_height());
- if (icon_align != ALIGN_CENTER) {
+ if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) {
minsize.width += _icon->get_width();
- if (xl_text != "") {
+ if (!xl_text.is_empty()) {
minsize.width += get_theme_constant(SNAME("hseparation"));
}
} else {
@@ -82,13 +82,13 @@ void Button::_notification(int p_what) {
xl_text = atr(text);
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_THEME_CHANGED: {
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_DRAW: {
@@ -216,19 +216,19 @@ void Button::_notification(int p_what) {
}
Rect2 icon_region = Rect2();
- TextAlign icon_align_rtl_checked = icon_align;
- TextAlign align_rtl_checked = align;
+ HorizontalAlignment icon_align_rtl_checked = icon_alignment;
+ HorizontalAlignment align_rtl_checked = alignment;
// Swap icon and text alignment sides if right-to-left layout is set.
if (rtl) {
- if (icon_align == ALIGN_RIGHT) {
- icon_align_rtl_checked = ALIGN_LEFT;
- } else if (icon_align == ALIGN_LEFT) {
- icon_align_rtl_checked = ALIGN_RIGHT;
+ if (icon_alignment == HORIZONTAL_ALIGNMENT_RIGHT) {
+ icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT;
+ } else if (icon_alignment == HORIZONTAL_ALIGNMENT_LEFT) {
+ icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT;
}
- if (align == ALIGN_RIGHT) {
- align_rtl_checked = ALIGN_LEFT;
- } else if (align == ALIGN_LEFT) {
- align_rtl_checked = ALIGN_RIGHT;
+ if (alignment == HORIZONTAL_ALIGNMENT_RIGHT) {
+ align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT;
+ } else if (alignment == HORIZONTAL_ALIGNMENT_LEFT) {
+ align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT;
}
}
if (!_icon.is_null()) {
@@ -240,14 +240,14 @@ void Button::_notification(int p_what) {
float icon_ofs_region = 0.0;
Point2 style_offset;
Size2 icon_size = _icon->get_size();
- if (icon_align_rtl_checked == ALIGN_LEFT) {
+ if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) {
style_offset.x = style->get_margin(SIDE_LEFT);
if (_internal_margin[SIDE_LEFT] > 0) {
icon_ofs_region = _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("hseparation"));
}
- } else if (icon_align_rtl_checked == ALIGN_CENTER) {
+ } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) {
style_offset.x = 0.0;
- } else if (icon_align_rtl_checked == ALIGN_RIGHT) {
+ } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_RIGHT) {
style_offset.x = -style->get_margin(SIDE_RIGHT);
if (_internal_margin[SIDE_RIGHT] > 0) {
icon_ofs_region = -_internal_margin[SIDE_RIGHT] - get_theme_constant(SNAME("hseparation"));
@@ -258,7 +258,7 @@ void Button::_notification(int p_what) {
if (expand_icon) {
Size2 _size = get_size() - style->get_offset() * 2;
_size.width -= get_theme_constant(SNAME("hseparation")) + icon_ofs_region;
- if (!clip_text && icon_align_rtl_checked != ALIGN_CENTER) {
+ if (!clip_text && icon_align_rtl_checked != HORIZONTAL_ALIGNMENT_CENTER) {
_size.width -= text_buf->get_size().width;
}
float icon_width = _icon->get_width() * _size.height / _icon->get_height();
@@ -272,9 +272,9 @@ void Button::_notification(int p_what) {
icon_size = Size2(icon_width, icon_height);
}
- if (icon_align_rtl_checked == ALIGN_LEFT) {
+ if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) {
icon_region = Rect2(style_offset + Point2(icon_ofs_region, Math::floor((valign - icon_size.y) * 0.5)), icon_size);
- } else if (icon_align_rtl_checked == ALIGN_CENTER) {
+ } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) {
icon_region = Rect2(style_offset + Point2(icon_ofs_region + Math::floor((size.x - icon_size.x) * 0.5), Math::floor((valign - icon_size.y) * 0.5)), icon_size);
} else {
icon_region = Rect2(style_offset + Point2(icon_ofs_region + size.x - icon_size.x, Math::floor((valign - icon_size.y) * 0.5)), icon_size);
@@ -286,7 +286,7 @@ void Button::_notification(int p_what) {
}
Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + get_theme_constant(SNAME("hseparation")), 0) : Point2();
- if (align_rtl_checked == ALIGN_CENTER && icon_align_rtl_checked == ALIGN_CENTER) {
+ if (align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER && icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) {
icon_ofs.x = 0.0;
}
int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width;
@@ -304,8 +304,9 @@ void Button::_notification(int p_what) {
Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - text_buf->get_size() - Point2(_internal_margin[SIDE_RIGHT] - _internal_margin[SIDE_LEFT], 0)) / 2.0;
switch (align_rtl_checked) {
- case ALIGN_LEFT: {
- if (icon_align_rtl_checked != ALIGN_LEFT) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
+ if (icon_align_rtl_checked != HORIZONTAL_ALIGNMENT_LEFT) {
icon_ofs.x = 0.0;
}
if (_internal_margin[SIDE_LEFT] > 0) {
@@ -315,23 +316,23 @@ void Button::_notification(int p_what) {
}
text_ofs.y += style->get_offset().y;
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (text_ofs.x < 0) {
text_ofs.x = 0;
}
- if (icon_align_rtl_checked == ALIGN_LEFT) {
+ if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) {
text_ofs += icon_ofs;
}
text_ofs += style->get_offset();
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (_internal_margin[SIDE_RIGHT] > 0) {
text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width - _internal_margin[SIDE_RIGHT] - get_theme_constant(SNAME("hseparation"));
} else {
text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width;
}
text_ofs.y += style->get_offset().y;
- if (icon_align_rtl_checked == ALIGN_RIGHT) {
+ if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_RIGHT) {
text_ofs.x -= icon_ofs.x;
}
} break;
@@ -358,7 +359,7 @@ void Button::_shape() {
} else {
text_buf->set_direction((TextServer::Direction)text_direction);
}
- text_buf->add_string(xl_text, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
}
void Button::set_text(const String &p_text) {
@@ -368,7 +369,7 @@ void Button::set_text(const String &p_text) {
_shape();
update();
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -428,7 +429,7 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) {
if (icon != p_icon) {
icon = p_icon;
update();
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -440,7 +441,7 @@ void Button::set_expand_icon(bool p_enabled) {
if (expand_icon != p_enabled) {
expand_icon = p_enabled;
update();
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -463,7 +464,7 @@ void Button::set_clip_text(bool p_enabled) {
if (clip_text != p_enabled) {
clip_text = p_enabled;
update();
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -471,25 +472,25 @@ bool Button::get_clip_text() const {
return clip_text;
}
-void Button::set_text_align(TextAlign p_align) {
- if (align != p_align) {
- align = p_align;
+void Button::set_text_alignment(HorizontalAlignment p_alignment) {
+ if (alignment != p_alignment) {
+ alignment = p_alignment;
update();
}
}
-Button::TextAlign Button::get_text_align() const {
- return align;
+HorizontalAlignment Button::get_text_alignment() const {
+ return alignment;
}
-void Button::set_icon_align(TextAlign p_align) {
- icon_align = p_align;
- minimum_size_changed();
+void Button::set_icon_alignment(HorizontalAlignment p_alignment) {
+ icon_alignment = p_alignment;
+ update_minimum_size();
update();
}
-Button::TextAlign Button::get_icon_align() const {
- return icon_align;
+HorizontalAlignment Button::get_icon_alignment() const {
+ return icon_alignment;
}
bool Button::_set(const StringName &p_name, const Variant &p_value) {
@@ -558,25 +559,21 @@ void Button::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_flat"), &Button::is_flat);
ClassDB::bind_method(D_METHOD("set_clip_text", "enabled"), &Button::set_clip_text);
ClassDB::bind_method(D_METHOD("get_clip_text"), &Button::get_clip_text);
- ClassDB::bind_method(D_METHOD("set_text_align", "align"), &Button::set_text_align);
- ClassDB::bind_method(D_METHOD("get_text_align"), &Button::get_text_align);
- ClassDB::bind_method(D_METHOD("set_icon_align", "icon_align"), &Button::set_icon_align);
- ClassDB::bind_method(D_METHOD("get_icon_align"), &Button::get_icon_align);
+ ClassDB::bind_method(D_METHOD("set_text_alignment", "alignment"), &Button::set_text_alignment);
+ ClassDB::bind_method(D_METHOD("get_text_alignment"), &Button::get_text_alignment);
+ ClassDB::bind_method(D_METHOD("set_icon_alignment", "icon_alignment"), &Button::set_icon_alignment);
+ ClassDB::bind_method(D_METHOD("get_icon_alignment"), &Button::get_icon_alignment);
ClassDB::bind_method(D_METHOD("set_expand_icon", "enabled"), &Button::set_expand_icon);
ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_align", "get_icon_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_alignment", "get_text_alignment");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_alignment", "get_icon_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon");
}
diff --git a/scene/gui/button.h b/scene/gui/button.h
index fd36cb77af..92d86542a6 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -37,13 +37,6 @@
class Button : public BaseButton {
GDCLASS(Button, BaseButton);
-public:
- enum TextAlign {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT
- };
-
private:
bool flat = false;
String text;
@@ -57,8 +50,8 @@ private:
Ref<Texture2D> icon;
bool expand_icon = false;
bool clip_text = false;
- TextAlign align = ALIGN_CENTER;
- TextAlign icon_align = ALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_CENTER;
+ HorizontalAlignment icon_alignment = HORIZONTAL_ALIGNMENT_LEFT;
float _internal_margin[4] = {};
void _shape();
@@ -100,16 +93,14 @@ public:
void set_clip_text(bool p_enabled);
bool get_clip_text() const;
- void set_text_align(TextAlign p_align);
- TextAlign get_text_align() const;
+ void set_text_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_text_alignment() const;
- void set_icon_align(TextAlign p_align);
- TextAlign get_icon_align() const;
+ void set_icon_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_icon_alignment() const;
Button(const String &p_text = String());
~Button();
};
-VARIANT_ENUM_CAST(Button::TextAlign);
-
#endif
diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp
index 909516e7ef..e17552006f 100644
--- a/scene/gui/center_container.cpp
+++ b/scene/gui/center_container.cpp
@@ -61,7 +61,7 @@ void CenterContainer::set_use_top_left(bool p_enable) {
use_top_left = p_enable;
- minimum_size_changed();
+ update_minimum_size();
queue_sort();
}
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 411fb2e1f0..134766b05f 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -123,7 +123,7 @@ CheckBox::CheckBox(const String &p_text) :
Button(p_text) {
set_toggle_mode(true);
- set_text_align(ALIGN_LEFT);
+ set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
if (is_layout_rtl()) {
_set_internal_margin(SIDE_RIGHT, get_icon_size().width);
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index 162a256d23..499bedda52 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -107,7 +107,7 @@ void CheckButton::_notification(int p_what) {
CheckButton::CheckButton() {
set_toggle_mode(true);
- set_text_align(ALIGN_LEFT);
+ set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
if (is_layout_rtl()) {
_set_internal_margin(SIDE_LEFT, get_icon_size().width);
} else {
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 57de75a71d..ba37d51e24 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -170,12 +170,12 @@ void CodeEdit::_notification(int p_what) {
if (code_completion_options[l].default_value.get_type() == Variant::COLOR) {
draw_rect(Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
}
- tl->set_align(HALIGN_RIGHT);
+ tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
} else {
if (code_completion_options[l].default_value.get_type() == Variant::COLOR) {
draw_rect(Rect2(Point2(code_completion_rect.position.x + code_completion_rect.size.width - icon_area_size.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
}
- tl->set_align(HALIGN_LEFT);
+ tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
tl->draw(ci, title_pos, code_completion_options[l].font_color);
}
@@ -189,7 +189,7 @@ void CodeEdit::_notification(int p_what) {
}
/* Code hint */
- if (caret_visible && code_hint != "" && (!code_completion_active || (code_completion_below != code_hint_draw_below))) {
+ if (caret_visible && !code_hint.is_empty() && (!code_completion_active || (code_completion_below != code_hint_draw_below))) {
const int font_height = font->get_height(font_size);
Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel"));
Color font_color = get_theme_color(SNAME("font_color"), SNAME("TooltipLabel"));
@@ -229,7 +229,7 @@ void CodeEdit::_notification(int p_what) {
Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent(font_size) + font_height * i + yofs);
round_ofs = round_ofs.round();
- draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HALIGN_LEFT, -1, font_size, font_color);
+ draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
if (end > 0) {
// Draw an underline for the currently edited function parameter.
const Vector2 b = hint_ofs + sb->get_offset() + Vector2(begin, font_height + font_height * i + yofs);
@@ -315,7 +315,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
if (mb->get_button_index() == MouseButton::LEFT) {
- if (mb->is_command_pressed() && symbol_lookup_word != String()) {
+ if (mb->is_command_pressed() && !symbol_lookup_word.is_empty()) {
Vector2i mpos = mb->get_position();
if (is_layout_rtl()) {
mpos.x = get_size().x - mpos.x;
@@ -530,7 +530,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
/* General overrides */
Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
- if (symbol_lookup_word != String()) {
+ if (!symbol_lookup_word.is_empty()) {
return CURSOR_POINTING_HAND;
}
@@ -1419,40 +1419,23 @@ void CodeEdit::fold_line(int p_line) {
/* End line is the same therefore we have a block of single line delimiters. */
if (end_line == p_line) {
for (int i = p_line + 1; i <= line_count; i++) {
- if (i == line_count) {
- end_line = line_count;
- break;
- }
-
if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
- end_line = i - 1;
break;
}
+ end_line = i;
}
}
} else {
int start_indent = get_indent_level(p_line);
for (int i = p_line + 1; i <= line_count; i++) {
- if (get_line(p_line).strip_edges().size() == 0 || is_in_string(i) != -1 || is_in_comment(i) != -1) {
- end_line = i;
+ if (get_line(i).strip_edges().size() == 0) {
continue;
}
-
- if (i == line_count) {
- /* Do not fold empty last line of script if any */
+ if (get_indent_level(i) > start_indent) {
end_line = i;
- if (get_line(i).strip_edges().size() == 0) {
- end_line--;
- }
- break;
+ continue;
}
-
- if ((get_indent_level(i) <= start_indent && get_line(i).strip_edges().size() != 0)) {
- /* Keep an empty line unfolded if any */
- end_line = i - 1;
- if (get_line(i - 1).strip_edges().size() == 0 && i - 2 > p_line) {
- end_line = i - 2;
- }
+ if (is_in_string(i) == -1 && is_in_comment(i) == -1) {
break;
}
}
@@ -2614,7 +2597,7 @@ void CodeEdit::_add_delimiter(const String &p_start_key, const String &p_end_key
delimiter.type = p_type;
delimiter.start_key = p_start_key;
delimiter.end_key = p_end_key;
- delimiter.line_only = p_line_only || p_end_key == "";
+ delimiter.line_only = p_line_only || p_end_key.is_empty();
delimiters.insert(at, delimiter);
if (!setting_delimiters) {
delimiter_cache.clear();
@@ -2664,7 +2647,7 @@ void CodeEdit::_set_delimiters(const TypedArray<String> &p_delimiters, Delimiter
const String start_key = key.get_slice(" ", 0);
const String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String();
- _add_delimiter(start_key, end_key, end_key == "", p_type);
+ _add_delimiter(start_key, end_key, end_key.is_empty(), p_type);
}
setting_delimiters = false;
_update_delimiter_cache();
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 5a378554c9..63ffe7bf95 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -1274,7 +1274,7 @@ ColorPicker::ColorPicker() :
preset_container->set_columns(preset_column_count);
add_child(preset_container, false, INTERNAL_MODE_FRONT);
- btn_add_preset->set_icon_align(Button::ALIGN_CENTER);
+ btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
btn_add_preset->set_tooltip(RTR("Add current color as a preset."));
btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
preset_container->add_child(btn_add_preset);
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index a1bd82f6f7..81afa53d85 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -35,7 +35,7 @@
void Container::_child_minsize_changed() {
//Size2 ms = get_combined_minimum_size();
//if (ms.width > get_size().width || ms.height > get_size().height) {
- minimum_size_changed();
+ update_minimum_size();
queue_sort();
}
@@ -51,7 +51,7 @@ void Container::add_child_notify(Node *p_child) {
control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed));
control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed));
- minimum_size_changed();
+ update_minimum_size();
queue_sort();
}
@@ -62,7 +62,7 @@ void Container::move_child_notify(Node *p_child) {
return;
}
- minimum_size_changed();
+ update_minimum_size();
queue_sort();
}
@@ -78,7 +78,7 @@ void Container::remove_child_notify(Node *p_child) {
control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed));
control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed));
- minimum_size_changed();
+ update_minimum_size();
queue_sort();
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 9f715be155..1fdc30eb6d 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -192,7 +192,7 @@ void Control::set_custom_minimum_size(const Size2 &p_custom) {
return;
}
data.custom_minimum_size = p_custom;
- minimum_size_changed();
+ update_minimum_size();
}
Size2 Control::get_custom_minimum_size() const {
@@ -213,7 +213,7 @@ void Control::_update_minimum_size_cache() {
data.minimum_size_valid = true;
if (size_changed) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -713,7 +713,7 @@ void Control::_notification(int p_notification) {
update();
} break;
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -2534,7 +2534,7 @@ void Control::grab_click_focus() {
get_viewport()->_gui_grab_click_focus(this);
}
-void Control::minimum_size_changed() {
+void Control::update_minimum_size() {
if (!is_inside_tree() || data.block_minimum_size_adjust) {
return;
}
@@ -2597,7 +2597,7 @@ bool Control::is_text_field() const {
return false;
}
-Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const {
+Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String &p_text) const {
Array ret;
switch (p_theme_type) {
case STRUCTURED_TEXT_URI: {
@@ -2696,7 +2696,7 @@ real_t Control::get_rotation() const {
void Control::_override_changed() {
notification(NOTIFICATION_THEME_CHANGED);
emit_signal(SceneStringNames::get_singleton()->theme_changed);
- minimum_size_changed(); // overrides are likely to affect minimum size
+ update_minimum_size(); // Overrides are likely to affect minimum size.
}
void Control::set_pivot_offset(const Vector2 &p_pivot) {
@@ -2791,7 +2791,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
TypedArray<String> Control::get_configuration_warnings() const {
TypedArray<String> warnings = Node::get_configuration_warnings();
- if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
+ if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) {
warnings.push_back(TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."));
}
@@ -2977,7 +2977,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Control::warp_mouse);
- ClassDB::bind_method(D_METHOD("minimum_size_changed"), &Control::minimum_size_changed);
+ ClassDB::bind_method(D_METHOD("update_minimum_size"), &Control::update_minimum_size);
ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Control::set_layout_direction);
ClassDB::bind_method(D_METHOD("get_layout_direction"), &Control::get_layout_direction);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 1a94cc68a6..ae9ca1489a 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -279,7 +279,7 @@ protected:
//virtual void _window_gui_input(InputEvent p_event);
- virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const;
+ virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String &p_text) const;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -441,7 +441,7 @@ public:
void set_stretch_ratio(real_t p_ratio);
real_t get_stretch_ratio() const;
- void minimum_size_changed();
+ void update_minimum_size();
/* FOCUS */
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index f66d3f6835..f1725e57ea 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -242,7 +242,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
hbc->add_spacer(true);
}
- if (p_action != "") {
+ if (!p_action.is_empty()) {
button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action), varray(p_action));
}
@@ -251,7 +251,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
String c = p_cancel;
- if (p_cancel == "") {
+ if (p_cancel.is_empty()) {
c = TTRC("Cancel");
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 44853fc006..08d5df3db8 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -473,6 +473,13 @@ void FileDialog::update_file_list() {
dir_access->list_dir_begin();
+ if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
+ message->hide();
+ } else {
+ message->set_text(TTRC("You don't have permission to access contents of this folder."));
+ message->show();
+ }
+
TreeItem *root = tree->create_item();
Ref<Texture2D> folder = vbox->get_theme_icon(SNAME("folder"), SNAME("FileDialog"));
Ref<Texture2D> file_icon = vbox->get_theme_icon(SNAME("file"), SNAME("FileDialog"));
@@ -482,17 +489,11 @@ void FileDialog::update_file_list() {
List<String> dirs;
bool is_hidden;
- String item;
-
- if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
- message->hide();
- } else {
- message->set_text(TTRC("You don't have permission to access contents of this folder."));
- message->show();
- }
+ String item = dir_access->get_next();
- while ((item = dir_access->get_next()) != "") {
+ while (!item.is_empty()) {
if (item == "." || item == "..") {
+ item = dir_access->get_next();
continue;
}
@@ -505,6 +506,7 @@ void FileDialog::update_file_list() {
dirs.push_back(item);
}
}
+ item = dir_access->get_next();
}
dirs.sort_custom<NaturalNoCaseComparator>();
@@ -998,8 +1000,8 @@ FileDialog::FileDialog() {
message = memnew(Label);
message->hide();
message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- message->set_align(Label::ALIGN_CENTER);
- message->set_valign(Label::VALIGN_CENTER);
+ message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tree->add_child(message);
file_box = memnew(HBoxContainer);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index e7d98a686f..32c62b7226 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1166,7 +1166,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
top_layer->update();
minimap->update();
} else {
- emit_signal(SNAME("popup_request"), b->get_global_position());
+ emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position());
}
}
}
@@ -2312,7 +2312,7 @@ GraphEdit::GraphEdit() {
zoom_hb->add_child(zoom_label);
zoom_label->set_visible(false);
zoom_label->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
- zoom_label->set_align(Label::ALIGN_CENTER);
+ zoom_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
zoom_label->set_custom_minimum_size(Size2(48, 0));
_update_zoom_label();
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index e7094c89b1..7a7b35585e 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -442,7 +442,7 @@ void GraphNode::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
}
@@ -458,7 +458,7 @@ void GraphNode::_shape() {
} else {
title_buf->set_direction((TextServer::Direction)text_direction);
}
- title_buf->add_string(title, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ title_buf->add_string(title, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
}
#ifdef TOOLS_ENABLED
@@ -666,7 +666,7 @@ void GraphNode::set_title(const String &p_title) {
_shape();
update();
- minimum_size_changed();
+ update_minimum_size();
}
String GraphNode::get_title() const {
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 2beb2624d2..624330cdf6 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -182,7 +182,7 @@ void GridContainer::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
} break;
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
@@ -195,7 +195,7 @@ void GridContainer::set_columns(int p_columns) {
ERR_FAIL_COND(p_columns < 1);
columns = p_columns;
queue_sort();
- minimum_size_changed();
+ update_minimum_size();
}
int GridContainer::get_columns() const {
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 408ef53e89..6deb39b9e2 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -43,7 +43,7 @@ void ItemList::_shape(int p_idx) {
} else {
item.text_buf->set_direction((TextServer::Direction)item.text_direction);
}
- item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.opentype_features, (item.language != "") ? item.language : TranslationServer::get_singleton()->get_tool_locale());
+ item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.opentype_features, (!item.language.is_empty()) ? item.language : TranslationServer::get_singleton()->get_tool_locale());
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
item.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
} else {
@@ -653,7 +653,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
if (p_event->is_pressed() && items.size() > 0) {
if (p_event->is_action("ui_up")) {
- if (search_string != "") {
+ if (!search_string.is_empty()) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
@@ -683,7 +683,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
accept_event();
}
} else if (p_event->is_action("ui_down")) {
- if (search_string != "") {
+ if (!search_string.is_empty()) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
@@ -920,7 +920,7 @@ void ItemList::_notification(int p_what) {
minsize = items[i].get_icon_size() * icon_scale;
}
- if (items[i].text != "") {
+ if (!items[i].text.is_empty()) {
if (icon_mode == ICON_MODE_TOP) {
minsize.y += icon_margin;
} else {
@@ -929,7 +929,7 @@ void ItemList::_notification(int p_what) {
}
}
- if (items[i].text != "") {
+ if (!items[i].text.is_empty()) {
int max_width = -1;
if (fixed_column_width) {
max_width = fixed_column_width;
@@ -1037,7 +1037,7 @@ void ItemList::_notification(int p_what) {
}
}
- minimum_size_changed();
+ update_minimum_size();
shape_changed = false;
}
@@ -1188,7 +1188,7 @@ void ItemList::_notification(int p_what) {
draw_texture(items[i].tag_icon, draw_pos + base_ofs);
}
- if (items[i].text != "") {
+ if (!items[i].text.is_empty()) {
int max_len = -1;
Vector2 size2 = items[i].text_buf->get_size();
@@ -1213,7 +1213,7 @@ void ItemList::_notification(int p_what) {
text_ofs.x = size.width - text_ofs.x - max_len;
}
- items.write[i].text_buf->set_align(HALIGN_CENTER);
+ items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_CENTER);
if (outline_size > 0 && font_outline_color.a > 0) {
items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color);
@@ -1241,9 +1241,9 @@ void ItemList::_notification(int p_what) {
items.write[i].text_buf->set_width(max_len);
if (rtl) {
- items.write[i].text_buf->set_align(HALIGN_RIGHT);
+ items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
} else {
- items.write[i].text_buf->set_align(HALIGN_LEFT);
+ items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
if (outline_size > 0 && font_outline_color.a > 0) {
@@ -1360,10 +1360,10 @@ String ItemList::get_tooltip(const Point2 &p_pos) const {
if (!items[closest].tooltip_enabled) {
return "";
}
- if (items[closest].tooltip != "") {
+ if (!items[closest].tooltip.is_empty()) {
return items[closest].tooltip;
}
- if (items[closest].text != "") {
+ if (!items[closest].text.is_empty()) {
return items[closest].text;
}
}
@@ -1663,7 +1663,7 @@ void ItemList::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
- ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_");
+ ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_");
ADD_GROUP("Columns", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width");
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 50908f6a77..0a09d87509 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -44,7 +44,7 @@ void Label::set_autowrap_mode(Label::AutowrapMode p_mode) {
update();
if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -96,7 +96,7 @@ void Label::_shape() {
if (visible_chars >= 0) {
text = text.substr(0, visible_chars);
}
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text));
dirty = false;
lines_dirty = true;
@@ -175,7 +175,7 @@ void Label::_shape() {
if (lines_hidden) {
overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
}
- if (align == ALIGN_FILL) {
+ if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
for (int i = 0; i < lines_rid.size(); i++) {
if (i < visible_lines - 1 || lines_rid.size() == 1) {
TS->shaped_text_fit_to_width(lines_rid[i], width);
@@ -191,7 +191,7 @@ void Label::_shape() {
} else {
// Autowrap disabled.
for (int i = 0; i < lines_rid.size(); i++) {
- if (align == ALIGN_FILL) {
+ if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(lines_rid[i], width);
overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
@@ -207,7 +207,7 @@ void Label::_shape() {
_update_visible();
if (autowrap_mode == AUTOWRAP_OFF || !clip || overrun_behavior == OVERRUN_NO_TRIMMING) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -326,21 +326,21 @@ void Label::_notification(int p_what) {
int vbegin = 0, vsep = 0;
if (lines_visible > 0) {
- switch (valign) {
- case VALIGN_TOP: {
+ switch (vertical_alignment) {
+ case VERTICAL_ALIGNMENT_TOP: {
// Nothing.
} break;
- case VALIGN_CENTER: {
+ case VERTICAL_ALIGNMENT_CENTER: {
vbegin = (size.y - (total_h - line_spacing)) / 2;
vsep = 0;
} break;
- case VALIGN_BOTTOM: {
+ case VERTICAL_ALIGNMENT_BOTTOM: {
vbegin = size.y - (total_h - line_spacing);
vsep = 0;
} break;
- case VALIGN_FILL: {
+ case VERTICAL_ALIGNMENT_FILL: {
vbegin = 0;
if (lines_visible > 1) {
vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1);
@@ -358,25 +358,25 @@ void Label::_notification(int p_what) {
Size2 line_size = TS->shaped_text_get_size(lines_rid[i]);
ofs.x = 0;
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP);
- switch (align) {
- case ALIGN_FILL:
+ switch (horizontal_alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
if (rtl && autowrap_mode != AUTOWRAP_OFF) {
ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width);
} else {
ofs.x = style->get_offset().x;
}
break;
- case ALIGN_LEFT: {
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl_layout) {
ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width);
} else {
ofs.x = style->get_offset().x;
}
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
ofs.x = int(size.width - line_size.width) / 2;
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (rtl_layout) {
ofs.x = style->get_offset().x;
} else {
@@ -556,29 +556,29 @@ int Label::get_visible_line_count() const {
return lines_visible;
}
-void Label::set_align(Align p_align) {
- ERR_FAIL_INDEX((int)p_align, 4);
- if (align != p_align) {
- if (align == ALIGN_FILL || p_align == ALIGN_FILL) {
+void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) {
+ ERR_FAIL_INDEX((int)p_alignment, 4);
+ if (horizontal_alignment != p_alignment) {
+ if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
lines_dirty = true; // Reshape lines.
}
- align = p_align;
+ horizontal_alignment = p_alignment;
}
update();
}
-Label::Align Label::get_align() const {
- return align;
+HorizontalAlignment Label::get_horizontal_alignment() const {
+ return horizontal_alignment;
}
-void Label::set_valign(VAlign p_align) {
- ERR_FAIL_INDEX((int)p_align, 4);
- valign = p_align;
+void Label::set_vertical_alignment(VerticalAlignment p_alignment) {
+ ERR_FAIL_INDEX((int)p_alignment, 4);
+ vertical_alignment = p_alignment;
update();
}
-Label::VAlign Label::get_valign() const {
- return valign;
+VerticalAlignment Label::get_vertical_alignment() const {
+ return vertical_alignment;
}
void Label::set_text(const String &p_string) {
@@ -592,7 +592,7 @@ void Label::set_text(const String &p_string) {
visible_chars = get_total_character_count() * percent_visible;
}
update();
- minimum_size_changed();
+ update_minimum_size();
}
void Label::set_text_direction(Control::TextDirection p_text_direction) {
@@ -668,7 +668,7 @@ String Label::get_language() const {
void Label::set_clip_text(bool p_clip) {
clip = p_clip;
update();
- minimum_size_changed();
+ update_minimum_size();
}
bool Label::is_clipping_text() const {
@@ -682,7 +682,7 @@ void Label::set_text_overrun_behavior(Label::OverrunBehavior p_behavior) {
}
update();
if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -809,10 +809,10 @@ void Label::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Label::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_align", "align"), &Label::set_align);
- ClassDB::bind_method(D_METHOD("get_align"), &Label::get_align);
- ClassDB::bind_method(D_METHOD("set_valign", "valign"), &Label::set_valign);
- ClassDB::bind_method(D_METHOD("get_valign"), &Label::get_valign);
+ ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label::set_horizontal_alignment);
+ ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &Label::get_horizontal_alignment);
+ ClassDB::bind_method(D_METHOD("set_vertical_alignment", "alignment"), &Label::set_vertical_alignment);
+ ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment);
ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
@@ -847,16 +847,6 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override_options", "args"), &Label::set_structured_text_bidi_override_options);
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options);
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
- BIND_ENUM_CONSTANT(ALIGN_FILL);
-
- BIND_ENUM_CONSTANT(VALIGN_TOP);
- BIND_ENUM_CONSTANT(VALIGN_CENTER);
- BIND_ENUM_CONSTANT(VALIGN_BOTTOM);
- BIND_ENUM_CONSTANT(VALIGN_FILL);
-
BIND_ENUM_CONSTANT(AUTOWRAP_OFF);
BIND_ENUM_CONSTANT(AUTOWRAP_ARBITRARY);
BIND_ENUM_CONSTANT(AUTOWRAP_WORD);
@@ -869,10 +859,11 @@ void Label::_bind_methods() {
BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ELLIPSIS);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
+ ADD_GROUP("Locale", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
diff --git a/scene/gui/label.h b/scene/gui/label.h
index 8b48eb9670..2ad8ae8818 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -37,20 +37,6 @@ class Label : public Control {
GDCLASS(Label, Control);
public:
- enum Align {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_FILL
- };
-
- enum VAlign {
- VALIGN_TOP,
- VALIGN_CENTER,
- VALIGN_BOTTOM,
- VALIGN_FILL
- };
-
enum AutowrapMode {
AUTOWRAP_OFF,
AUTOWRAP_ARBITRARY,
@@ -67,8 +53,8 @@ public:
};
private:
- Align align = ALIGN_LEFT;
- VAlign valign = VALIGN_TOP;
+ HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT;
+ VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_TOP;
String text;
String xl_text;
AutowrapMode autowrap_mode = AUTOWRAP_OFF;
@@ -109,11 +95,11 @@ protected:
public:
virtual Size2 get_minimum_size() const override;
- void set_align(Align p_align);
- Align get_align() const;
+ void set_horizontal_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_horizontal_alignment() const;
- void set_valign(VAlign p_align);
- VAlign get_valign() const;
+ void set_vertical_alignment(VerticalAlignment p_alignment);
+ VerticalAlignment get_vertical_alignment() const;
void set_text(const String &p_string);
String get_text() const;
@@ -167,8 +153,6 @@ public:
~Label();
};
-VARIANT_ENUM_CAST(Label::Align);
-VARIANT_ENUM_CAST(Label::VAlign);
VARIANT_ENUM_CAST(Label::AutowrapMode);
VARIANT_ENUM_CAST(Label::OverrunBehavior);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 69b08fda3c..810781995e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -227,7 +227,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
}
if (b->is_pressed() && b->get_button_index() == MouseButton::RIGHT && context_menu_enabled) {
_ensure_menu();
- menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
+ menu->set_position(get_screen_position() + get_local_mouse_position());
menu->reset_size();
menu->popup();
grab_focus();
@@ -322,7 +322,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
deselect();
selection.start_column = caret_column;
selection.creating = true;
- } else if (selection.enabled) {
+ } else if (selection.enabled && !selection.double_click) {
selection.drag_attempt = true;
}
}
@@ -392,7 +392,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
if (k->is_action("ui_menu", true)) {
_ensure_menu();
Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size")))) / 2);
- menu->set_position(get_global_transform().xform(pos));
+ menu->set_position(get_screen_position() + pos);
menu->reset_size();
menu->popup();
menu->grab_focus();
@@ -548,17 +548,17 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
}
}
-void LineEdit::set_align(Align p_align) {
- ERR_FAIL_INDEX((int)p_align, 4);
- if (align != p_align) {
- align = p_align;
+void LineEdit::set_horizontal_alignment(HorizontalAlignment p_alignment) {
+ ERR_FAIL_INDEX((int)p_alignment, 4);
+ if (alignment != p_alignment) {
+ alignment = p_alignment;
_shape();
}
update();
}
-LineEdit::Align LineEdit::get_align() const {
- return align;
+HorizontalAlignment LineEdit::get_horizontal_alignment() const {
+ return alignment;
}
Variant LineEdit::get_drag_data(const Point2 &p_point) {
@@ -588,13 +588,19 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
if (p_data.get_type() == Variant::STRING && is_editable()) {
set_caret_at_pixel_pos(p_point.x);
int caret_column_tmp = caret_column;
+ bool is_inside_sel = selection.enabled && caret_column >= selection.begin && caret_column <= selection.end;
+ if (Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ is_inside_sel = selection.enabled && caret_column > selection.begin && caret_column < selection.end;
+ }
if (selection.drag_attempt) {
selection.drag_attempt = false;
- if (caret_column < selection.begin || caret_column > selection.end) {
- if (caret_column_tmp > selection.end) {
- caret_column_tmp = caret_column_tmp - (selection.end - selection.begin);
+ if (!is_inside_sel) {
+ if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ if (caret_column_tmp > selection.end) {
+ caret_column_tmp = caret_column_tmp - (selection.end - selection.begin);
+ }
+ selection_delete();
}
- selection_delete();
set_caret_column(caret_column_tmp);
insert_text_at_caret(p_data);
@@ -709,23 +715,23 @@ void LineEdit::_notification(int p_what) {
float text_width = TS->shaped_text_get_size(text_rid).x;
float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
- switch (align) {
- case ALIGN_FILL:
- case ALIGN_LEFT: {
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - style->get_margin(SIDE_RIGHT) - (text_width)));
} else {
x_ofs = style->get_offset().x;
}
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (scroll_offset != 0) {
x_ofs = style->get_offset().x;
} else {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - (text_width)) / 2);
}
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (rtl) {
x_ofs = style->get_offset().x;
} else {
@@ -763,7 +769,7 @@ void LineEdit::_notification(int p_what) {
r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(SIDE_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon);
- if (align == ALIGN_CENTER) {
+ if (alignment == HORIZONTAL_ALIGNMENT_CENTER) {
if (scroll_offset == 0) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2);
}
@@ -975,7 +981,7 @@ void LineEdit::_notification(int p_what) {
if (is_drag_successful()) {
if (selection.drag_attempt) {
selection.drag_attempt = false;
- if (is_editable()) {
+ if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
selection_delete();
} else if (deselect_on_focus_loss_enabled) {
deselect();
@@ -1011,7 +1017,7 @@ void LineEdit::paste_text() {
// Strip escape characters like \n and \t as they can't be displayed on LineEdit.
String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes();
- if (paste_buffer != "") {
+ if (!paste_buffer.is_empty()) {
int prev_len = text.length();
if (selection.enabled) {
selection_delete();
@@ -1109,23 +1115,23 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) {
int x_ofs = 0;
float text_width = TS->shaped_text_get_size(text_rid).x;
- switch (align) {
- case ALIGN_FILL:
- case ALIGN_LEFT: {
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width)));
} else {
x_ofs = style->get_offset().x;
}
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (scroll_offset != 0) {
x_ofs = style->get_offset().x;
} else {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2);
}
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (rtl) {
x_ofs = style->get_offset().x;
} else {
@@ -1138,7 +1144,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) {
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon;
- if (align == ALIGN_CENTER) {
+ if (alignment == HORIZONTAL_ALIGNMENT_CENTER) {
if (scroll_offset == 0) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2);
}
@@ -1157,23 +1163,23 @@ Vector2i LineEdit::get_caret_pixel_pos() {
int x_ofs = 0;
float text_width = TS->shaped_text_get_size(text_rid).x;
- switch (align) {
- case ALIGN_FILL:
- case ALIGN_LEFT: {
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width)));
} else {
x_ofs = style->get_offset().x;
}
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (scroll_offset != 0) {
x_ofs = style->get_offset().x;
} else {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2);
}
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (rtl) {
x_ofs = style->get_offset().x;
} else {
@@ -1186,7 +1192,7 @@ Vector2i LineEdit::get_caret_pixel_pos() {
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon;
- if (align == ALIGN_CENTER) {
+ if (alignment == HORIZONTAL_ALIGNMENT_CENTER) {
if (scroll_offset == 0) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2);
}
@@ -1502,23 +1508,23 @@ void LineEdit::set_caret_column(int p_column) {
int x_ofs = 0;
float text_width = TS->shaped_text_get_size(text_rid).x;
- switch (align) {
- case ALIGN_FILL:
- case ALIGN_LEFT: {
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width)));
} else {
x_ofs = style->get_offset().x;
}
} break;
- case ALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (scroll_offset != 0) {
x_ofs = style->get_offset().x;
} else {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2);
}
} break;
- case ALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (rtl) {
x_ofs = style->get_offset().x;
} else {
@@ -1532,7 +1538,7 @@ void LineEdit::set_caret_column(int p_column) {
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon;
- if (align == ALIGN_CENTER) {
+ if (alignment == HORIZONTAL_ALIGNMENT_CENTER) {
if (scroll_offset == 0) {
x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2);
}
@@ -1712,7 +1718,7 @@ void LineEdit::set_editable(bool p_editable) {
editable = p_editable;
- minimum_size_changed();
+ update_minimum_size();
update();
}
@@ -1942,7 +1948,7 @@ void LineEdit::_editor_settings_changed() {
void LineEdit::set_expand_to_text_length_enabled(bool p_enabled) {
expand_to_text_length = p_enabled;
- minimum_size_changed();
+ update_minimum_size();
set_caret_column(caret_column);
}
@@ -1956,7 +1962,7 @@ void LineEdit::set_clear_button_enabled(bool p_enabled) {
}
clear_button_enabled = p_enabled;
_fit_to_width();
- minimum_size_changed();
+ update_minimum_size();
update();
}
@@ -2017,7 +2023,7 @@ void LineEdit::set_right_icon(const Ref<Texture2D> &p_icon) {
}
right_icon = p_icon;
_fit_to_width();
- minimum_size_changed();
+ update_minimum_size();
update();
}
@@ -2072,7 +2078,7 @@ void LineEdit::_shape() {
const Ref<Font> &font = get_theme_font(SNAME("font"));
int font_size = get_theme_font_size(SNAME("font_size"));
ERR_FAIL_COND(font.is_null());
- TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t));
full_width = TS->shaped_text_get_size(text_rid).x;
@@ -2081,12 +2087,12 @@ void LineEdit::_shape() {
Size2 size = TS->shaped_text_get_size(text_rid);
if ((expand_to_text_length && old_size.x != size.x) || (old_size.y != size.y)) {
- minimum_size_changed();
+ update_minimum_size();
}
}
void LineEdit::_fit_to_width() {
- if (align == ALIGN_FILL) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
int t_width = get_size().width - style->get_margin(SIDE_RIGHT) - style->get_margin(SIDE_LEFT);
bool using_placeholder = text.is_empty() && ime_text.is_empty();
@@ -2212,8 +2218,8 @@ void LineEdit::_validate_property(PropertyInfo &property) const {
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
- ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align);
- ClassDB::bind_method(D_METHOD("get_align"), &LineEdit::get_align);
+ ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &LineEdit::set_horizontal_alignment);
+ ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &LineEdit::get_horizontal_alignment);
ClassDB::bind_method(D_METHOD("clear"), &LineEdit::clear);
ClassDB::bind_method(D_METHOD("select", "from", "to"), &LineEdit::select, DEFVAL(0), DEFVAL(-1));
@@ -2291,11 +2297,6 @@ void LineEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring")));
ADD_SIGNAL(MethodInfo("text_submitted", PropertyInfo(Variant::STRING, "new_text")));
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
- BIND_ENUM_CONSTANT(ALIGN_FILL);
-
BIND_ENUM_CONSTANT(MENU_CUT);
BIND_ENUM_CONSTANT(MENU_COPY);
BIND_ENUM_CONSTANT(MENU_PASTE);
@@ -2327,7 +2328,7 @@ void LineEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_MAX);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret");
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 221dd9eb2e..854e54e8f1 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -38,13 +38,6 @@ class LineEdit : public Control {
GDCLASS(LineEdit, Control);
public:
- enum Align {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_FILL
- };
-
enum MenuItems {
MENU_CUT,
MENU_COPY,
@@ -78,7 +71,7 @@ public:
};
private:
- Align align = ALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
bool editable = false;
bool pass = false;
@@ -218,8 +211,8 @@ protected:
void _validate_property(PropertyInfo &property) const override;
public:
- void set_align(Align p_align);
- Align get_align() const;
+ void set_horizontal_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_horizontal_alignment() const;
virtual Variant get_drag_data(const Point2 &p_point) override;
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
@@ -347,7 +340,6 @@ public:
~LineEdit();
};
-VARIANT_ENUM_CAST(LineEdit::Align);
VARIANT_ENUM_CAST(LineEdit::MenuItems);
#endif
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index c3201186ea..b59f4fb7d4 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -42,7 +42,7 @@ void LinkButton::_shape() {
text_buf->set_direction((TextServer::Direction)text_direction);
}
TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text));
- text_buf->add_string(xl_text, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
}
void LinkButton::set_text(const String &p_text) {
@@ -52,7 +52,7 @@ void LinkButton::set_text(const String &p_text) {
text = p_text;
xl_text = atr(text);
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
}
@@ -149,7 +149,7 @@ void LinkButton::_notification(int p_what) {
xl_text = atr(text);
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
@@ -157,7 +157,7 @@ void LinkButton::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
_shape();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_DRAW: {
diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp
index 50b4d192a9..af239d67ae 100644
--- a/scene/gui/margin_container.cpp
+++ b/scene/gui/margin_container.cpp
@@ -90,7 +90,7 @@ void MarginContainer::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
} break;
}
}
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 39c7b04955..32501b65a0 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -207,7 +207,7 @@ void MenuButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_count"), &MenuButton::get_item_count);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover");
- ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "popup/item_");
+ ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_");
ADD_SIGNAL(MethodInfo("about_to_popup"));
}
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index 8bf25ac915..ea5c82306d 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -97,7 +97,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
if (texture.is_valid())
texture->set_flags(texture->get_flags()&(~Texture::FLAG_REPEAT)); //remove repeat from texture, it looks bad in sprites
*/
- minimum_size_changed();
+ update_minimum_size();
emit_signal(SceneStringNames::get_singleton()->texture_changed);
}
@@ -109,7 +109,7 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
margin[p_side] = p_size;
update();
- minimum_size_changed();
+ update_minimum_size();
}
int NinePatchRect::get_patch_margin(Side p_side) const {
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index dcf3cfeb09..cbbda09261 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -341,7 +341,7 @@ void OptionButton::_bind_methods() {
OptionButton::OptionButton() {
set_toggle_mode(true);
- set_text_align(ALIGN_LEFT);
+ set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
if (is_layout_rtl()) {
if (has_theme_icon(SNAME("arrow"))) {
_set_internal_margin(SIDE_LEFT, Control::get_theme_icon(SNAME("arrow"))->get_width());
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 2e854abb76..a61d77e95c 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -80,7 +80,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
accel_max_w = MAX(accel_w, accel_max_w);
}
- if (items[i].submenu != "") {
+ if (!items[i].submenu.is_empty()) {
size.width += get_theme_icon(SNAME("submenu"))->get_width();
}
@@ -216,7 +216,7 @@ void PopupMenu::_activate_submenu(int p_over) {
submenu_pos.x = this_pos.x + submenu_size.width;
}
- if (submenu_pos.x + submenu_size.width > get_parent_rect().size.width) {
+ if (submenu_pos.x + submenu_size.width > get_parent_rect().position.x + get_parent_rect().size.width) {
submenu_pos.x = this_pos.x - submenu_size.width;
}
@@ -326,13 +326,13 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
set_input_as_handled();
}
} else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
- if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) {
+ if (mouse_over >= 0 && mouse_over < items.size() && !!items[mouse_over].separator && items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) {
_activate_submenu(mouse_over);
set_input_as_handled();
}
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
- if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
+ if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) {
_activate_submenu(mouse_over);
} else {
activate_item(mouse_over);
@@ -371,7 +371,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
// Disable clicks under a time threshold to avoid selection right when opening the popup.
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - popup_time_msec;
- if (diff < 100) {
+ if (diff < 150) {
return;
}
@@ -387,7 +387,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
return;
}
- if (items[over].submenu != "") {
+ if (!items[over].submenu.is_empty()) {
_activate_submenu(over);
return;
}
@@ -419,7 +419,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
return;
}
- if (items[over].submenu != "" && submenu_over != over) {
+ if (!items[over].submenu.is_empty() && submenu_over != over) {
submenu_over = over;
submenu_timer->start();
}
@@ -558,7 +558,7 @@ void PopupMenu::_draw_items() {
if (items[i].separator) {
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
int sep_ofs = Math::floor((h - sep_h) / 2.0);
- if (text != String()) {
+ if (!text.is_empty()) {
int text_size = items[i].text_buf->get_size().width;
int text_center = display_width / 2;
int text_left = text_center - text_size / 2;
@@ -599,7 +599,7 @@ void PopupMenu::_draw_items() {
}
// Submenu arrow on right hand side
- if (items[i].submenu != "") {
+ if (!items[i].submenu.is_empty()) {
if (rtl) {
submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
} else {
@@ -611,7 +611,7 @@ void PopupMenu::_draw_items() {
Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
int outline_size = get_theme_constant(SNAME("outline_size"));
if (items[i].separator) {
- if (text != String()) {
+ if (!text.is_empty()) {
int center = (display_width - items[i].text_buf->get_size().width) / 2;
Vector2 text_pos = Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
if (outline_size > 0 && font_outline_color.a > 0) {
@@ -701,7 +701,7 @@ void PopupMenu::_shape_item(int p_item) {
} else {
items.write[p_item].text_buf->set_direction((TextServer::Direction)items[p_item].text_direction);
}
- items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, (items[p_item].language != "") ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale());
+ items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, !items[p_item].language.is_empty() ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale());
items.write[p_item].accel_text_buf->clear();
items.write[p_item].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
@@ -736,7 +736,7 @@ void PopupMenu::_notification(int p_what) {
grab_focus();
} break;
case NOTIFICATION_WM_MOUSE_EXIT: {
- if (mouse_over >= 0 && (items[mouse_over].submenu == "" || submenu_over != -1)) {
+ if (mouse_over >= 0 && (items[mouse_over].submenu.is_empty() || submenu_over != -1)) {
mouse_over = -1;
control->update();
}
@@ -769,7 +769,7 @@ void PopupMenu::_notification(int p_what) {
}
for (int i = 0; i < items.size(); i++) {
- if (items[i].submenu == "") {
+ if (items[i].submenu.is_empty()) {
continue;
}
@@ -1323,7 +1323,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
return true;
}
- if (items[i].submenu != "") {
+ if (!items[i].submenu.is_empty()) {
Node *n = get_node(items[i].submenu);
if (!n) {
continue;
@@ -1412,7 +1412,7 @@ void PopupMenu::add_separator(const String &p_text, int p_id) {
Item sep;
sep.separator = true;
sep.id = p_id;
- if (p_text != String()) {
+ if (!p_text.is_empty()) {
sep.text = p_text;
sep.xl_text = atr(p_text);
}
@@ -1510,7 +1510,7 @@ void PopupMenu::set_parent_rect(const Rect2 &p_rect) {
void PopupMenu::get_translatable_strings(List<String> *p_strings) const {
for (int i = 0; i < items.size(); i++) {
- if (items[i].xl_text != "") {
+ if (!items[i].xl_text.is_empty()) {
p_strings->push_back(items[i].xl_text);
}
}
@@ -1690,53 +1690,53 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_submenu_item", "label", "submenu", "id"), &PopupMenu::add_submenu_item, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &PopupMenu::set_item_text);
- ClassDB::bind_method(D_METHOD("set_item_text_direction", "idx", "direction"), &PopupMenu::set_item_text_direction);
- ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "idx", "tag", "value"), &PopupMenu::set_item_opentype_feature);
- ClassDB::bind_method(D_METHOD("set_item_language", "idx", "language"), &PopupMenu::set_item_language);
- ClassDB::bind_method(D_METHOD("set_item_icon", "idx", "icon"), &PopupMenu::set_item_icon);
- ClassDB::bind_method(D_METHOD("set_item_checked", "idx", "checked"), &PopupMenu::set_item_checked);
- ClassDB::bind_method(D_METHOD("set_item_id", "idx", "id"), &PopupMenu::set_item_id);
- ClassDB::bind_method(D_METHOD("set_item_accelerator", "idx", "accel"), &PopupMenu::set_item_accelerator);
- ClassDB::bind_method(D_METHOD("set_item_metadata", "idx", "metadata"), &PopupMenu::set_item_metadata);
- ClassDB::bind_method(D_METHOD("set_item_disabled", "idx", "disabled"), &PopupMenu::set_item_disabled);
- ClassDB::bind_method(D_METHOD("set_item_submenu", "idx", "submenu"), &PopupMenu::set_item_submenu);
- ClassDB::bind_method(D_METHOD("set_item_as_separator", "idx", "enable"), &PopupMenu::set_item_as_separator);
- ClassDB::bind_method(D_METHOD("set_item_as_checkable", "idx", "enable"), &PopupMenu::set_item_as_checkable);
- ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "idx", "enable"), &PopupMenu::set_item_as_radio_checkable);
- ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &PopupMenu::set_item_tooltip);
- ClassDB::bind_method(D_METHOD("set_item_shortcut", "idx", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("set_item_multistate", "idx", "state"), &PopupMenu::set_item_multistate);
- ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "idx", "disabled"), &PopupMenu::set_item_shortcut_disabled);
-
- ClassDB::bind_method(D_METHOD("toggle_item_checked", "idx"), &PopupMenu::toggle_item_checked);
- ClassDB::bind_method(D_METHOD("toggle_item_multistate", "idx"), &PopupMenu::toggle_item_multistate);
-
- ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &PopupMenu::get_item_text);
- ClassDB::bind_method(D_METHOD("get_item_text_direction", "idx"), &PopupMenu::get_item_text_direction);
- ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "idx", "tag"), &PopupMenu::get_item_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "idx"), &PopupMenu::clear_item_opentype_features);
- ClassDB::bind_method(D_METHOD("get_item_language", "idx"), &PopupMenu::get_item_language);
- ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &PopupMenu::get_item_icon);
- ClassDB::bind_method(D_METHOD("is_item_checked", "idx"), &PopupMenu::is_item_checked);
- ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &PopupMenu::get_item_id);
+ ClassDB::bind_method(D_METHOD("set_item_text", "index", "text"), &PopupMenu::set_item_text);
+ ClassDB::bind_method(D_METHOD("set_item_text_direction", "index", "direction"), &PopupMenu::set_item_text_direction);
+ ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "index", "tag", "value"), &PopupMenu::set_item_opentype_feature);
+ ClassDB::bind_method(D_METHOD("set_item_language", "index", "language"), &PopupMenu::set_item_language);
+ ClassDB::bind_method(D_METHOD("set_item_icon", "index", "icon"), &PopupMenu::set_item_icon);
+ ClassDB::bind_method(D_METHOD("set_item_checked", "index", "checked"), &PopupMenu::set_item_checked);
+ ClassDB::bind_method(D_METHOD("set_item_id", "index", "id"), &PopupMenu::set_item_id);
+ ClassDB::bind_method(D_METHOD("set_item_accelerator", "index", "accel"), &PopupMenu::set_item_accelerator);
+ ClassDB::bind_method(D_METHOD("set_item_metadata", "index", "metadata"), &PopupMenu::set_item_metadata);
+ ClassDB::bind_method(D_METHOD("set_item_disabled", "index", "disabled"), &PopupMenu::set_item_disabled);
+ ClassDB::bind_method(D_METHOD("set_item_submenu", "index", "submenu"), &PopupMenu::set_item_submenu);
+ ClassDB::bind_method(D_METHOD("set_item_as_separator", "index", "enable"), &PopupMenu::set_item_as_separator);
+ ClassDB::bind_method(D_METHOD("set_item_as_checkable", "index", "enable"), &PopupMenu::set_item_as_checkable);
+ ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "index", "enable"), &PopupMenu::set_item_as_radio_checkable);
+ ClassDB::bind_method(D_METHOD("set_item_tooltip", "index", "tooltip"), &PopupMenu::set_item_tooltip);
+ ClassDB::bind_method(D_METHOD("set_item_shortcut", "index", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("set_item_multistate", "index", "state"), &PopupMenu::set_item_multistate);
+ ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "index", "disabled"), &PopupMenu::set_item_shortcut_disabled);
+
+ ClassDB::bind_method(D_METHOD("toggle_item_checked", "index"), &PopupMenu::toggle_item_checked);
+ ClassDB::bind_method(D_METHOD("toggle_item_multistate", "index"), &PopupMenu::toggle_item_multistate);
+
+ ClassDB::bind_method(D_METHOD("get_item_text", "index"), &PopupMenu::get_item_text);
+ ClassDB::bind_method(D_METHOD("get_item_text_direction", "index"), &PopupMenu::get_item_text_direction);
+ ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "index", "tag"), &PopupMenu::get_item_opentype_feature);
+ ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "index"), &PopupMenu::clear_item_opentype_features);
+ ClassDB::bind_method(D_METHOD("get_item_language", "index"), &PopupMenu::get_item_language);
+ ClassDB::bind_method(D_METHOD("get_item_icon", "index"), &PopupMenu::get_item_icon);
+ ClassDB::bind_method(D_METHOD("is_item_checked", "index"), &PopupMenu::is_item_checked);
+ ClassDB::bind_method(D_METHOD("get_item_id", "index"), &PopupMenu::get_item_id);
ClassDB::bind_method(D_METHOD("get_item_index", "id"), &PopupMenu::get_item_index);
- ClassDB::bind_method(D_METHOD("get_item_accelerator", "idx"), &PopupMenu::get_item_accelerator);
- ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &PopupMenu::get_item_metadata);
- ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &PopupMenu::is_item_disabled);
- ClassDB::bind_method(D_METHOD("get_item_submenu", "idx"), &PopupMenu::get_item_submenu);
- ClassDB::bind_method(D_METHOD("is_item_separator", "idx"), &PopupMenu::is_item_separator);
- ClassDB::bind_method(D_METHOD("is_item_checkable", "idx"), &PopupMenu::is_item_checkable);
- ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "idx"), &PopupMenu::is_item_radio_checkable);
- ClassDB::bind_method(D_METHOD("is_item_shortcut_disabled", "idx"), &PopupMenu::is_item_shortcut_disabled);
- ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &PopupMenu::get_item_tooltip);
- ClassDB::bind_method(D_METHOD("get_item_shortcut", "idx"), &PopupMenu::get_item_shortcut);
+ ClassDB::bind_method(D_METHOD("get_item_accelerator", "index"), &PopupMenu::get_item_accelerator);
+ ClassDB::bind_method(D_METHOD("get_item_metadata", "index"), &PopupMenu::get_item_metadata);
+ ClassDB::bind_method(D_METHOD("is_item_disabled", "index"), &PopupMenu::is_item_disabled);
+ ClassDB::bind_method(D_METHOD("get_item_submenu", "index"), &PopupMenu::get_item_submenu);
+ ClassDB::bind_method(D_METHOD("is_item_separator", "index"), &PopupMenu::is_item_separator);
+ ClassDB::bind_method(D_METHOD("is_item_checkable", "index"), &PopupMenu::is_item_checkable);
+ ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "index"), &PopupMenu::is_item_radio_checkable);
+ ClassDB::bind_method(D_METHOD("is_item_shortcut_disabled", "index"), &PopupMenu::is_item_shortcut_disabled);
+ ClassDB::bind_method(D_METHOD("get_item_tooltip", "index"), &PopupMenu::get_item_tooltip);
+ ClassDB::bind_method(D_METHOD("get_item_shortcut", "index"), &PopupMenu::get_item_shortcut);
ClassDB::bind_method(D_METHOD("get_current_index"), &PopupMenu::get_current_index);
ClassDB::bind_method(D_METHOD("set_item_count", "count"), &PopupMenu::set_item_count);
ClassDB::bind_method(D_METHOD("get_item_count"), &PopupMenu::get_item_count);
- ClassDB::bind_method(D_METHOD("remove_item", "idx"), &PopupMenu::remove_item);
+ ClassDB::bind_method(D_METHOD("remove_item", "index"), &PopupMenu::remove_item);
ClassDB::bind_method(D_METHOD("add_separator", "label", "id"), &PopupMenu::add_separator, DEFVAL(String()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("clear"), &PopupMenu::clear);
@@ -1762,7 +1762,7 @@ void PopupMenu::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search");
- ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_");
+ ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_");
ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("id_focused", PropertyInfo(Variant::INT, "id")));
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index fd19fad667..7ed8056826 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -383,7 +383,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
// Add indent.
l.offset.x = _find_margin(l.from, p_base_font, p_base_font_size);
l.text_buf->set_width(p_width - l.offset.x);
- l.text_buf->set_align((HAlign)_find_align(l.from));
+ l.text_buf->set_alignment(_find_alignment(l.from));
l.text_buf->set_direction(_find_direction(l.from));
if (tab_size > 0) { // Align inline tabs.
@@ -670,7 +670,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
prefix = segment + prefix;
}
}
- if (prefix != "") {
+ if (!prefix.is_empty()) {
Ref<Font> font = _find_font(l.from);
if (font.is_null()) {
font = get_theme_font(SNAME("normal_font"));
@@ -684,13 +684,13 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
if (!lrtl && p_frame == main) { // Skip Scrollbar.
offx -= scroll_w;
}
- font->draw_string(ci, p_ofs + Vector2(p_width - l.offset.x + offx, l.text_buf->get_line_ascent(0)), " " + prefix, HALIGN_LEFT, l.offset.x, font_size, _find_color(l.from, p_base_color));
+ font->draw_string(ci, p_ofs + Vector2(p_width - l.offset.x + offx, l.text_buf->get_line_ascent(0)), " " + prefix, HORIZONTAL_ALIGNMENT_LEFT, l.offset.x, font_size, _find_color(l.from, p_base_color));
} else {
float offx = 0.0f;
if (lrtl && p_frame == main) { // Skip Scrollbar.
offx += scroll_w;
}
- font->draw_string(ci, p_ofs + Vector2(offx, l.text_buf->get_line_ascent(0)), prefix + " ", HALIGN_RIGHT, l.offset.x, font_size, _find_color(l.from, p_base_color));
+ font->draw_string(ci, p_ofs + Vector2(offx, l.text_buf->get_line_ascent(0)), prefix + " ", HORIZONTAL_ALIGNMENT_RIGHT, l.offset.x, font_size, _find_color(l.from, p_base_color));
}
}
@@ -734,17 +734,17 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
// Draw text.
- switch (l.text_buf->get_align()) {
- case HALIGN_FILL:
- case HALIGN_LEFT: {
+ switch (l.text_buf->get_alignment()) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
off.x += width - length;
}
} break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
off.x += Math::floor((width - length) / 2.0);
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (!rtl) {
off.x += width - length;
}
@@ -1214,17 +1214,17 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
}
}
- switch (l.text_buf->get_align()) {
- case HALIGN_FILL:
- case HALIGN_LEFT: {
+ switch (l.text_buf->get_alignment()) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
off.x += width - length;
}
} break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
off.x += Math::floor((width - length) / 2.0);
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (!rtl) {
off.x += width - length;
}
@@ -1423,7 +1423,7 @@ void RichTextLabel::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
- if (text != "") {
+ if (!text.is_empty()) {
set_text(text);
}
@@ -1950,19 +1950,19 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
return margin;
}
-RichTextLabel::Align RichTextLabel::_find_align(Item *p_item) {
+HorizontalAlignment RichTextLabel::_find_alignment(Item *p_item) {
Item *item = p_item;
while (item) {
if (item->type == ITEM_PARAGRAPH) {
ItemParagraph *p = static_cast<ItemParagraph *>(item);
- return p->align;
+ return p->alignment;
}
item = item->parent;
}
- return default_align;
+ return default_alignment;
}
TextServer::Direction RichTextLabel::_find_direction(Item *p_item) {
@@ -2190,7 +2190,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
updating_scroll = false;
if (fit_content_height) {
- minimum_size_changed();
+ update_minimum_size();
}
return;
}
@@ -2227,7 +2227,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
updating_scroll = false;
if (fit_content_height) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -2324,7 +2324,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline)
_invalidate_current_line(current_frame);
if (fixed_width != -1) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -2351,7 +2351,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
}
-void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlign p_align) {
+void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment) {
if (current->type == ITEM_TABLE) {
return;
}
@@ -2363,7 +2363,7 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
item->image = p_image;
item->color = p_color;
- item->inline_align = p_align;
+ item->inline_align = p_alignment;
if (p_width > 0) {
// custom width
@@ -2555,11 +2555,11 @@ void RichTextLabel::push_strikethrough() {
_add_item(item, true);
}
-void RichTextLabel::push_paragraph(Align p_align, Control::TextDirection p_direction, const String &p_language, Control::StructuredTextParser p_st_parser) {
+void RichTextLabel::push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction, const String &p_language, Control::StructuredTextParser p_st_parser) {
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemParagraph *item = memnew(ItemParagraph);
- item->align = p_align;
+ item->alignment = p_alignment;
item->direction = p_direction;
item->language = p_language;
item->st_parser = p_st_parser;
@@ -2595,13 +2595,13 @@ void RichTextLabel::push_meta(const Variant &p_meta) {
_add_item(item, true);
}
-void RichTextLabel::push_table(int p_columns, InlineAlign p_align) {
+void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) {
ERR_FAIL_COND(p_columns < 1);
ItemTable *item = memnew(ItemTable);
item->columns.resize(p_columns);
item->total_width = 0;
- item->inline_align = p_align;
+ item->inline_align = p_alignment;
for (int i = 0; i < item->columns.size(); i++) {
item->columns.write[i].expand = false;
item->columns.write[i].expand_ratio = 1;
@@ -2755,7 +2755,7 @@ void RichTextLabel::clear() {
}
if (fixed_width != -1) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -2772,7 +2772,7 @@ int RichTextLabel::get_tab_size() const {
void RichTextLabel::set_fit_content_height(bool p_enabled) {
if (p_enabled != fit_content_height) {
fit_content_height = p_enabled;
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -2958,35 +2958,35 @@ void RichTextLabel::append_text(const String &p_bbcode) {
columns = 1;
}
- int align = INLINE_ALIGN_TOP;
+ int alignment = INLINE_ALIGNMENT_TOP;
if (subtag.size() > 2) {
if (subtag[1] == "top" || subtag[1] == "t") {
- align = INLINE_ALIGN_TOP_TO;
+ alignment = INLINE_ALIGNMENT_TOP_TO;
} else if (subtag[1] == "center" || subtag[1] == "c") {
- align = INLINE_ALIGN_CENTER_TO;
+ alignment = INLINE_ALIGNMENT_CENTER_TO;
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
- align = INLINE_ALIGN_BOTTOM_TO;
+ alignment = INLINE_ALIGNMENT_BOTTOM_TO;
}
if (subtag[2] == "top" || subtag[2] == "t") {
- align |= INLINE_ALIGN_TO_TOP;
+ alignment |= INLINE_ALIGNMENT_TO_TOP;
} else if (subtag[2] == "center" || subtag[2] == "c") {
- align |= INLINE_ALIGN_TO_CENTER;
+ alignment |= INLINE_ALIGNMENT_TO_CENTER;
} else if (subtag[2] == "baseline" || subtag[2] == "l") {
- align |= INLINE_ALIGN_TO_BASELINE;
+ alignment |= INLINE_ALIGNMENT_TO_BASELINE;
} else if (subtag[2] == "bottom" || subtag[2] == "b") {
- align |= INLINE_ALIGN_TO_BOTTOM;
+ alignment |= INLINE_ALIGNMENT_TO_BOTTOM;
}
} else if (subtag.size() > 1) {
if (subtag[1] == "top" || subtag[1] == "t") {
- align = INLINE_ALIGN_TOP;
+ alignment = INLINE_ALIGNMENT_TOP;
} else if (subtag[1] == "center" || subtag[1] == "c") {
- align = INLINE_ALIGN_CENTER;
+ alignment = INLINE_ALIGNMENT_CENTER;
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
- align = INLINE_ALIGN_BOTTOM;
+ alignment = INLINE_ALIGNMENT_BOTTOM;
}
}
- push_table(columns, (InlineAlign)align);
+ push_table(columns, (InlineAlignment)alignment);
pos = brk_end + 1;
tag_stack.push_front("table");
} else if (tag == "cell") {
@@ -3099,15 +3099,15 @@ void RichTextLabel::append_text(const String &p_bbcode) {
add_text(String::chr(0x00AD));
pos = brk_end + 1;
} else if (tag == "center") {
- push_paragraph(ALIGN_CENTER);
+ push_paragraph(HORIZONTAL_ALIGNMENT_CENTER);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "fill") {
- push_paragraph(ALIGN_FILL);
+ push_paragraph(HORIZONTAL_ALIGNMENT_FILL);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "right") {
- push_paragraph(ALIGN_RIGHT);
+ push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "ul") {
@@ -3146,12 +3146,12 @@ void RichTextLabel::append_text(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "p") {
- push_paragraph(ALIGN_LEFT);
+ push_paragraph(HORIZONTAL_ALIGNMENT_LEFT);
pos = brk_end + 1;
tag_stack.push_front("p");
} else if (tag.begins_with("p ")) {
Vector<String> subtag = tag.substr(2, tag.length()).split(" ");
- Align align = ALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
Control::TextDirection dir = Control::TEXT_DIRECTION_INHERITED;
String lang;
Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT;
@@ -3160,13 +3160,13 @@ void RichTextLabel::append_text(const String &p_bbcode) {
if (subtag_a.size() == 2) {
if (subtag_a[0] == "align") {
if (subtag_a[1] == "l" || subtag_a[1] == "left") {
- align = ALIGN_LEFT;
+ alignment = HORIZONTAL_ALIGNMENT_LEFT;
} else if (subtag_a[1] == "c" || subtag_a[1] == "center") {
- align = ALIGN_CENTER;
+ alignment = HORIZONTAL_ALIGNMENT_CENTER;
} else if (subtag_a[1] == "r" || subtag_a[1] == "right") {
- align = ALIGN_RIGHT;
+ alignment = HORIZONTAL_ALIGNMENT_RIGHT;
} else if (subtag_a[1] == "f" || subtag_a[1] == "fill") {
- align = ALIGN_FILL;
+ alignment = HORIZONTAL_ALIGNMENT_FILL;
}
} else if (subtag_a[0] == "dir" || subtag_a[0] == "direction") {
if (subtag_a[1] == "a" || subtag_a[1] == "auto") {
@@ -3197,7 +3197,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
}
- push_paragraph(align, dir, lang, st_parser);
+ push_paragraph(alignment, dir, lang, st_parser);
pos = brk_end + 1;
tag_stack.push_front("p");
} else if (tag == "url") {
@@ -3265,33 +3265,33 @@ void RichTextLabel::append_text(const String &p_bbcode) {
pos = end;
tag_stack.push_front(bbcode_name);
} else if (tag.begins_with("img")) {
- int align = INLINE_ALIGN_CENTER;
+ int alignment = INLINE_ALIGNMENT_CENTER;
if (tag.begins_with("img=")) {
Vector<String> subtag = tag.substr(4, tag.length()).split(",");
if (subtag.size() > 1) {
if (subtag[0] == "top" || subtag[0] == "t") {
- align = INLINE_ALIGN_TOP_TO;
+ alignment = INLINE_ALIGNMENT_TOP_TO;
} else if (subtag[0] == "center" || subtag[0] == "c") {
- align = INLINE_ALIGN_CENTER_TO;
+ alignment = INLINE_ALIGNMENT_CENTER_TO;
} else if (subtag[0] == "bottom" || subtag[0] == "b") {
- align = INLINE_ALIGN_BOTTOM_TO;
+ alignment = INLINE_ALIGNMENT_BOTTOM_TO;
}
if (subtag[1] == "top" || subtag[1] == "t") {
- align |= INLINE_ALIGN_TO_TOP;
+ alignment |= INLINE_ALIGNMENT_TO_TOP;
} else if (subtag[1] == "center" || subtag[1] == "c") {
- align |= INLINE_ALIGN_TO_CENTER;
+ alignment |= INLINE_ALIGNMENT_TO_CENTER;
} else if (subtag[1] == "baseline" || subtag[1] == "l") {
- align |= INLINE_ALIGN_TO_BASELINE;
+ alignment |= INLINE_ALIGNMENT_TO_BASELINE;
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
- align |= INLINE_ALIGN_TO_BOTTOM;
+ alignment |= INLINE_ALIGNMENT_TO_BOTTOM;
}
} else if (subtag.size() > 0) {
if (subtag[0] == "top" || subtag[0] == "t") {
- align = INLINE_ALIGN_TOP;
+ alignment = INLINE_ALIGNMENT_TOP;
} else if (subtag[0] == "center" || subtag[0] == "c") {
- align = INLINE_ALIGN_CENTER;
+ alignment = INLINE_ALIGNMENT_CENTER;
} else if (subtag[0] == "bottom" || subtag[0] == "b") {
- align = INLINE_ALIGN_BOTTOM;
+ alignment = INLINE_ALIGNMENT_BOTTOM;
}
}
}
@@ -3333,7 +3333,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
- add_image(texture, width, height, color, (InlineAlign)align);
+ add_image(texture, width, height, color, (InlineAlignment)alignment);
}
pos = end;
@@ -3853,7 +3853,7 @@ String RichTextLabel::get_selected_text() const {
void RichTextLabel::selection_copy() {
String text = get_selected_text();
- if (text != "") {
+ if (!text.is_empty()) {
DisplayServer::get_singleton()->clipboard_set(text);
}
}
@@ -4005,7 +4005,7 @@ float RichTextLabel::get_percent_visible() const {
void RichTextLabel::set_effects(Array p_effects) {
custom_effects = p_effects;
- if ((text != "") && use_bbcode) {
+ if ((!text.is_empty()) && use_bbcode) {
parse_bbcode(text);
}
}
@@ -4020,7 +4020,7 @@ void RichTextLabel::install_effect(const Variant effect) {
if (rteffect.is_valid()) {
custom_effects.push_back(effect);
- if ((text != "") && use_bbcode) {
+ if ((!text.is_empty()) && use_bbcode) {
parse_bbcode(text);
}
}
@@ -4050,7 +4050,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_parsed_text"), &RichTextLabel::get_parsed_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
- ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGN_CENTER));
+ ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
@@ -4064,13 +4064,13 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("push_color", "color"), &RichTextLabel::push_color);
ClassDB::bind_method(D_METHOD("push_outline_size", "outline_size"), &RichTextLabel::push_outline_size);
ClassDB::bind_method(D_METHOD("push_outline_color", "color"), &RichTextLabel::push_outline_color);
- ClassDB::bind_method(D_METHOD("push_paragraph", "align", "base_direction", "language", "st_parser"), &RichTextLabel::push_paragraph, DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(""), DEFVAL(STRUCTURED_TEXT_DEFAULT));
+ ClassDB::bind_method(D_METHOD("push_paragraph", "alignment", "base_direction", "language", "st_parser"), &RichTextLabel::push_paragraph, DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(""), DEFVAL(STRUCTURED_TEXT_DEFAULT));
ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent);
ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize"), &RichTextLabel::push_list);
ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta);
ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);
ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough);
- ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGN_TOP));
+ ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP));
ClassDB::bind_method(D_METHOD("push_dropcap", "string", "font", "size", "dropcap_margins", "color", "outline_size", "outline_color"), &RichTextLabel::push_dropcap, DEFVAL(Rect2()), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(0, 0, 0, 0)));
ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand);
ClassDB::bind_method(D_METHOD("set_cell_row_background_color", "odd_row_bg", "even_row_bg"), &RichTextLabel::set_cell_row_background_color);
@@ -4188,11 +4188,6 @@ void RichTextLabel::_bind_methods() {
ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("meta_hover_ended", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
- BIND_ENUM_CONSTANT(ALIGN_FILL);
-
BIND_ENUM_CONSTANT(LIST_NUMBERS);
BIND_ENUM_CONSTANT(LIST_LETTERS);
BIND_ENUM_CONSTANT(LIST_ROMAN);
@@ -4268,7 +4263,7 @@ int RichTextLabel::get_total_character_count() const {
void RichTextLabel::set_fixed_size_to_width(int p_width) {
fixed_width = p_width;
- minimum_size_changed();
+ update_minimum_size();
}
Size2 RichTextLabel::get_minimum_size() const {
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 5b58f14d96..58a531e5ad 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -39,13 +39,6 @@ class RichTextLabel : public Control {
GDCLASS(RichTextLabel, Control);
public:
- enum Align {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_FILL
- };
-
enum ListType {
LIST_NUMBERS,
LIST_LETTERS,
@@ -160,7 +153,7 @@ private:
struct ItemImage : public Item {
Ref<Texture2D> image;
- InlineAlign inline_align = INLINE_ALIGN_CENTER;
+ InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
Size2 size;
Color color;
ItemImage() { type = ITEM_IMAGE; }
@@ -210,7 +203,7 @@ private:
};
struct ItemParagraph : public Item {
- Align align = ALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
String language;
Control::TextDirection direction = Control::TEXT_DIRECTION_AUTO;
Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT;
@@ -247,7 +240,7 @@ private:
int total_width = 0;
int total_height = 0;
- InlineAlign inline_align = INLINE_ALIGN_TOP;
+ InlineAlignment inline_align = INLINE_ALIGNMENT_TOP;
ItemTable() { type = ITEM_TABLE; }
};
@@ -360,7 +353,7 @@ private:
bool underline_meta = true;
bool override_selected_font_color = false;
- Align default_align = ALIGN_LEFT;
+ HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT;
ItemMeta *meta_hovering = nullptr;
Variant current_meta;
@@ -428,7 +421,7 @@ private:
ItemDropcap *_find_dc_item(Item *p_item);
int _find_list(Item *p_item, Vector<int> &r_index, Vector<ItemList *> &r_list);
int _find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size);
- Align _find_align(Item *p_item);
+ HorizontalAlignment _find_alignment(Item *p_item);
TextServer::Direction _find_direction(Item *p_item);
Control::StructuredTextParser _find_stt(Item *p_item);
String _find_language(Item *p_item);
@@ -469,7 +462,7 @@ private:
public:
String get_parsed_text() const;
void add_text(const String &p_text);
- void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), InlineAlign p_align = INLINE_ALIGN_CENTER);
+ void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), InlineAlignment p_alignment = INLINE_ALIGNMENT_CENTER);
void add_newline();
bool remove_line(const int p_line);
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
@@ -486,11 +479,11 @@ public:
void push_outline_color(const Color &p_color);
void push_underline();
void push_strikethrough();
- void push_paragraph(Align p_align, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", Control::StructuredTextParser p_st_parser = STRUCTURED_TEXT_DEFAULT);
+ void push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", Control::StructuredTextParser p_st_parser = STRUCTURED_TEXT_DEFAULT);
void push_indent(int p_level);
void push_list(int p_level, ListType p_list, bool p_capitalize);
void push_meta(const Variant &p_meta);
- void push_table(int p_columns, InlineAlign p_align = INLINE_ALIGN_TOP);
+ void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP);
void push_fade(int p_start_index, int p_length);
void push_shake(int p_strength, float p_rate);
void push_wave(float p_frequency, float p_amplitude);
@@ -595,7 +588,6 @@ public:
~RichTextLabel();
};
-VARIANT_ENUM_CAST(RichTextLabel::Align);
VARIANT_ENUM_CAST(RichTextLabel::ListType);
VARIANT_ENUM_CAST(RichTextLabel::ItemType);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 7b2ea46e17..dcd2c32a3b 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -49,10 +49,10 @@ Size2 ScrollContainer::get_minimum_size() const {
}
Size2 minsize = c->get_combined_minimum_size();
- if (!scroll_h) {
+ if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) {
min_size.x = MAX(min_size.x, minsize.x);
}
- if (!scroll_v) {
+ if (vertical_scroll_mode == SCROLL_MODE_DISABLED) {
min_size.y = MAX(min_size.y, minsize.y);
}
}
@@ -170,7 +170,7 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) {
Vector2 motion = mm->get_relative();
drag_accum -= motion;
- if (beyond_deadzone || (scroll_h && Math::abs(drag_accum.x) > deadzone) || (scroll_v && Math::abs(drag_accum.y) > deadzone)) {
+ if (beyond_deadzone || (horizontal_scroll_mode != SCROLL_MODE_DISABLED && Math::abs(drag_accum.x) > deadzone) || (vertical_scroll_mode != SCROLL_MODE_DISABLED && Math::abs(drag_accum.y) > deadzone)) {
if (!beyond_deadzone) {
propagate_notification(NOTIFICATION_SCROLL_BEGIN);
emit_signal(SNAME("scroll_started"));
@@ -180,12 +180,12 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) {
drag_accum = -motion;
}
Vector2 diff = drag_from + drag_accum;
- if (scroll_h) {
+ if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) {
h_scroll->set_value(diff.x);
} else {
drag_accum.x = 0;
}
- if (scroll_v) {
+ if (vertical_scroll_mode != SCROLL_MODE_DISABLED) {
v_scroll->set_value(diff.y);
} else {
drag_accum.y = 0;
@@ -286,7 +286,7 @@ void ScrollContainer::_update_dimensions() {
child_max_size.y = MAX(child_max_size.y, minsize.y);
Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize);
- if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
+ if (horizontal_scroll_mode == SCROLL_MODE_DISABLED || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
r.position.x = 0;
if (c->get_h_size_flags() & SIZE_EXPAND) {
r.size.width = MAX(size.width, minsize.width);
@@ -294,7 +294,7 @@ void ScrollContainer::_update_dimensions() {
r.size.width = minsize.width;
}
}
- if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
+ if (vertical_scroll_mode == SCROLL_MODE_DISABLED || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
r.position.y = 0;
if (c->get_v_size_flags() & SIZE_EXPAND) {
r.size.height = MAX(size.height, minsize.height);
@@ -364,10 +364,10 @@ void ScrollContainer::_notification(int p_what) {
turnoff_v = true;
}
- if (scroll_h) {
+ if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) {
h_scroll->set_value(pos.x);
}
- if (scroll_v) {
+ if (vertical_scroll_mode != SCROLL_MODE_DISABLED) {
v_scroll->set_value(pos.y);
}
@@ -413,17 +413,17 @@ void ScrollContainer::update_scrollbars() {
Size2 hmin;
Size2 vmin;
- if (scroll_h) {
+ if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) {
hmin = h_scroll->get_combined_minimum_size();
}
- if (scroll_v) {
+ if (vertical_scroll_mode != SCROLL_MODE_DISABLED) {
vmin = v_scroll->get_combined_minimum_size();
}
Size2 min = child_max_size;
- bool hide_scroll_h = !scroll_h || min.width <= size.width || !h_scroll_visible;
- bool hide_scroll_v = !scroll_v || min.height <= size.height || !v_scroll_visible;
+ bool hide_scroll_h = horizontal_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (horizontal_scroll_mode == SCROLL_MODE_DISABLED || horizontal_scroll_mode == SCROLL_MODE_SHOW_NEVER || (horizontal_scroll_mode == SCROLL_MODE_AUTO && min.width <= size.width));
+ bool hide_scroll_v = vertical_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (vertical_scroll_mode == SCROLL_MODE_DISABLED || vertical_scroll_mode == SCROLL_MODE_SHOW_NEVER || (vertical_scroll_mode == SCROLL_MODE_AUTO && min.height <= size.height));
h_scroll->set_max(min.width);
h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width));
@@ -461,58 +461,32 @@ int ScrollContainer::get_v_scroll() const {
return v_scroll->get_value();
}
-void ScrollContainer::set_enable_h_scroll(bool p_enable) {
- if (scroll_h == p_enable) {
+void ScrollContainer::set_horizontal_scroll_mode(ScrollMode p_mode) {
+ if (horizontal_scroll_mode == p_mode) {
return;
}
- scroll_h = p_enable;
- minimum_size_changed();
+ horizontal_scroll_mode = p_mode;
+ update_minimum_size();
queue_sort();
}
-bool ScrollContainer::is_h_scroll_enabled() const {
- return scroll_h;
+ScrollContainer::ScrollMode ScrollContainer::get_horizontal_scroll_mode() const {
+ return horizontal_scroll_mode;
}
-void ScrollContainer::set_enable_v_scroll(bool p_enable) {
- if (scroll_v == p_enable) {
+void ScrollContainer::set_vertical_scroll_mode(ScrollMode p_mode) {
+ if (vertical_scroll_mode == p_mode) {
return;
}
- scroll_v = p_enable;
- minimum_size_changed();
+ vertical_scroll_mode = p_mode;
+ update_minimum_size();
queue_sort();
}
-bool ScrollContainer::is_v_scroll_enabled() const {
- return scroll_v;
-}
-
-void ScrollContainer::set_h_scroll_visible(bool p_visible) {
- if (h_scroll_visible == p_visible) {
- return;
- }
-
- h_scroll_visible = p_visible;
- update_scrollbars();
-}
-
-bool ScrollContainer::is_h_scroll_visible() const {
- return h_scroll_visible;
-}
-
-void ScrollContainer::set_v_scroll_visible(bool p_visible) {
- if (v_scroll_visible == p_visible) {
- return;
- }
-
- v_scroll_visible = p_visible;
- update_scrollbars();
-}
-
-bool ScrollContainer::is_v_scroll_visible() const {
- return v_scroll_visible;
+ScrollContainer::ScrollMode ScrollContainer::get_vertical_scroll_mode() const {
+ return vertical_scroll_mode;
}
int ScrollContainer::get_deadzone() const {
@@ -575,17 +549,11 @@ void ScrollContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll);
ClassDB::bind_method(D_METHOD("get_v_scroll"), &ScrollContainer::get_v_scroll);
- ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
- ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
-
- ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
- ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
+ ClassDB::bind_method(D_METHOD("set_horizontal_scroll_mode", "enable"), &ScrollContainer::set_horizontal_scroll_mode);
+ ClassDB::bind_method(D_METHOD("get_horizontal_scroll_mode"), &ScrollContainer::get_horizontal_scroll_mode);
- ClassDB::bind_method(D_METHOD("set_h_scroll_visible", "visible"), &ScrollContainer::set_h_scroll_visible);
- ClassDB::bind_method(D_METHOD("is_h_scroll_visible"), &ScrollContainer::is_h_scroll_visible);
-
- ClassDB::bind_method(D_METHOD("set_v_scroll_visible", "visible"), &ScrollContainer::set_v_scroll_visible);
- ClassDB::bind_method(D_METHOD("is_v_scroll_visible"), &ScrollContainer::is_v_scroll_visible);
+ ClassDB::bind_method(D_METHOD("set_vertical_scroll_mode", "enable"), &ScrollContainer::set_vertical_scroll_mode);
+ ClassDB::bind_method(D_METHOD("get_vertical_scroll_mode"), &ScrollContainer::get_vertical_scroll_mode);
ClassDB::bind_method(D_METHOD("set_deadzone", "deadzone"), &ScrollContainer::set_deadzone);
ClassDB::bind_method(D_METHOD("get_deadzone"), &ScrollContainer::get_deadzone);
@@ -605,12 +573,15 @@ void ScrollContainer::_bind_methods() {
ADD_GROUP("Scroll", "scroll_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_vertical"), "set_v_scroll", "get_v_scroll");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_visible"), "set_h_scroll_visible", "is_h_scroll_visible");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_visible"), "set_v_scroll_visible", "is_v_scroll_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_horizontal_scroll_mode", "get_horizontal_scroll_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_vertical_scroll_mode", "get_vertical_scroll_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_deadzone"), "set_deadzone", "get_deadzone");
+ BIND_ENUM_CONSTANT(SCROLL_MODE_DISABLED);
+ BIND_ENUM_CONSTANT(SCROLL_MODE_AUTO);
+ BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_ALWAYS);
+ BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_NEVER);
+
GLOBAL_DEF("gui/common/default_scroll_deadzone", 0);
};
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 9f4ec558dc..0cec4db57a 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -38,6 +38,15 @@
class ScrollContainer : public Container {
GDCLASS(ScrollContainer, Container);
+public:
+ enum ScrollMode {
+ SCROLL_MODE_DISABLED = 0,
+ SCROLL_MODE_AUTO,
+ SCROLL_MODE_SHOW_ALWAYS,
+ SCROLL_MODE_SHOW_NEVER,
+ };
+
+private:
HScrollBar *h_scroll;
VScrollBar *v_scroll;
@@ -54,11 +63,8 @@ class ScrollContainer : public Container {
bool drag_touching_deaccel = false;
bool beyond_deadzone = false;
- bool scroll_h = true;
- bool scroll_v = true;
-
- bool h_scroll_visible = true;
- bool v_scroll_visible = true;
+ ScrollMode horizontal_scroll_mode = SCROLL_MODE_AUTO;
+ ScrollMode vertical_scroll_mode = SCROLL_MODE_AUTO;
int deadzone = 0;
bool follow_focus = false;
@@ -68,7 +74,6 @@ class ScrollContainer : public Container {
protected:
Size2 get_minimum_size() const override;
- virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
void _gui_focus_changed(Control *p_control);
void _update_dimensions();
void _notification(int p_what);
@@ -80,23 +85,19 @@ protected:
void _update_scrollbar_position();
public:
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
+
void set_h_scroll(int p_pos);
int get_h_scroll() const;
void set_v_scroll(int p_pos);
int get_v_scroll() const;
- void set_enable_h_scroll(bool p_enable);
- bool is_h_scroll_enabled() const;
-
- void set_enable_v_scroll(bool p_enable);
- bool is_v_scroll_enabled() const;
+ void set_horizontal_scroll_mode(ScrollMode p_mode);
+ ScrollMode get_horizontal_scroll_mode() const;
- void set_h_scroll_visible(bool p_visible);
- bool is_h_scroll_visible() const;
-
- void set_v_scroll_visible(bool p_visible);
- bool is_v_scroll_visible() const;
+ void set_vertical_scroll_mode(ScrollMode p_mode);
+ ScrollMode get_vertical_scroll_mode() const;
int get_deadzone() const;
void set_deadzone(int p_deadzone);
@@ -113,4 +114,6 @@ public:
ScrollContainer();
};
+VARIANT_ENUM_CAST(ScrollContainer::ScrollMode);
+
#endif
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 4cc425aad3..f8cabe172c 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -142,7 +142,7 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) {
void Slider::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_MOUSE_ENTER: {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index f30206c943..8d6315d085 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -41,10 +41,10 @@ Size2 SpinBox::get_minimum_size() const {
void SpinBox::_value_changed(double) {
String value = TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step())));
- if (prefix != "") {
+ if (!prefix.is_empty()) {
value = prefix + " " + value;
}
- if (suffix != "") {
+ if (!suffix.is_empty()) {
value += " " + suffix;
}
line_edit->set_text(value);
@@ -220,19 +220,19 @@ void SpinBox::_notification(int p_what) {
} else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_value_changed(0);
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
- call_deferred(SNAME("minimum_size_changed"));
- get_line_edit()->call_deferred(SNAME("minimum_size_changed"));
+ call_deferred(SNAME("update_minimum_size"));
+ get_line_edit()->call_deferred(SNAME("update_minimum_size"));
} else if (p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) {
update();
}
}
-void SpinBox::set_align(LineEdit::Align p_align) {
- line_edit->set_align(p_align);
+void SpinBox::set_horizontal_alignment(HorizontalAlignment p_alignment) {
+ line_edit->set_horizontal_alignment(p_alignment);
}
-LineEdit::Align SpinBox::get_align() const {
- return line_edit->get_align();
+HorizontalAlignment SpinBox::get_horizontal_alignment() const {
+ return line_edit->get_horizontal_alignment();
}
void SpinBox::set_suffix(const String &p_suffix) {
@@ -284,8 +284,8 @@ void SpinBox::apply() {
}
void SpinBox::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_align", "align"), &SpinBox::set_align);
- ClassDB::bind_method(D_METHOD("get_align"), &SpinBox::get_align);
+ ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment);
+ ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment);
ClassDB::bind_method(D_METHOD("set_suffix", "suffix"), &SpinBox::set_suffix);
ClassDB::bind_method(D_METHOD("get_suffix"), &SpinBox::get_suffix);
ClassDB::bind_method(D_METHOD("set_prefix", "prefix"), &SpinBox::set_prefix);
@@ -297,7 +297,7 @@ void SpinBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply);
ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "update_on_text_changed"), "set_update_on_text_changed", "get_update_on_text_changed");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix");
@@ -310,7 +310,7 @@ SpinBox::SpinBox() {
line_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
line_edit->set_mouse_filter(MOUSE_FILTER_PASS);
- line_edit->set_align(LineEdit::ALIGN_LEFT);
+ line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), Vector<Variant>(), CONNECT_DEFERRED);
line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index f2299ce1c2..736a5d873d 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -79,8 +79,8 @@ public:
virtual Size2 get_minimum_size() const override;
- void set_align(LineEdit::Align p_align);
- LineEdit::Align get_align() const;
+ void set_horizontal_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_horizontal_alignment() const;
void set_editable(bool p_enabled);
bool is_editable() const;
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 6b53c0220e..106bb7949f 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -201,7 +201,7 @@ void SplitContainer::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
- minimum_size_changed();
+ update_minimum_size();
} break;
}
}
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 57ee7fd494..3d88c117e7 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -50,7 +50,7 @@ Size2 TabBar::get_minimum_size() const {
Ref<Texture2D> tex = tabs[i].icon;
if (tex.is_valid()) {
ms.height = MAX(ms.height, tex->get_size().height);
- if (tabs[i].text != "") {
+ if (!tabs[i].text.is_empty()) {
ms.width += get_theme_constant(SNAME("hseparation"));
}
}
@@ -164,7 +164,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
if (rb_hover != -1) {
- // pressed
+ // Right mouse button clicked.
emit_signal(SNAME("tab_rmb_clicked"), rb_hover);
}
@@ -174,7 +174,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
if (cb_hover != -1) {
- // pressed
+ // Close button pressed.
emit_signal(SNAME("tab_close_pressed"), cb_hover);
}
@@ -183,7 +183,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
}
if (mb->is_pressed() && (mb->get_button_index() == MouseButton::LEFT || (select_with_rmb && mb->get_button_index() == MouseButton::RIGHT))) {
- // clicks
+ // Clicks.
Point2 pos = mb->get_position();
if (buttons_visible) {
@@ -235,7 +235,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
return;
}
- if (tabs[i].cb_rect.has_point(pos)) {
+ if (tabs[i].cb_rect.has_point(pos) && (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current))) {
cb_pressing = true;
update();
return;
@@ -270,7 +270,7 @@ void TabBar::_shape(int p_tab) {
tabs.write[p_tab].text_buf->set_direction((TextServer::Direction)tabs[p_tab].text_direction);
}
- tabs.write[p_tab].text_buf->add_string(tabs.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, (tabs[p_tab].language != "") ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale());
+ tabs.write[p_tab].text_buf->add_string(tabs.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, !tabs[p_tab].language.is_empty() ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale());
}
void TabBar::_notification(int p_what) {
@@ -285,7 +285,7 @@ void TabBar::_notification(int p_what) {
_shape(i);
}
_update_cache();
- minimum_size_changed();
+ update_minimum_size();
update();
} break;
case NOTIFICATION_RESIZED: {
@@ -319,9 +319,9 @@ void TabBar::_notification(int p_what) {
mw += get_tab_width(i);
}
- if (tab_align == ALIGN_CENTER) {
+ if (tab_alignment == ALIGNMENT_CENTER) {
w = (get_size().width - mw) / 2;
- } else if (tab_align == ALIGN_RIGHT) {
+ } else if (tab_alignment == ALIGNMENT_RIGHT) {
w = get_size().width - mw;
}
@@ -385,7 +385,7 @@ void TabBar::_notification(int p_what) {
} else {
icon->draw(ci, Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
}
- if (tabs[i].text != "") {
+ if (!tabs[i].text.is_empty()) {
w += icon->get_width() + get_theme_constant(SNAME("hseparation"));
}
}
@@ -554,7 +554,7 @@ void TabBar::set_tab_title(int p_tab, const String &p_title) {
tabs.write[p_tab].text = p_title;
_shape(p_tab);
update();
- minimum_size_changed();
+ update_minimum_size();
}
String TabBar::get_tab_title(int p_tab) const {
@@ -621,7 +621,7 @@ void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].icon = p_icon;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const {
@@ -645,7 +645,7 @@ void TabBar::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_butto
tabs.write[p_tab].right_button = p_right_button;
_update_cache();
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TabBar::get_tab_right_button(int p_tab) const {
@@ -659,7 +659,7 @@ void TabBar::_update_hover() {
}
const Point2 &pos = get_local_mouse_position();
- // test hovering to display right or close button
+ // test hovering to display right or close button.
int hover_now = -1;
int hover_buttons = -1;
for (int i = offset; i < tabs.size(); i++) {
@@ -684,7 +684,7 @@ void TabBar::_update_hover() {
emit_signal(SNAME("tab_hovered"), hover);
}
- if (hover_buttons == -1) { // no hover
+ if (hover_buttons == -1) { // No hover.
rb_hover = hover_buttons;
cb_hover = hover_buttons;
}
@@ -777,7 +777,7 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
_update_cache();
call_deferred(SNAME("_update_hover"));
update();
- minimum_size_changed();
+ update_minimum_size();
}
void TabBar::clear_tabs() {
@@ -797,7 +797,7 @@ void TabBar::remove_tab(int p_idx) {
_update_cache();
call_deferred(SNAME("_update_hover"));
update();
- minimum_size_changed();
+ update_minimum_size();
if (current < 0) {
current = 0;
@@ -860,7 +860,7 @@ bool TabBar::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
if (from_path == to_path) {
return true;
} else if (get_tabs_rearrange_group() != -1) {
- // drag and drop between other TabBars
+ // Drag and drop between other TabBars.
Node *from_node = get_node(from_path);
TabBar *from_tabs = Object::cast_to<TabBar>(from_node);
if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) {
@@ -895,7 +895,7 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) {
emit_signal(SNAME("active_tab_rearranged"), hover_now);
set_current_tab(hover_now);
} else if (get_tabs_rearrange_group() != -1) {
- // drag and drop between Tabs
+ // Drag and drop between Tabs.
Node *from_node = get_node(from_path);
TabBar *from_tabs = Object::cast_to<TabBar>(from_node);
if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) {
@@ -929,14 +929,14 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const {
return hover_now;
}
-void TabBar::set_tab_align(TabAlign p_align) {
- ERR_FAIL_INDEX(p_align, ALIGN_MAX);
- tab_align = p_align;
+void TabBar::set_tab_alignment(AlignmentMode p_alignment) {
+ ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX);
+ tab_alignment = p_alignment;
update();
}
-TabBar::TabAlign TabBar::get_tab_align() const {
- return tab_align;
+TabBar::AlignmentMode TabBar::get_tab_alignment() const {
+ return tab_alignment;
}
void TabBar::set_clip_tabs(bool p_clip_tabs) {
@@ -945,7 +945,7 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) {
}
clip_tabs = p_clip_tabs;
update();
- minimum_size_changed();
+ update_minimum_size();
}
bool TabBar::get_clip_tabs() const {
@@ -980,7 +980,7 @@ int TabBar::get_tab_width(int p_idx) const {
Ref<Texture2D> tex = tabs[p_idx].icon;
if (tex.is_valid()) {
x += tex->get_width();
- if (tabs[p_idx].text != "") {
+ if (!tabs[p_idx].text.is_empty()) {
x += get_theme_constant(SNAME("hseparation"));
}
}
@@ -1149,8 +1149,8 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabBar::get_tab_disabled);
ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab);
ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
- ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabBar::set_tab_align);
- ClassDB::bind_method(D_METHOD("get_tab_align"), &TabBar::get_tab_align);
+ ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabBar::set_tab_alignment);
+ ClassDB::bind_method(D_METHOD("get_tab_alignment"), &TabBar::get_tab_alignment);
ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &TabBar::set_clip_tabs);
ClassDB::bind_method(D_METHOD("get_clip_tabs"), &TabBar::get_clip_tabs);
ClassDB::bind_method(D_METHOD("get_tab_offset"), &TabBar::get_tab_offset);
@@ -1178,16 +1178,16 @@ void TabBar::_bind_methods() {
ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
- BIND_ENUM_CONSTANT(ALIGN_MAX);
+ BIND_ENUM_CONSTANT(ALIGNMENT_LEFT);
+ BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
+ BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT);
+ BIND_ENUM_CONSTANT(ALIGNMENT_MAX);
BIND_ENUM_CONSTANT(CLOSE_BUTTON_SHOW_NEVER);
BIND_ENUM_CONSTANT(CLOSE_BUTTON_SHOW_ACTIVE_ONLY);
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index 411a62b1d9..2d211937fc 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -38,11 +38,11 @@ class TabBar : public Control {
GDCLASS(TabBar, Control);
public:
- enum TabAlign {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_MAX
+ enum AlignmentMode {
+ ALIGNMENT_LEFT,
+ ALIGNMENT_CENTER,
+ ALIGNMENT_RIGHT,
+ ALIGNMENT_MAX,
};
enum CloseButtonDisplayPolicy {
@@ -83,7 +83,7 @@ private:
Vector<Tab> tabs;
int current = 0;
int previous = 0;
- TabAlign tab_align = ALIGN_CENTER;
+ AlignmentMode tab_alignment = ALIGNMENT_CENTER;
bool clip_tabs = true;
int rb_hover = -1;
bool rb_pressing = false;
@@ -145,8 +145,8 @@ public:
void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button);
Ref<Texture2D> get_tab_right_button(int p_tab) const;
- void set_tab_align(TabAlign p_align);
- TabAlign get_tab_align() const;
+ void set_tab_alignment(AlignmentMode p_alignment);
+ AlignmentMode get_tab_alignment() const;
void set_clip_tabs(bool p_clip_tabs);
bool get_clip_tabs() const;
@@ -189,7 +189,7 @@ public:
TabBar();
};
-VARIANT_ENUM_CAST(TabBar::TabAlign);
+VARIANT_ENUM_CAST(TabBar::AlignmentMode);
VARIANT_ENUM_CAST(TabBar::CloseButtonDisplayPolicy);
#endif // TAB_BAR_H
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index ff53d91ea3..fd5df5c93b 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -406,14 +406,14 @@ void TabContainer::_notification(int p_what) {
}
// Find the offset at which to draw tabs, according to the alignment.
- switch (align) {
- case ALIGN_LEFT:
+ switch (alignment) {
+ case ALIGNMENT_LEFT:
tabs_ofs_cache = header_x;
break;
- case ALIGN_CENTER:
+ case ALIGNMENT_CENTER:
tabs_ofs_cache = header_x + (header_width / 2) - (all_tabs_width / 2);
break;
- case ALIGN_RIGHT:
+ case ALIGNMENT_RIGHT:
tabs_ofs_cache = header_x + header_width - all_tabs_width;
break;
}
@@ -561,7 +561,7 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in
if (icon.is_valid()) {
int y = y_center - (icon->get_height() / 2);
icon->draw(canvas, Point2i(x_content, y));
- if (text != "") {
+ if (!text.is_empty()) {
x_content += icon->get_width() + icon_text_distance;
}
}
@@ -600,7 +600,7 @@ void TabContainer::_on_theme_changed() {
_refresh_texts();
- minimum_size_changed();
+ update_minimum_size();
if (get_tab_count() > 0) {
_repaint();
update();
@@ -656,7 +656,7 @@ int TabContainer::_get_tab_width(int p_index) const {
Ref<Texture2D> icon = control->get_meta("_tab_icon");
if (icon.is_valid()) {
width += icon->get_width();
- if (text != "") {
+ if (!text.is_empty()) {
width += get_theme_constant(SNAME("icon_separation"));
}
}
@@ -967,14 +967,14 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const {
return -1;
}
-void TabContainer::set_tab_align(TabAlign p_align) {
- ERR_FAIL_INDEX(p_align, 3);
- align = p_align;
+void TabContainer::set_tab_alignment(AlignmentMode p_alignment) {
+ ERR_FAIL_INDEX(p_alignment, 3);
+ alignment = p_alignment;
update();
}
-TabContainer::TabAlign TabContainer::get_tab_align() const {
- return align;
+TabContainer::AlignmentMode TabContainer::get_tab_alignment() const {
+ return alignment;
}
void TabContainer::set_tabs_visible(bool p_visible) {
@@ -995,7 +995,7 @@ void TabContainer::set_tabs_visible(bool p_visible) {
}
update();
- minimum_size_changed();
+ update_minimum_size();
}
bool TabContainer::are_tabs_visible() const {
@@ -1108,7 +1108,7 @@ void TabContainer::get_translatable_strings(List<String> *p_strings) const {
String name = c->get_meta("_tab_name");
- if (name != "") {
+ if (!name.is_empty()) {
p_strings->push_back(name);
}
}
@@ -1198,8 +1198,8 @@ void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabContainer::get_previous_tab);
ClassDB::bind_method(D_METHOD("get_current_tab_control"), &TabContainer::get_current_tab_control);
ClassDB::bind_method(D_METHOD("get_tab_control", "tab_idx"), &TabContainer::get_tab_control);
- ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align);
- ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align);
+ ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabContainer::set_tab_alignment);
+ ClassDB::bind_method(D_METHOD("get_tab_alignment"), &TabContainer::get_tab_alignment);
ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible);
ClassDB::bind_method(D_METHOD("are_tabs_visible"), &TabContainer::are_tabs_visible);
ClassDB::bind_method(D_METHOD("set_all_tabs_in_front", "is_front"), &TabContainer::set_all_tabs_in_front);
@@ -1230,16 +1230,16 @@ void TabContainer::_bind_methods() {
ADD_SIGNAL(MethodInfo("tab_selected", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("pre_popup_pressed"));
- ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "all_tabs_in_front"), "set_all_tabs_in_front", "is_all_tabs_in_front");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hidden_tabs_for_min_size"), "set_use_hidden_tabs_for_min_size", "get_use_hidden_tabs_for_min_size");
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
+ BIND_ENUM_CONSTANT(ALIGNMENT_LEFT);
+ BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
+ BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT);
}
TabContainer::TabContainer() {
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index fe96df25e8..6dfeb2b625 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -39,10 +39,10 @@ class TabContainer : public Container {
GDCLASS(TabContainer, Container);
public:
- enum TabAlign {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT
+ enum AlignmentMode {
+ ALIGNMENT_LEFT,
+ ALIGNMENT_CENTER,
+ ALIGNMENT_RIGHT,
};
private:
@@ -56,7 +56,7 @@ private:
bool buttons_visible_cache = false;
bool menu_hovered = false;
int highlight_arrow = -1;
- TabAlign align = ALIGN_CENTER;
+ AlignmentMode alignment = ALIGNMENT_CENTER;
int _get_top_margin() const;
mutable ObjectID popup_obj_id;
bool drag_to_rearrange_enabled = false;
@@ -90,8 +90,8 @@ protected:
static void _bind_methods();
public:
- void set_tab_align(TabAlign p_align);
- TabAlign get_tab_align() const;
+ void set_tab_alignment(AlignmentMode p_alignment);
+ AlignmentMode get_tab_alignment() const;
void set_tabs_visible(bool p_visible);
bool are_tabs_visible() const;
@@ -136,6 +136,6 @@ public:
TabContainer();
};
-VARIANT_ENUM_CAST(TabContainer::TabAlign);
+VARIANT_ENUM_CAST(TabContainer::AlignmentMode);
#endif // TAB_CONTAINER_H
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 2cb9d10fca..c9060033f2 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -39,6 +39,7 @@
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "core/string/translation.h"
+#include "label.h"
#include "scene/main/window.h"
@@ -154,30 +155,30 @@ _FORCE_INLINE_ const String &TextEdit::Text::operator[](int p_line) const {
void TextEdit::Text::_calculate_line_height() {
int height = 0;
- for (int i = 0; i < text.size(); i++) {
+ for (const Line &l : text) {
// Found another line with the same height...nothing to update.
- if (text[i].height == line_height) {
+ if (l.height == line_height) {
height = line_height;
break;
}
- height = MAX(height, text[i].height);
+ height = MAX(height, l.height);
}
line_height = height;
}
void TextEdit::Text::_calculate_max_line_width() {
int width = 0;
- for (int i = 0; i < text.size(); i++) {
- if (is_hidden(i)) {
+ for (const Line &l : text) {
+ if (l.hidden) {
continue;
}
// Found another line with the same width...nothing to update.
- if (text[i].width == max_width) {
+ if (l.width == max_width) {
width = max_width;
break;
}
- width = MAX(width, text[i].width);
+ width = MAX(width, l.width);
}
max_width = width;
}
@@ -215,7 +216,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_
// Update height.
const int old_height = text.write[p_line].height;
const int wrap_amount = get_line_wrap_amount(p_line);
- int height = font->get_height(font_size);
+ int height = font_height;
for (int i = 0; i <= wrap_amount; i++) {
height = MAX(height, text[p_line].data_buf->get_line_size(i).y);
}
@@ -266,6 +267,13 @@ void TextEdit::Text::invalidate_all() {
return;
}
+ max_width = -1;
+ line_height = -1;
+
+ if (!font.is_null() && font_size > 0) {
+ font_height = font->get_height(font_size);
+ }
+
for (int i = 0; i < text.size(); i++) {
invalidate_cache(i);
}
@@ -274,7 +282,15 @@ void TextEdit::Text::invalidate_all() {
void TextEdit::Text::clear() {
text.clear();
- insert(0, "", Array());
+
+ max_width = -1;
+ line_height = -1;
+
+ Line line;
+ line.gutters.resize(gutter_count);
+ line.data = "";
+ text.insert(0, line);
+ invalidate_cache(0);
}
int TextEdit::Text::get_max_width() const {
@@ -289,30 +305,64 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_o
invalidate_cache(p_line);
}
-void TextEdit::Text::insert(int p_at, const String &p_text, const Array &p_bidi_override) {
- Line line;
- line.gutters.resize(gutter_count);
- line.hidden = false;
- line.data = p_text;
- line.bidi_override = p_bidi_override;
- text.insert(p_at, line);
+void TextEdit::Text::insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override) {
+ int new_line_count = p_text.size() - 1;
+ if (new_line_count > 0) {
+ text.resize(text.size() + new_line_count);
+ for (int i = (text.size() - 1); i > p_at; i--) {
+ if ((i - new_line_count) <= 0) {
+ break;
+ }
+ text.write[i] = text[i - new_line_count];
+ }
+ }
- invalidate_cache(p_at);
+ for (int i = 0; i < p_text.size(); i++) {
+ if (i == 0) {
+ set(p_at + i, p_text[i], p_bidi_override[i]);
+ continue;
+ }
+ Line line;
+ line.gutters.resize(gutter_count);
+ line.data = p_text[i];
+ line.bidi_override = p_bidi_override[i];
+ text.write[p_at + i] = line;
+ invalidate_cache(p_at + i);
+ }
}
-void TextEdit::Text::remove_at(int p_index) {
- int height = text[p_index].height;
- int width = text[p_index].width;
+void TextEdit::Text::remove_range(int p_from_line, int p_to_line) {
+ if (p_from_line == p_to_line) {
+ return;
+ }
+
+ bool dirty_height = false;
+ bool dirty_width = false;
+ for (int i = p_from_line; i < p_to_line; i++) {
+ if (!dirty_height && text[i].height == line_height) {
+ dirty_height = true;
+ }
- text.remove_at(p_index);
+ if (!dirty_width && text[i].width == max_width) {
+ dirty_width = true;
+ }
- // If this is the tallest line, we need to get the next tallest.
- if (height == line_height) {
+ if (dirty_height && dirty_width) {
+ break;
+ }
+ }
+
+ int diff = (p_to_line - p_from_line);
+ for (int i = p_to_line; i < text.size() - 1; i++) {
+ text.write[(i - diff) + 1] = text[i + 1];
+ }
+ text.resize(text.size() - diff);
+
+ if (dirty_height) {
_calculate_line_height();
}
- // If this is the longest line, we need to get the next longest.
- if (width == max_width) {
+ if (dirty_width) {
_calculate_max_line_width();
}
}
@@ -600,7 +650,7 @@ void TextEdit::_notification(int p_what) {
String highlighted_text = get_selected_text();
// Check if highlighted words contain only whitespaces (tabs or spaces).
- bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String();
+ bool only_whitespaces_highlighted = highlighted_text.strip_edges().is_empty();
const int caret_wrap_index = get_caret_wrap_index();
@@ -915,7 +965,7 @@ void TextEdit::_notification(int p_what) {
switch (gutter.type) {
case GUTTER_TYPE_STRING: {
const String &text = get_line_gutter_text(line, g);
- if (text == "") {
+ if (text.is_empty()) {
break;
}
@@ -1055,7 +1105,7 @@ void TextEdit::_notification(int p_what) {
while (highlighted_word_col != -1) {
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_word_col + start, highlighted_word_col + lookup_symbol_word.length() + start);
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y + (line_spacing / 2), sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1065,9 +1115,9 @@ void TextEdit::_notification(int p_what) {
} else if (rect.position.x + rect.size.x > xmargin_end) {
rect.size.x = xmargin_end - rect.position.x;
}
- rect.position.y = TS->shaped_text_get_ascent(rid) + font->get_underline_position(font_size);
- rect.size.y = font->get_underline_thickness(font_size);
- draw_rect(rect, font_selected_color);
+ rect.position.y += ceil(TS->shaped_text_get_ascent(rid)) + ceil(font->get_underline_position(font_size));
+ rect.size.y = MAX(1, font->get_underline_thickness(font_size));
+ draw_rect(rect, color);
}
highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1);
@@ -1224,7 +1274,7 @@ void TextEdit::_notification(int p_what) {
if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) {
caret.visible = true;
- if (draw_caret) {
+ if (draw_caret || drag_caret_force_displayed) {
if (caret_type == CaretType::CARET_TYPE_BLOCK || overtype_mode) {
//Block or underline caret, draw trailing carets at full height.
int h = font->get_height(font_size);
@@ -1391,7 +1441,7 @@ void TextEdit::_notification(int p_what) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
}
- if (deselect_on_focus_loss_enabled) {
+ if (deselect_on_focus_loss_enabled && !selection.drag_attempt) {
deselect();
}
} break;
@@ -1411,6 +1461,30 @@ void TextEdit::_notification(int p_what) {
update();
}
} break;
+ case Control::NOTIFICATION_DRAG_BEGIN: {
+ selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
+ drag_action = true;
+ dragging_minimap = false;
+ dragging_selection = false;
+ can_drag_minimap = false;
+ click_select_held->stop();
+ } break;
+ case Control::NOTIFICATION_DRAG_END: {
+ if (is_drag_successful()) {
+ if (selection.drag_attempt) {
+ selection.drag_attempt = false;
+ if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ delete_selection();
+ } else if (deselect_on_focus_loss_enabled) {
+ deselect();
+ }
+ }
+ } else {
+ selection.drag_attempt = false;
+ }
+ drag_action = false;
+ drag_caret_force_displayed = false;
+ } break;
}
}
@@ -1495,6 +1569,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
set_caret_line(row, false, false);
set_caret_column(col);
+ selection.drag_attempt = false;
if (mb->is_shift_pressed() && (caret.column != prev_col || caret.line != prev_line)) {
if (!selection.active) {
@@ -1538,6 +1613,9 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
+ } else if (is_mouse_over_selection()) {
+ selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
+ selection.drag_attempt = true;
} else {
selection.active = false;
selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER;
@@ -1551,6 +1629,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (!mb->is_double_click() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < triple_click_timeout && mb->get_position().distance_to(last_dblclk_pos) < triple_click_tolerance) {
// Triple-click select line.
selection.selecting_mode = SelectionMode::SELECTION_MODE_LINE;
+ selection.drag_attempt = false;
_update_selection_mode_line();
last_dblclk = 0;
} else if (mb->is_double_click() && text[caret.line].length()) {
@@ -1594,17 +1673,23 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
_generate_context_menu();
- menu->set_position(get_screen_transform().xform(mpos));
+ menu->set_position(get_screen_position() + mpos);
menu->reset_size();
menu->popup();
grab_focus();
}
} else {
if (mb->get_button_index() == MouseButton::LEFT) {
+ if (selection.drag_attempt && is_mouse_over_selection()) {
+ selection.active = false;
+ }
dragging_minimap = false;
dragging_selection = false;
can_drag_minimap = false;
click_select_held->stop();
+ if (!drag_action) {
+ selection.drag_attempt = false;
+ }
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CLIPBOARD_PRIMARY)) {
DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text());
}
@@ -1689,6 +1774,14 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
hovered_gutter = current_hovered_gutter;
update();
}
+
+ if (drag_action && can_drop_data(mpos, get_viewport()->gui_get_drag_data())) {
+ drag_caret_force_displayed = true;
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ set_caret_line(pos.y, false);
+ set_caret_column(pos.x);
+ dragging_selection = true;
+ }
}
if (draw_minimap && !dragging_selection) {
@@ -1827,7 +1920,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (context_menu_enabled) {
_generate_context_menu();
adjust_viewport_to_caret();
- menu->set_position(get_screen_transform().xform(get_caret_draw_pos()));
+ menu->set_position(get_screen_position() + get_caret_draw_pos());
menu->reset_size();
menu->popup();
menu->grab_focus();
@@ -2384,7 +2477,7 @@ void TextEdit::_update_caches() {
} else {
dir = (TextServer::Direction)text_direction;
}
- text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
text.set_font_features(opentype_features);
text.set_draw_control_chars(draw_control_chars);
text.set_font(font);
@@ -2406,6 +2499,75 @@ bool TextEdit::is_text_field() const {
return true;
}
+Variant TextEdit::get_drag_data(const Point2 &p_point) {
+ if (selection.active && selection.drag_attempt) {
+ String t = get_selected_text();
+ Label *l = memnew(Label);
+ l->set_text(t);
+ set_drag_preview(l);
+ return t;
+ }
+
+ return Variant();
+}
+
+bool TextEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
+ bool drop_override = Control::can_drop_data(p_point, p_data); // In case user wants to drop custom data.
+ if (drop_override) {
+ return drop_override;
+ }
+
+ return is_editable() && p_data.get_type() == Variant::STRING;
+}
+
+void TextEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
+ Control::drop_data(p_point, p_data);
+
+ if (p_data.get_type() == Variant::STRING && is_editable()) {
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ int caret_row_tmp = pos.y;
+ int caret_column_tmp = pos.x;
+ if (selection.drag_attempt) {
+ selection.drag_attempt = false;
+ if (!is_mouse_over_selection(!Input::get_singleton()->is_key_pressed(Key::CTRL))) {
+ begin_complex_operation();
+ if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ if (caret_row_tmp > selection.to_line) {
+ caret_row_tmp = caret_row_tmp - (selection.to_line - selection.from_line);
+ } else if (caret_row_tmp == selection.to_line && caret_column_tmp >= selection.to_column) {
+ caret_column_tmp = caret_column_tmp - (selection.to_column - selection.from_column);
+ }
+ delete_selection();
+ } else {
+ deselect();
+ }
+
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ end_complex_operation();
+ }
+ } else if (is_mouse_over_selection()) {
+ caret_row_tmp = selection.from_line;
+ caret_column_tmp = selection.from_column;
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ grab_focus();
+ } else {
+ deselect();
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ grab_focus();
+ }
+
+ if (caret_row_tmp != caret.line || caret_column_tmp != caret.column) {
+ select(caret_row_tmp, caret_column_tmp, caret.line, caret.column);
+ }
+ }
+}
+
Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
Point2i pos = get_line_column_at_pos(p_pos);
int row = pos.y;
@@ -2498,7 +2660,7 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) {
} else {
dir = (TextServer::Direction)text_direction;
}
- text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
text.invalidate_all();
if (menu_dir) {
@@ -2549,7 +2711,7 @@ void TextEdit::set_language(const String &p_language) {
} else {
dir = (TextServer::Direction)text_direction;
}
- text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
text.invalidate_all();
update();
}
@@ -3580,6 +3742,21 @@ bool TextEdit::is_dragging_cursor() const {
return dragging_selection || dragging_minimap;
}
+bool TextEdit::is_mouse_over_selection(bool p_edges) const {
+ if (!has_selection()) {
+ return false;
+ }
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ int row = pos.y;
+ int col = pos.x;
+ if (p_edges) {
+ if ((row == selection.from_line && col == selection.from_column) || (row == selection.to_line && col == selection.to_column)) {
+ return true;
+ }
+ }
+ return (row >= selection.from_line && row <= selection.to_line && (row > selection.from_line || col > selection.from_column) && (row < selection.to_line || col < selection.to_column));
+}
+
/* Caret */
void TextEdit::set_caret_type(CaretType p_type) {
caret_type = p_type;
@@ -4776,6 +4953,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_minimap_line_at_pos", "position"), &TextEdit::get_minimap_line_at_pos);
ClassDB::bind_method(D_METHOD("is_dragging_cursor"), &TextEdit::is_dragging_cursor);
+ ClassDB::bind_method(D_METHOD("is_mouse_over_selection", "edges"), &TextEdit::is_mouse_over_selection);
/* Caret. */
BIND_ENUM_CONSTANT(CARET_TYPE_LINE);
@@ -6160,11 +6338,11 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
ERR_FAIL_COND(p_char < 0);
/* STEP 1: Remove \r from source text and separate in substrings. */
-
- Vector<String> substrings = p_text.replace("\r", "").split("\n");
+ const String text_to_insert = p_text.replace("\r", "");
+ Vector<String> substrings = text_to_insert.split("\n");
// Is this just a new empty line?
- bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n";
+ bool shift_first_line = p_char == 0 && substrings.size() == 2 && text_to_insert == "\n";
/* STEP 2: Add spaces if the char is greater than the end of the line. */
while (p_char > text[p_line].length()) {
@@ -6172,24 +6350,19 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
/* STEP 3: Separate dest string in pre and post text. */
-
- String preinsert_text = text[p_line].substr(0, p_char);
String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
- for (int j = 0; j < substrings.size(); j++) {
- // Insert the substrings.
-
- if (j == 0) {
- text.set(p_line, preinsert_text + substrings[j], structured_text_parser(st_parser, st_args, preinsert_text + substrings[j]));
- } else {
- text.insert(p_line + j, substrings[j], structured_text_parser(st_parser, st_args, substrings[j]));
- }
+ substrings.write[0] = text[p_line].substr(0, p_char) + substrings[0];
+ substrings.write[substrings.size() - 1] += postinsert_text;
- if (j == substrings.size() - 1) {
- text.set(p_line + j, text[p_line + j] + postinsert_text, structured_text_parser(st_parser, st_args, text[p_line + j] + postinsert_text));
- }
+ Vector<Array> bidi_override;
+ bidi_override.resize(substrings.size());
+ for (int i = 0; i < substrings.size(); i++) {
+ bidi_override.write[i] = structured_text_parser(st_parser, st_args, substrings[i]);
}
+ text.insert(p_line, substrings, bidi_override);
+
if (shift_first_line) {
text.move_gutters(p_line, p_line + 1);
text.set_hidden(p_line + 1, text.is_hidden(p_line));
@@ -6222,7 +6395,7 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // 'from > to'.
ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // 'from > to'.
- String ret;
+ StringBuilder ret;
for (int i = p_from_line; i <= p_to_line; i++) {
int begin = (i == p_from_line) ? p_from_column : 0;
@@ -6234,7 +6407,7 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
ret += text[i].substr(begin, end - begin);
}
- return ret;
+ return ret.as_string();
}
void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
@@ -6248,9 +6421,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
String pre_text = text[p_from_line].substr(0, p_from_column);
String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
- for (int i = p_from_line; i < p_to_line; i++) {
- text.remove_at(p_from_line + 1);
- }
+ text.remove_range(p_from_line, p_to_line);
text.set(p_from_line, pre_text + post_text, structured_text_parser(st_parser, st_args, pre_text + post_text));
if (!text_changed_dirty && !setting_text) {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 42b21cbe9c..df3edca943 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -159,6 +159,7 @@ private:
mutable Vector<Line> text;
Ref<Font> font;
int font_size = -1;
+ int font_height = 0;
Dictionary opentype_features;
String language;
@@ -204,8 +205,8 @@ private:
}
}
bool is_hidden(int p_line) const { return text[p_line].hidden; }
- void insert(int p_at, const String &p_text, const Array &p_bidi_override);
- void remove_at(int p_index);
+ void insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override);
+ void remove_range(int p_from_line, int p_to_line);
int size() const { return text.size(); }
void clear();
@@ -375,6 +376,9 @@ private:
bool caret_mid_grapheme_enabled = false;
+ bool drag_action = false;
+ bool drag_caret_force_displayed = false;
+
void _emit_caret_changed();
void _reset_caret_blink_timer();
@@ -400,6 +404,7 @@ private:
int to_column = 0;
bool shiftclick_left = false;
+ bool drag_attempt = false;
} selection;
bool selecting_enabled = true;
@@ -611,6 +616,9 @@ public:
virtual Size2 get_minimum_size() const override;
virtual bool is_text_field() const override;
virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
+ virtual Variant get_drag_data(const Point2 &p_point) override;
+ virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
+ virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
virtual String get_tooltip(const Point2 &p_pos) const override;
void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata);
@@ -731,6 +739,7 @@ public:
int get_minimap_line_at_pos(const Point2i &p_pos) const;
bool is_dragging_cursor() const;
+ bool is_mouse_over_selection(bool p_edges = true) const;
/* Caret */
void set_caret_type(CaretType p_type);
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 8659ea06a2..3f0d907a7e 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -289,19 +289,19 @@ void TextureButton::_bind_methods() {
void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) {
normal = p_normal;
update();
- minimum_size_changed();
+ update_minimum_size();
}
void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) {
pressed = p_pressed;
update();
- minimum_size_changed();
+ update_minimum_size();
}
void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) {
hover = p_hover;
update();
- minimum_size_changed();
+ update_minimum_size();
}
void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
@@ -312,7 +312,7 @@ void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
click_mask = p_click_mask;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TextureButton::get_normal_texture() const {
@@ -349,7 +349,7 @@ bool TextureButton::get_expand() const {
void TextureButton::set_expand(bool p_expand) {
expand = p_expand;
- minimum_size_changed();
+ update_minimum_size();
update();
}
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index fe11de128a..6a926a0364 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -35,7 +35,7 @@
void TextureProgressBar::set_under_texture(const Ref<Texture2D> &p_texture) {
under = p_texture;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TextureProgressBar::get_under_texture() const {
@@ -46,7 +46,7 @@ void TextureProgressBar::set_over_texture(const Ref<Texture2D> &p_texture) {
over = p_texture;
update();
if (under.is_null()) {
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -58,7 +58,7 @@ void TextureProgressBar::set_stretch_margin(Side p_side, int p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
stretch_margin[p_side] = p_size;
update();
- minimum_size_changed();
+ update_minimum_size();
}
int TextureProgressBar::get_stretch_margin(Side p_side) const {
@@ -69,7 +69,7 @@ int TextureProgressBar::get_stretch_margin(Side p_side) const {
void TextureProgressBar::set_nine_patch_stretch(bool p_stretch) {
nine_patch_stretch = p_stretch;
update();
- minimum_size_changed();
+ update_minimum_size();
}
bool TextureProgressBar::get_nine_patch_stretch() const {
@@ -93,7 +93,7 @@ Size2 TextureProgressBar::get_minimum_size() const {
void TextureProgressBar::set_progress_texture(const Ref<Texture2D> &p_texture) {
progress = p_texture;
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TextureProgressBar::get_progress_texture() const {
@@ -387,7 +387,6 @@ void TextureProgressBar::draw_nine_patch_stretched(const Ref<Texture2D> &p_textu
}
void TextureProgressBar::_notification(int p_what) {
- const float corners[12] = { -0.125, -0.375, -0.625, -0.875, 0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875 };
switch (p_what) {
case NOTIFICATION_DRAW: {
if (nine_patch_stretch && (mode == FILL_LEFT_TO_RIGHT || mode == FILL_RIGHT_TO_LEFT || mode == FILL_TOP_TO_BOTTOM || mode == FILL_BOTTOM_TO_TOP || mode == FILL_BILINEAR_LEFT_AND_RIGHT || mode == FILL_BILINEAR_TOP_AND_BOTTOM)) {
@@ -452,7 +451,7 @@ void TextureProgressBar::_notification(int p_what) {
float val = get_as_ratio() * rad_max_degrees / 360;
if (val == 1) {
Rect2 region = Rect2(progress_offset, s);
- Rect2 source = Rect2(Point2(), s);
+ Rect2 source = Rect2(Point2(), progress->get_size());
draw_texture_rect_region(progress, region, source, tint_progress);
} else if (val != 0) {
Array pts;
@@ -466,16 +465,14 @@ void TextureProgressBar::_notification(int p_what) {
}
float end = start + direction * val;
- pts.append(start);
- pts.append(end);
float from = MIN(start, end);
float to = MAX(start, end);
- for (int i = 0; i < 12; i++) {
- if (corners[i] > from && corners[i] < to) {
- pts.append(corners[i]);
- }
+ pts.append(from);
+ for (float corner = Math::floor(from * 4 + 0.5) * 0.25 + 0.125; corner < to; corner += 0.25) {
+ pts.append(corner);
}
- pts.sort();
+ pts.append(to);
+
Vector<Point2> uvs;
Vector<Point2> points;
uvs.push_back(get_relative_center());
@@ -492,6 +489,8 @@ void TextureProgressBar::_notification(int p_what) {
colors.push_back(tint_progress);
draw_polygon(points, colors, uvs, progress);
}
+
+ // Draw a reference cross.
if (Engine::get_singleton()->is_editor_hint()) {
Point2 p;
@@ -502,6 +501,7 @@ void TextureProgressBar::_notification(int p_what) {
}
p *= get_relative_center();
+ p += progress_offset;
p = p.floor();
draw_line(p - Point2(8, 0), p + Point2(8, 0), Color(0.9, 0.5, 0.5), 2);
draw_line(p - Point2(0, 8), p + Point2(0, 8), Color(0.9, 0.5, 0.5), 2);
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index 1cba88e06f..85c15cdae7 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -152,7 +152,7 @@ void TextureRect::_bind_methods() {
void TextureRect::_texture_changed() {
if (texture.is_valid()) {
update();
- minimum_size_changed();
+ update_minimum_size();
}
}
@@ -172,7 +172,7 @@ void TextureRect::set_texture(const Ref<Texture2D> &p_tex) {
}
update();
- minimum_size_changed();
+ update_minimum_size();
}
Ref<Texture2D> TextureRect::get_texture() const {
@@ -182,7 +182,7 @@ Ref<Texture2D> TextureRect::get_texture() const {
void TextureRect::set_expand(bool p_expand) {
expand = p_expand;
update();
- minimum_size_changed();
+ update_minimum_size();
}
bool TextureRect::has_expand() const {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 89caaaafd0..5a6ac7c0d2 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1002,18 +1002,18 @@ bool TreeItem::is_custom_set_as_button(int p_column) const {
return cells[p_column].custom_button;
}
-void TreeItem::set_text_align(int p_column, TextAlign p_align) {
+void TreeItem::set_text_alignment(int p_column, HorizontalAlignment p_alignment) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells.write[p_column].text_align = p_align;
+ cells.write[p_column].text_alignment = p_alignment;
cells.write[p_column].cached_minimum_size_dirty = true;
_changed_notify(p_column);
}
-TreeItem::TextAlign TreeItem::get_text_align(int p_column) const {
- ERR_FAIL_INDEX_V(p_column, cells.size(), ALIGN_LEFT);
- return cells[p_column].text_align;
+HorizontalAlignment TreeItem::get_text_alignment(int p_column) const {
+ ERR_FAIL_INDEX_V(p_column, cells.size(), HORIZONTAL_ALIGNMENT_LEFT);
+ return cells[p_column].text_alignment;
}
void TreeItem::set_expand_right(int p_column, bool p_enable) {
@@ -1231,8 +1231,8 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tooltip", "column", "tooltip"), &TreeItem::set_tooltip);
ClassDB::bind_method(D_METHOD("get_tooltip", "column"), &TreeItem::get_tooltip);
- ClassDB::bind_method(D_METHOD("set_text_align", "column", "text_align"), &TreeItem::set_text_align);
- ClassDB::bind_method(D_METHOD("get_text_align", "column"), &TreeItem::get_text_align);
+ ClassDB::bind_method(D_METHOD("set_text_alignment", "column", "text_alignment"), &TreeItem::set_text_alignment);
+ ClassDB::bind_method(D_METHOD("get_text_alignment", "column"), &TreeItem::get_text_alignment);
ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right);
ClassDB::bind_method(D_METHOD("get_expand_right", "column"), &TreeItem::get_expand_right);
@@ -1278,10 +1278,6 @@ void TreeItem::_bind_methods() {
BIND_ENUM_CONSTANT(CELL_MODE_RANGE);
BIND_ENUM_CONSTANT(CELL_MODE_ICON);
BIND_ENUM_CONSTANT(CELL_MODE_CUSTOM);
-
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
}
void TreeItem::clear_children() {
@@ -1477,16 +1473,17 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co
}
w += ts.width;
- switch (p_cell.text_align) {
- case TreeItem::ALIGN_LEFT:
+ switch (p_cell.text_alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT: {
if (rtl) {
rect.position.x += MAX(0, (rect.size.width - w));
}
- break;
- case TreeItem::ALIGN_CENTER:
+ } break;
+ case HORIZONTAL_ALIGNMENT_CENTER:
rect.position.x += MAX(0, (rect.size.width - w) / 2);
break;
- case TreeItem::ALIGN_RIGHT:
+ case HORIZONTAL_ALIGNMENT_RIGHT:
if (!rtl) {
rect.position.x += MAX(0, (rect.size.width - w));
}
@@ -1539,7 +1536,7 @@ void Tree::update_column(int p_col) {
columns.write[p_col].text_buf->set_direction((TextServer::Direction)columns[p_col].text_direction);
}
- columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].opentype_features, (columns[p_col].language != "") ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
+ columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].opentype_features, !columns[p_col].language.is_empty() ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
}
void Tree::update_item_cell(TreeItem *p_item, int p_col) {
@@ -1547,7 +1544,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
p_item->cells.write[p_col].text_buf->clear();
if (p_item->cells[p_col].mode == TreeItem::CELL_MODE_RANGE) {
- if (p_item->cells[p_col].text != "") {
+ if (!p_item->cells[p_col].text.is_empty()) {
if (!p_item->cells[p_col].editable) {
return;
}
@@ -1574,7 +1571,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
valtext = p_item->cells[p_col].text;
}
- if (p_item->cells[p_col].suffix != String()) {
+ if (!p_item->cells[p_col].suffix.is_empty()) {
valtext += " " + p_item->cells[p_col].suffix;
}
@@ -1597,7 +1594,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
} else {
font_size = cache.font_size;
}
- p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, (p_item->cells[p_col].language != "") ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
+ p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, !p_item->cells[p_col].language.is_empty() ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
TS->shaped_text_set_bidi_override(p_item->cells[p_col].text_buf->get_rid(), structured_text_parser(p_item->cells[p_col].st_parser, p_item->cells[p_col].st_args, valtext));
p_item->cells.write[p_col].dirty = false;
}
@@ -1663,7 +1660,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].expand_right) {
int plus = 1;
- while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) {
+ while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text.is_empty() && p_item->cells[i + plus].icon.is_null()) {
w += get_column_width(i + plus);
plus++;
skip2++;
@@ -1860,7 +1857,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_RANGE: {
- if (p_item->cells[i].text != "") {
+ if (!p_item->cells[i].text.is_empty()) {
if (!p_item->cells[i].editable) {
break;
}
@@ -2340,7 +2337,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
if (p_item->cells[i].expand_right) {
int plus = 1;
- while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) {
+ while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text.is_empty() && p_item->cells[i + plus].icon.is_null()) {
col_width += cache.hseparation;
col_width += get_column_width(i + plus);
plus++;
@@ -2523,7 +2520,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
} break;
case TreeItem::CELL_MODE_RANGE: {
- if (c.text != "") {
+ if (!c.text.is_empty()) {
//if (x >= (get_column_width(col)-item_h/2)) {
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
@@ -2532,7 +2529,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
popup_menu->set_size(Size2(col_width, 0));
- popup_menu->set_position(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - cache.offset);
+ popup_menu->set_position(get_screen_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - cache.offset);
popup_menu->popup();
popup_edited_item = p_item;
popup_edited_item_col = col;
@@ -3433,7 +3430,7 @@ bool Tree::edit_selected() {
item_edited(col, s);
return true;
- } else if (c.mode == TreeItem::CELL_MODE_RANGE && c.text != "") {
+ } else if (c.mode == TreeItem::CELL_MODE_RANGE && !c.text.is_empty()) {
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
String s2 = c.text.get_slicec(',', i);
@@ -3441,7 +3438,7 @@ bool Tree::edit_selected() {
}
popup_menu->set_size(Size2(rect.size.width, 0));
- popup_menu->set_position(get_global_position() + rect.position + Point2i(0, rect.size.height));
+ popup_menu->set_position(get_screen_position() + rect.position + Point2i(0, rect.size.height));
popup_menu->popup();
popup_edited_item = s;
popup_edited_item_col = col;
@@ -4370,7 +4367,7 @@ void Tree::scroll_to_item(TreeItem *p_item) {
void Tree::set_h_scroll_enabled(bool p_enable) {
h_scroll_enabled = p_enable;
- minimum_size_changed();
+ update_minimum_size();
}
bool Tree::is_h_scroll_enabled() const {
@@ -4379,7 +4376,7 @@ bool Tree::is_h_scroll_enabled() const {
void Tree::set_v_scroll_enabled(bool p_enable) {
v_scroll_enabled = p_enable;
- minimum_size_changed();
+ update_minimum_size();
}
bool Tree::is_v_scroll_enabled() const {
@@ -4682,7 +4679,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const {
Size2 size = b->get_size() + cache.button_pressed->get_minimum_size();
if (pos.x > col_width - size.width) {
String tooltip = c.buttons[j].tooltip;
- if (tooltip != "") {
+ if (!tooltip.is_empty()) {
return tooltip;
}
}
@@ -4830,6 +4827,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_allow_reselect"), &Tree::get_allow_reselect);
ADD_PROPERTY(PropertyInfo(Variant::INT, "columns"), "set_columns", "get_columns");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "column_titles_visible"), "set_column_titles_visible", "are_column_titles_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index d4caec614a..a190567f0f 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -52,12 +52,6 @@ public:
CELL_MODE_CUSTOM, ///< Contains a custom value, show a string, and an edit button
};
- enum TextAlign {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT
- };
-
private:
friend class Tree;
@@ -98,7 +92,7 @@ private:
Size2i cached_minimum_size;
bool cached_minimum_size_dirty = true;
- TextAlign text_align = ALIGN_LEFT;
+ HorizontalAlignment text_alignment = HORIZONTAL_ALIGNMENT_LEFT;
Variant meta;
String tooltip;
@@ -316,8 +310,8 @@ public:
void set_tooltip(int p_column, const String &p_tooltip);
String get_tooltip(int p_column) const;
- void set_text_align(int p_column, TextAlign p_align);
- TextAlign get_text_align(int p_column) const;
+ void set_text_alignment(int p_column, HorizontalAlignment p_alignment);
+ HorizontalAlignment get_text_alignment(int p_column) const;
void set_expand_right(int p_column, bool p_enable);
bool get_expand_right(int p_column) const;
@@ -359,7 +353,6 @@ public:
};
VARIANT_ENUM_CAST(TreeItem::TreeCellMode);
-VARIANT_ENUM_CAST(TreeItem::TextAlign);
class VBoxContainer;
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_stream_player.cpp
index 989aabc549..a11d56a2ed 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_stream_player.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* video_player.cpp */
+/* video_stream_player.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "video_player.h"
+#include "video_stream_player.h"
#include "core/os/os.h"
#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
-int VideoPlayer::sp_get_channel_count() const {
+int VideoStreamPlayer::sp_get_channel_count() const {
if (playback.is_null()) {
return 0;
}
@@ -42,7 +42,7 @@ int VideoPlayer::sp_get_channel_count() const {
return playback->get_channels();
}
-bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) {
+bool VideoStreamPlayer::mix(AudioFrame *p_buffer, int p_frames) {
// Check the amount resampler can really handle.
// If it cannot, wait "wait_resampler_phase_limit" times.
// This mechanism contributes to smoother pause/unpause operation.
@@ -56,11 +56,11 @@ bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) {
}
// Called from main thread (e.g. VideoStreamPlaybackTheora::update).
-int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) {
+int VideoStreamPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) {
ERR_FAIL_NULL_V(p_udata, 0);
ERR_FAIL_NULL_V(p_data, 0);
- VideoPlayer *vp = (VideoPlayer *)p_udata;
+ VideoStreamPlayer *vp = (VideoStreamPlayer *)p_udata;
int todo = MIN(vp->resampler.get_writer_space(), p_frames);
@@ -75,13 +75,13 @@ int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_f
return todo;
}
-void VideoPlayer::_mix_audios(void *p_self) {
+void VideoStreamPlayer::_mix_audios(void *p_self) {
ERR_FAIL_NULL(p_self);
- reinterpret_cast<VideoPlayer *>(p_self)->_mix_audio();
+ reinterpret_cast<VideoStreamPlayer *>(p_self)->_mix_audio();
}
// Called from audio thread
-void VideoPlayer::_mix_audio() {
+void VideoStreamPlayer::_mix_audio() {
if (!stream.is_valid()) {
return;
}
@@ -126,7 +126,7 @@ void VideoPlayer::_mix_audio() {
}
}
-void VideoPlayer::_notification(int p_notification) {
+void VideoStreamPlayer::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE: {
AudioServer::get_singleton()->add_mix_callback(_mix_audios, this);
@@ -180,7 +180,7 @@ void VideoPlayer::_notification(int p_notification) {
};
};
-Size2 VideoPlayer::get_minimum_size() const {
+Size2 VideoStreamPlayer::get_minimum_size() const {
if (!expand && !texture.is_null()) {
return texture->get_size();
} else {
@@ -188,17 +188,17 @@ Size2 VideoPlayer::get_minimum_size() const {
}
}
-void VideoPlayer::set_expand(bool p_expand) {
+void VideoStreamPlayer::set_expand(bool p_expand) {
expand = p_expand;
update();
- minimum_size_changed();
+ update_minimum_size();
}
-bool VideoPlayer::has_expand() const {
+bool VideoStreamPlayer::has_expand() const {
return expand;
}
-void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
+void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stop();
AudioServer::get_singleton()->lock();
@@ -241,15 +241,15 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
update();
if (!expand) {
- minimum_size_changed();
+ update_minimum_size();
}
};
-Ref<VideoStream> VideoPlayer::get_stream() const {
+Ref<VideoStream> VideoStreamPlayer::get_stream() const {
return stream;
};
-void VideoPlayer::play() {
+void VideoStreamPlayer::play() {
ERR_FAIL_COND(!is_inside_tree());
if (playback.is_null()) {
return;
@@ -262,7 +262,7 @@ void VideoPlayer::play() {
last_audio_time = 0;
};
-void VideoPlayer::stop() {
+void VideoStreamPlayer::stop() {
if (!is_inside_tree()) {
return;
}
@@ -277,7 +277,7 @@ void VideoPlayer::stop() {
last_audio_time = 0;
};
-bool VideoPlayer::is_playing() const {
+bool VideoStreamPlayer::is_playing() const {
if (playback.is_null()) {
return false;
}
@@ -285,7 +285,7 @@ bool VideoPlayer::is_playing() const {
return playback->is_playing();
};
-void VideoPlayer::set_paused(bool p_paused) {
+void VideoStreamPlayer::set_paused(bool p_paused) {
paused = p_paused;
if (playback.is_valid()) {
playback->set_paused(p_paused);
@@ -294,35 +294,35 @@ void VideoPlayer::set_paused(bool p_paused) {
last_audio_time = 0;
};
-bool VideoPlayer::is_paused() const {
+bool VideoStreamPlayer::is_paused() const {
return paused;
}
-void VideoPlayer::set_buffering_msec(int p_msec) {
+void VideoStreamPlayer::set_buffering_msec(int p_msec) {
buffering_ms = p_msec;
}
-int VideoPlayer::get_buffering_msec() const {
+int VideoStreamPlayer::get_buffering_msec() const {
return buffering_ms;
}
-void VideoPlayer::set_audio_track(int p_track) {
+void VideoStreamPlayer::set_audio_track(int p_track) {
audio_track = p_track;
}
-int VideoPlayer::get_audio_track() const {
+int VideoStreamPlayer::get_audio_track() const {
return audio_track;
}
-void VideoPlayer::set_volume(float p_vol) {
+void VideoStreamPlayer::set_volume(float p_vol) {
volume = p_vol;
};
-float VideoPlayer::get_volume() const {
+float VideoStreamPlayer::get_volume() const {
return volume;
};
-void VideoPlayer::set_volume_db(float p_db) {
+void VideoStreamPlayer::set_volume_db(float p_db) {
if (p_db < -79) {
set_volume(0);
} else {
@@ -330,7 +330,7 @@ void VideoPlayer::set_volume_db(float p_db) {
}
};
-float VideoPlayer::get_volume_db() const {
+float VideoStreamPlayer::get_volume_db() const {
if (volume == 0) {
return -80;
} else {
@@ -338,27 +338,27 @@ float VideoPlayer::get_volume_db() const {
}
};
-String VideoPlayer::get_stream_name() const {
+String VideoStreamPlayer::get_stream_name() const {
if (stream.is_null()) {
return "<No Stream>";
}
return stream->get_name();
};
-float VideoPlayer::get_stream_position() const {
+float VideoStreamPlayer::get_stream_position() const {
if (playback.is_null()) {
return 0;
}
return playback->get_playback_position();
};
-void VideoPlayer::set_stream_position(float p_position) {
+void VideoStreamPlayer::set_stream_position(float p_position) {
if (playback.is_valid()) {
playback->seek(p_position);
}
}
-Ref<Texture2D> VideoPlayer::get_video_texture() const {
+Ref<Texture2D> VideoStreamPlayer::get_video_texture() const {
if (playback.is_valid()) {
return playback->get_texture();
}
@@ -366,22 +366,22 @@ Ref<Texture2D> VideoPlayer::get_video_texture() const {
return Ref<Texture2D>();
}
-void VideoPlayer::set_autoplay(bool p_enable) {
+void VideoStreamPlayer::set_autoplay(bool p_enable) {
autoplay = p_enable;
};
-bool VideoPlayer::has_autoplay() const {
+bool VideoStreamPlayer::has_autoplay() const {
return autoplay;
};
-void VideoPlayer::set_bus(const StringName &p_bus) {
+void VideoStreamPlayer::set_bus(const StringName &p_bus) {
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
AudioServer::get_singleton()->unlock();
}
-StringName VideoPlayer::get_bus() const {
+StringName VideoStreamPlayer::get_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
return bus;
@@ -390,7 +390,7 @@ StringName VideoPlayer::get_bus() const {
return "Master";
}
-void VideoPlayer::_validate_property(PropertyInfo &p_property) const {
+void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "bus") {
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
@@ -405,45 +405,45 @@ void VideoPlayer::_validate_property(PropertyInfo &p_property) const {
}
}
-void VideoPlayer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream);
- ClassDB::bind_method(D_METHOD("get_stream"), &VideoPlayer::get_stream);
+void VideoStreamPlayer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoStreamPlayer::set_stream);
+ ClassDB::bind_method(D_METHOD("get_stream"), &VideoStreamPlayer::get_stream);
- ClassDB::bind_method(D_METHOD("play"), &VideoPlayer::play);
- ClassDB::bind_method(D_METHOD("stop"), &VideoPlayer::stop);
+ ClassDB::bind_method(D_METHOD("play"), &VideoStreamPlayer::play);
+ ClassDB::bind_method(D_METHOD("stop"), &VideoStreamPlayer::stop);
- ClassDB::bind_method(D_METHOD("is_playing"), &VideoPlayer::is_playing);
+ ClassDB::bind_method(D_METHOD("is_playing"), &VideoStreamPlayer::is_playing);
- ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoPlayer::set_paused);
- ClassDB::bind_method(D_METHOD("is_paused"), &VideoPlayer::is_paused);
+ ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoStreamPlayer::set_paused);
+ ClassDB::bind_method(D_METHOD("is_paused"), &VideoStreamPlayer::is_paused);
- ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoPlayer::set_volume);
- ClassDB::bind_method(D_METHOD("get_volume"), &VideoPlayer::get_volume);
+ ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoStreamPlayer::set_volume);
+ ClassDB::bind_method(D_METHOD("get_volume"), &VideoStreamPlayer::get_volume);
- ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoPlayer::set_volume_db);
- ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoPlayer::get_volume_db);
+ ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoStreamPlayer::set_volume_db);
+ ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoStreamPlayer::get_volume_db);
- ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoPlayer::set_audio_track);
- ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoPlayer::get_audio_track);
+ ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoStreamPlayer::set_audio_track);
+ ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoStreamPlayer::get_audio_track);
- ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoPlayer::get_stream_name);
+ ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoStreamPlayer::get_stream_name);
- ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoPlayer::set_stream_position);
- ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoPlayer::get_stream_position);
+ ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoStreamPlayer::set_stream_position);
+ ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoStreamPlayer::get_stream_position);
- ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoPlayer::set_autoplay);
- ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoPlayer::has_autoplay);
+ ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoStreamPlayer::set_autoplay);
+ ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoStreamPlayer::has_autoplay);
- ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoPlayer::set_expand);
- ClassDB::bind_method(D_METHOD("has_expand"), &VideoPlayer::has_expand);
+ ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoStreamPlayer::set_expand);
+ ClassDB::bind_method(D_METHOD("has_expand"), &VideoStreamPlayer::has_expand);
- ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoPlayer::set_buffering_msec);
- ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoPlayer::get_buffering_msec);
+ ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoStreamPlayer::set_buffering_msec);
+ ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoStreamPlayer::get_buffering_msec);
- ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoPlayer::set_bus);
- ClassDB::bind_method(D_METHOD("get_bus"), &VideoPlayer::get_bus);
+ ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoStreamPlayer::set_bus);
+ ClassDB::bind_method(D_METHOD("get_bus"), &VideoStreamPlayer::get_bus);
- ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture);
+ ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoStreamPlayer::get_video_texture);
ADD_SIGNAL(MethodInfo("finished"));
@@ -461,9 +461,9 @@ void VideoPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
}
-VideoPlayer::VideoPlayer() {}
+VideoStreamPlayer::VideoStreamPlayer() {}
-VideoPlayer::~VideoPlayer() {
+VideoStreamPlayer::~VideoStreamPlayer() {
// if (stream_rid.is_valid())
// AudioServer::get_singleton()->free(stream_rid);
resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes
diff --git a/scene/gui/video_player.h b/scene/gui/video_stream_player.h
index 0edad296a1..ad4a3dd9e9 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_stream_player.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* video_player.h */
+/* video_stream_player.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VIDEO_PLAYER_H
-#define VIDEO_PLAYER_H
+#ifndef VIDEO_STREAM_PLAYER_H
+#define VIDEO_STREAM_PLAYER_H
#include "scene/gui/control.h"
#include "scene/resources/video_stream.h"
#include "servers/audio/audio_rb_resampler.h"
#include "servers/audio_server.h"
-class VideoPlayer : public Control {
- GDCLASS(VideoPlayer, Control);
+class VideoStreamPlayer : public Control {
+ GDCLASS(VideoStreamPlayer, Control);
struct Output {
AudioFrame vol;
@@ -119,8 +119,8 @@ public:
void set_bus(const StringName &p_bus);
StringName get_bus() const;
- VideoPlayer();
- ~VideoPlayer();
+ VideoStreamPlayer();
+ ~VideoStreamPlayer();
};
-#endif // VIDEO_PLAYER_H
+#endif // VIDEO_STREAM_PLAYER_H
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 22e3c3bf24..2022a9a46e 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -275,9 +275,6 @@ void CanvasItem::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
ERR_FAIL_COND(!is_inside_tree());
- _update_texture_filter_changed(false);
- _update_texture_repeat_changed(false);
-
first_draw = true;
Node *parent = get_parent();
if (parent) {
@@ -306,6 +303,10 @@ void CanvasItem::_notification(int p_what) {
}
}
_enter_canvas();
+
+ _update_texture_filter_changed(false);
+ _update_texture_repeat_changed(false);
+
if (!block_transform_notify && !xform_change.in_list()) {
get_tree()->xform_change_list.add(&xform_change);
}
@@ -648,16 +649,16 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
}
-void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
- p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
+ p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
}
-void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
- p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
+ p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
}
real_t CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const {
@@ -893,8 +894,8 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
- ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "align", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "align", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &CanvasItem::draw_char, DEFVAL(""), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)));
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh);
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 04376ad809..26a7068e68 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -235,8 +235,8 @@ public:
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
- void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index a4fcc04e20..4797729871 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -243,7 +243,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
}
}
- if (new_request != "") {
+ if (!new_request.is_empty()) {
// Process redirect
client->close();
int new_redirs = redirections + 1; // Because _request() will clear it
@@ -363,7 +363,7 @@ bool HTTPRequest::_update_connection() {
return true;
}
- if (download_to_file != String()) {
+ if (!download_to_file.is_empty()) {
file = FileAccess::open(download_to_file, FileAccess::WRITE);
if (!file) {
call_deferred(SNAME("_request_done"), RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray());
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 5e004d6863..87f77ed4bd 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -114,7 +114,7 @@ void Node::_notification(int p_notification) {
get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, false);
}
} break;
- case NOTIFICATION_PATH_CHANGED: {
+ case NOTIFICATION_PATH_RENAMED: {
if (data.path_cache) {
memdelete(data.path_cache);
data.path_cache = nullptr;
@@ -892,14 +892,14 @@ void Node::_set_name_nocheck(const StringName &p_name) {
void Node::set_name(const String &p_name) {
String name = p_name.validate_node_name();
- ERR_FAIL_COND(name == "");
+ ERR_FAIL_COND(name.is_empty());
data.name = name;
if (data.parent) {
data.parent->_validate_child_name(this);
}
- propagate_notification(NOTIFICATION_PATH_CHANGED);
+ propagate_notification(NOTIFICATION_PATH_RENAMED);
if (is_inside_tree()) {
emit_signal(SNAME("renamed"));
@@ -1990,7 +1990,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
nip->set_instance_path(ip->get_instance_path());
node = nip;
- } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_scene_file_path() != String()) {
+ } else if ((p_flags & DUPLICATE_USE_INSTANCING) && !get_scene_file_path().is_empty()) {
Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path());
ERR_FAIL_COND_V(res.is_null(), nullptr);
PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED;
@@ -2014,7 +2014,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
ERR_FAIL_COND_V(!node, nullptr);
}
- if (get_scene_file_path() != "") { //an instance
+ if (!get_scene_file_path().is_empty()) { //an instance
node->set_scene_file_path(get_scene_file_path());
node->data.editable_instance = data.editable_instance;
}
@@ -2046,7 +2046,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
node_tree.push_back(descendant);
- if (descendant->get_scene_file_path() != "" && instance_roots.has(descendant->get_owner())) {
+ if (!descendant->get_scene_file_path().is_empty() && instance_roots.has(descendant->get_owner())) {
instance_roots.push_back(descendant);
}
}
@@ -2829,7 +2829,7 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_INSTANCED);
BIND_CONSTANT(NOTIFICATION_DRAG_BEGIN);
BIND_CONSTANT(NOTIFICATION_DRAG_END);
- BIND_CONSTANT(NOTIFICATION_PATH_CHANGED);
+ BIND_CONSTANT(NOTIFICATION_PATH_RENAMED);
BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS);
BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE);
diff --git a/scene/main/node.h b/scene/main/node.h
index 2dd32a2e1d..dc74a33580 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -256,7 +256,7 @@ public:
NOTIFICATION_INSTANCED = 20,
NOTIFICATION_DRAG_BEGIN = 21,
NOTIFICATION_DRAG_END = 22,
- NOTIFICATION_PATH_CHANGED = 23,
+ NOTIFICATION_PATH_RENAMED = 23,
//NOTIFICATION_TRANSLATION_CHANGED = 24, moved below
NOTIFICATION_INTERNAL_PROCESS = 25,
NOTIFICATION_INTERNAL_PHYSICS_PROCESS = 26,
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index a122241cd0..2af8024fe4 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -510,7 +510,7 @@ bool SceneTree::process(double p_time) {
cpath = fallback->get_path();
}
if (cpath != env_path) {
- if (env_path != String()) {
+ if (!env_path.is_empty()) {
fallback = ResourceLoader::load(env_path);
if (fallback.is_null()) {
//could not load fallback, set as empty
@@ -1290,7 +1290,7 @@ void SceneTree::get_argument_options(const StringName &p_function, int p_idx, Li
dir_access->list_dir_begin();
String filename = dir_access->get_next();
- while (filename != "") {
+ while (!filename.is_empty()) {
if (filename == "." || filename == "..") {
filename = dir_access->get_next();
continue;
@@ -1400,7 +1400,7 @@ SceneTree::SceneTree() {
ResourceLoader::get_recognized_extensions_for_type("Environment", &exts);
String ext_hint;
for (const String &E : exts) {
- if (ext_hint != String()) {
+ if (!ext_hint.is_empty()) {
ext_hint += ",";
}
ext_hint += "*." + E;
@@ -1410,7 +1410,7 @@ SceneTree::SceneTree() {
// Setup property.
ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/defaults/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
env_path = env_path.strip_edges();
- if (env_path != String()) {
+ if (!env_path.is_empty()) {
Ref<Environment> env = ResourceLoader::load(env_path);
if (env.is_valid()) {
root->get_world_3d()->set_fallback_environment(env);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index f9e96a0784..af4032a77d 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -396,14 +396,15 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
- RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true);
+ RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false);
RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
- //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);
+ RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
#endif // _3D_DISABLED
+ set_physics_process_internal(true);
}
} break;
@@ -1182,7 +1183,7 @@ void Viewport::_gui_show_tooltip() {
Control *tooltip_owner = nullptr;
String tooltip_text = _gui_get_tooltip(
gui.tooltip_control,
- gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos),
+ gui.tooltip_control->get_screen_transform().xform_inv(gui.last_mouse_pos),
&tooltip_owner);
tooltip_text = tooltip_text.strip_edges();
if (tooltip_text.is_empty()) {
@@ -1707,13 +1708,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mm->get_button_mask() == MouseButton::NONE) {
// Nothing pressed.
- bool can_tooltip = true;
-
bool is_tooltip_shown = false;
if (gui.tooltip_popup) {
- if (can_tooltip && gui.tooltip_control) {
- String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos));
+ if (gui.tooltip_control) {
+ String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_screen_transform().xform_inv(mpos));
if (tooltip.length() == 0) {
_gui_cancel_tooltip();
@@ -1737,7 +1736,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- if (can_tooltip && !is_tooltip_shown) {
+ if (!is_tooltip_shown && over->can_process()) {
if (gui.tooltip_timer.is_valid()) {
gui.tooltip_timer->release_connections();
gui.tooltip_timer = Ref<SceneTreeTimer>();
@@ -1870,14 +1869,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
gui.drag_mouse_over_pos = localizer.xform(viewport_pos);
- if ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
- bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
+ bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
- if (!can_drop) {
- ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN;
- } else {
- ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP;
- }
+ if (!can_drop) {
+ ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN;
+ } else {
+ ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP;
}
}
@@ -2045,6 +2042,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *
if (p_control) {
_gui_set_drag_preview(p_base, p_control);
}
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
}
void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp
index 7df601492b..e3c65bbc6e 100644
--- a/scene/property_utils.cpp
+++ b/scene/property_utils.cpp
@@ -164,7 +164,7 @@ Vector<SceneState::PackState> PropertyUtils::get_node_states_stack(const Node *p
}
}
break;
- } else if (n->get_scene_file_path() != String()) {
+ } else if (!n->get_scene_file_path().is_empty()) {
const Ref<SceneState> &state = n->get_scene_instance_state();
_collect_inheritance_chain(state, n->get_path_to(p_node), states_stack);
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 056ace5e4e..9023b758b6 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -123,7 +123,7 @@
#include "scene/gui/texture_progress_bar.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
-#include "scene/gui/video_player.h"
+#include "scene/gui/video_stream_player.h"
#include "scene/main/canvas_item.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/http_request.h"
@@ -232,7 +232,6 @@
#include "scene/3d/path_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/position_3d.h"
-#include "scene/3d/proximity_group_3d.h"
#include "scene/3d/ray_cast_3d.h"
#include "scene/3d/reflection_probe.h"
#include "scene/3d/remote_transform_3d.h"
@@ -361,7 +360,7 @@ void register_scene_types() {
GDREGISTER_CLASS(ItemList);
GDREGISTER_CLASS(LineEdit);
- GDREGISTER_CLASS(VideoPlayer);
+ GDREGISTER_CLASS(VideoStreamPlayer);
#ifndef ADVANCED_GUI_DISABLED
GDREGISTER_CLASS(FileDialog);
@@ -477,14 +476,14 @@ void register_scene_types() {
GDREGISTER_VIRTUAL_CLASS(Lightmapper);
GDREGISTER_CLASS(GPUParticles3D);
GDREGISTER_VIRTUAL_CLASS(GPUParticlesCollision3D);
- GDREGISTER_CLASS(GPUParticlesCollisionBox);
- GDREGISTER_CLASS(GPUParticlesCollisionSphere);
- GDREGISTER_CLASS(GPUParticlesCollisionSDF);
- GDREGISTER_CLASS(GPUParticlesCollisionHeightField);
+ GDREGISTER_CLASS(GPUParticlesCollisionBox3D);
+ GDREGISTER_CLASS(GPUParticlesCollisionSphere3D);
+ GDREGISTER_CLASS(GPUParticlesCollisionSDF3D);
+ GDREGISTER_CLASS(GPUParticlesCollisionHeightField3D);
GDREGISTER_VIRTUAL_CLASS(GPUParticlesAttractor3D);
- GDREGISTER_CLASS(GPUParticlesAttractorBox);
- GDREGISTER_CLASS(GPUParticlesAttractorSphere);
- GDREGISTER_CLASS(GPUParticlesAttractorVectorField);
+ GDREGISTER_CLASS(GPUParticlesAttractorBox3D);
+ GDREGISTER_CLASS(GPUParticlesAttractorSphere3D);
+ GDREGISTER_CLASS(GPUParticlesAttractorVectorField3D);
GDREGISTER_CLASS(CPUParticles3D);
GDREGISTER_CLASS(Position3D);
@@ -511,7 +510,6 @@ void register_scene_types() {
GDREGISTER_CLASS(VehicleBody3D);
GDREGISTER_CLASS(VehicleWheel3D);
GDREGISTER_CLASS(Area3D);
- GDREGISTER_CLASS(ProximityGroup3D);
GDREGISTER_CLASS(CollisionShape3D);
GDREGISTER_CLASS(CollisionPolygon3D);
GDREGISTER_CLASS(RayCast3D);
@@ -933,6 +931,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D");
ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D");
ClassDB::add_compatibility_class("Light", "Light3D");
+ ClassDB::add_compatibility_class("Light2D", "PointLight2D");
ClassDB::add_compatibility_class("LineShape2D", "WorldBoundaryShape2D");
ClassDB::add_compatibility_class("Listener", "AudioListener3D");
ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D");
@@ -964,7 +963,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("PinJoint", "PinJoint3D");
ClassDB::add_compatibility_class("PlaneShape", "WorldBoundaryShape3D");
ClassDB::add_compatibility_class("ProceduralSky", "Sky");
- ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D");
ClassDB::add_compatibility_class("RayCast", "RayCast3D");
ClassDB::add_compatibility_class("RayShape", "SeparationRayShape3D");
ClassDB::add_compatibility_class("RayShape2D", "SeparationRayShape2D");
@@ -986,13 +984,17 @@ void register_scene_types() {
ClassDB::add_compatibility_class("SpringArm", "SpringArm3D");
ClassDB::add_compatibility_class("Sprite", "Sprite2D");
ClassDB::add_compatibility_class("StaticBody", "StaticBody3D");
+ ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D");
ClassDB::add_compatibility_class("TextureProgress", "TextureProgressBar");
ClassDB::add_compatibility_class("VehicleBody", "VehicleBody3D");
ClassDB::add_compatibility_class("VehicleWheel", "VehicleWheel3D");
+ ClassDB::add_compatibility_class("VideoPlayer", "VideoStreamPlayer");
ClassDB::add_compatibility_class("ViewportContainer", "SubViewportContainer");
ClassDB::add_compatibility_class("Viewport", "SubViewport");
ClassDB::add_compatibility_class("VisibilityEnabler", "VisibleOnScreenEnabler3D");
ClassDB::add_compatibility_class("VisibilityNotifier", "VisibleOnScreenNotifier3D");
+ ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D");
+ ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D");
ClassDB::add_compatibility_class("VisualServer", "RenderingServer");
ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant");
ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc");
@@ -1010,11 +1012,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch");
ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp");
ClassDB::add_compatibility_class("World", "World3D");
- ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D");
- ClassDB::add_compatibility_class("Light2D", "PointLight2D");
- ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D");
- ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D");
-
#endif /* DISABLE_DEPRECATED */
OS::get_singleton()->yield(); // may take time to init
@@ -1031,6 +1028,16 @@ void register_scene_types() {
GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i + 1), "");
}
+ if (RenderingServer::get_singleton()) {
+ ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed.
+ }
+
+ SceneDebugger::initialize();
+
+ NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
+}
+
+void initialize_theme() {
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/use_hidpi", PropertyInfo(Variant::BOOL, "gui/theme/use_hidpi", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
@@ -1039,7 +1046,7 @@ void register_scene_types() {
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
Ref<Font> font;
- if (font_path != String()) {
+ if (!font_path.is_empty()) {
font = ResourceLoader::load(font_path);
if (!font.is_valid()) {
ERR_PRINT("Error loading custom font '" + font_path + "'");
@@ -1049,10 +1056,9 @@ void register_scene_types() {
// 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_hidpi, font);
- ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed.
}
- if (theme_path != String()) {
+ if (!theme_path.is_empty()) {
Ref<Theme> theme = ResourceLoader::load(theme_path);
if (theme.is_valid()) {
Theme::set_project_default(theme);
@@ -1063,9 +1069,6 @@ void register_scene_types() {
ERR_PRINT("Error loading custom theme '" + theme_path + "'");
}
}
- SceneDebugger::initialize();
-
- NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
}
void unregister_scene_types() {
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index 1ff542eef8..32ab165fb3 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -34,4 +34,6 @@
void register_scene_types();
void unregister_scene_types();
+void initialize_theme();
+
#endif
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index e3cf9183a0..255d0ececd 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -3998,13 +3998,12 @@ bool Animation::_blend_shape_track_optimize_key(const TKey<float> &t0, const TKe
float v1 = t1.value;
float v2 = t2.value;
- if (Math::is_equal_approx(v1, v2, p_allowed_unit_error)) {
+ if (Math::is_equal_approx(v1, v2, (float)p_allowed_unit_error)) {
//0 and 2 are close, let's see if 1 is close
- if (!Math::is_equal_approx(v0, v1, p_allowed_unit_error)) {
+ if (!Math::is_equal_approx(v0, v1, (float)p_allowed_unit_error)) {
//not close, not optimizable
return false;
}
-
} else {
/*
TODO eventually discuss a way to optimize these better.
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index b87639de6a..bf3efd7599 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -33,15 +33,15 @@
#include "core/core_string_names.h"
template <class T>
-static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control_2, T end) {
+static _FORCE_INLINE_ T _bezier_interp(real_t p_t, T p_start, T p_control_1, T p_control_2, T p_end) {
/* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - t);
+ real_t omt = (1.0 - p_t);
real_t omt2 = omt * omt;
real_t omt3 = omt2 * omt;
- real_t t2 = t * t;
- real_t t3 = t2 * t;
+ real_t t2 = p_t * p_t;
+ real_t t3 = t2 * p_t;
- return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
+ return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3;
}
const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
@@ -49,46 +49,46 @@ const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
Curve::Curve() {
}
-int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) {
+int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) {
// Add a point and preserve order
// Curve bounds is in 0..1
- if (p_pos.x > MAX_X) {
- p_pos.x = MAX_X;
- } else if (p_pos.x < MIN_X) {
- p_pos.x = MIN_X;
+ if (p_position.x > MAX_X) {
+ p_position.x = MAX_X;
+ } else if (p_position.x < MIN_X) {
+ p_position.x = MIN_X;
}
int ret = -1;
if (_points.size() == 0) {
- _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
} else if (_points.size() == 1) {
// TODO Is the `else` able to handle this block already?
- real_t diff = p_pos.x - _points[0].pos.x;
+ real_t diff = p_position.x - _points[0].position.x;
if (diff > 0) {
- _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 1;
} else {
- _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
}
} else {
- int i = get_index(p_pos.x);
+ int i = get_index(p_position.x);
- if (i == 0 && p_pos.x < _points[0].pos.x) {
+ if (i == 0 && p_position.x < _points[0].position.x) {
// Insert before anything else
- _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
} else {
// Insert between i and i+1
++i;
- _points.insert(i, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(i, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = i;
}
}
@@ -100,7 +100,7 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
return ret;
}
-int Curve::get_index(real_t offset) const {
+int Curve::get_index(real_t p_offset) const {
// Lower-bound float binary search
int imin = 0;
@@ -109,13 +109,13 @@ int Curve::get_index(real_t offset) const {
while (imax - imin > 1) {
int m = (imin + imax) / 2;
- real_t a = _points[m].pos.x;
- real_t b = _points[m + 1].pos.x;
+ real_t a = _points[m].position.x;
+ real_t b = _points[m + 1].position.x;
- if (a < offset && b < offset) {
+ if (a < p_offset && b < p_offset) {
imin = m;
- } else if (a > offset) {
+ } else if (a > p_offset) {
imax = m;
} else {
@@ -124,7 +124,7 @@ int Curve::get_index(real_t offset) const {
}
// Will happen if the offset is out of bounds
- if (offset > _points[imax].pos.x) {
+ if (p_offset > _points[imax].position.x) {
return imax;
}
return imin;
@@ -134,7 +134,7 @@ void Curve::clean_dupes() {
bool dirty = false;
for (int i = 1; i < _points.size(); ++i) {
- real_t diff = _points[i - 1].pos.x - _points[i].pos.x;
+ real_t diff = _points[i - 1].position.x - _points[i].position.x;
if (diff <= CMP_EPSILON) {
_points.remove_at(i);
--i;
@@ -147,62 +147,62 @@ void Curve::clean_dupes() {
}
}
-void Curve::set_point_left_tangent(int i, real_t tangent) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].left_tangent = tangent;
- _points.write[i].left_mode = TANGENT_FREE;
+void Curve::set_point_left_tangent(int p_index, real_t p_tangent) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].left_tangent = p_tangent;
+ _points.write[p_index].left_mode = TANGENT_FREE;
mark_dirty();
}
-void Curve::set_point_right_tangent(int i, real_t tangent) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].right_tangent = tangent;
- _points.write[i].right_mode = TANGENT_FREE;
+void Curve::set_point_right_tangent(int p_index, real_t p_tangent) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].right_tangent = p_tangent;
+ _points.write[p_index].right_mode = TANGENT_FREE;
mark_dirty();
}
-void Curve::set_point_left_mode(int i, TangentMode p_mode) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].left_mode = p_mode;
- if (i > 0) {
+void Curve::set_point_left_mode(int p_index, TangentMode p_mode) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].left_mode = p_mode;
+ if (p_index > 0) {
if (p_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - _points[i].pos).normalized();
- _points.write[i].left_tangent = v.y / v.x;
+ Vector2 v = (_points[p_index - 1].position - _points[p_index].position).normalized();
+ _points.write[p_index].left_tangent = v.y / v.x;
}
}
mark_dirty();
}
-void Curve::set_point_right_mode(int i, TangentMode p_mode) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].right_mode = p_mode;
- if (i + 1 < _points.size()) {
+void Curve::set_point_right_mode(int p_index, TangentMode p_mode) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].right_mode = p_mode;
+ if (p_index + 1 < _points.size()) {
if (p_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - _points[i].pos).normalized();
- _points.write[i].right_tangent = v.y / v.x;
+ Vector2 v = (_points[p_index + 1].position - _points[p_index].position).normalized();
+ _points.write[p_index].right_tangent = v.y / v.x;
}
}
mark_dirty();
}
-real_t Curve::get_point_left_tangent(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), 0);
- return _points[i].left_tangent;
+real_t Curve::get_point_left_tangent(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), 0);
+ return _points[p_index].left_tangent;
}
-real_t Curve::get_point_right_tangent(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), 0);
- return _points[i].right_tangent;
+real_t Curve::get_point_right_tangent(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), 0);
+ return _points[p_index].right_tangent;
}
-Curve::TangentMode Curve::get_point_left_mode(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE);
- return _points[i].left_mode;
+Curve::TangentMode Curve::get_point_left_mode(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE);
+ return _points[p_index].left_mode;
}
-Curve::TangentMode Curve::get_point_right_mode(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE);
- return _points[i].right_mode;
+Curve::TangentMode Curve::get_point_right_mode(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE);
+ return _points[p_index].right_mode;
}
void Curve::remove_point(int p_index) {
@@ -216,18 +216,18 @@ void Curve::clear_points() {
mark_dirty();
}
-void Curve::set_point_value(int p_index, real_t pos) {
+void Curve::set_point_value(int p_index, real_t p_position) {
ERR_FAIL_INDEX(p_index, _points.size());
- _points.write[p_index].pos.y = pos;
+ _points.write[p_index].position.y = p_position;
update_auto_tangents(p_index);
mark_dirty();
}
-int Curve::set_point_offset(int p_index, float offset) {
+int Curve::set_point_offset(int p_index, real_t p_offset) {
ERR_FAIL_INDEX_V(p_index, _points.size(), -1);
Point p = _points[p_index];
remove_point(p_index);
- int i = add_point(Vector2(offset, p.pos.y));
+ int i = add_point(Vector2(p_offset, p.position.y));
_points.write[i].left_tangent = p.left_tangent;
_points.write[i].right_tangent = p.right_tangent;
_points.write[i].left_mode = p.left_mode;
@@ -241,7 +241,7 @@ int Curve::set_point_offset(int p_index, float offset) {
Vector2 Curve::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), Vector2(0, 0));
- return _points[p_index].pos;
+ return _points[p_index].position;
}
Curve::Point Curve::get_point(int p_index) const {
@@ -249,35 +249,35 @@ Curve::Point Curve::get_point(int p_index) const {
return _points[p_index];
}
-void Curve::update_auto_tangents(int i) {
- Point &p = _points.write[i];
+void Curve::update_auto_tangents(int p_index) {
+ Point &p = _points.write[p_index];
- if (i > 0) {
+ if (p_index > 0) {
if (p.left_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - p.pos).normalized();
+ Vector2 v = (_points[p_index - 1].position - p.position).normalized();
p.left_tangent = v.y / v.x;
}
- if (_points[i - 1].right_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - p.pos).normalized();
- _points.write[i - 1].right_tangent = v.y / v.x;
+ if (_points[p_index - 1].right_mode == TANGENT_LINEAR) {
+ Vector2 v = (_points[p_index - 1].position - p.position).normalized();
+ _points.write[p_index - 1].right_tangent = v.y / v.x;
}
}
- if (i + 1 < _points.size()) {
+ if (p_index + 1 < _points.size()) {
if (p.right_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - p.pos).normalized();
+ Vector2 v = (_points[p_index + 1].position - p.position).normalized();
p.right_tangent = v.y / v.x;
}
- if (_points[i + 1].left_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - p.pos).normalized();
- _points.write[i + 1].left_tangent = v.y / v.x;
+ if (_points[p_index + 1].left_mode == TANGENT_LINEAR) {
+ Vector2 v = (_points[p_index + 1].position - p.position).normalized();
+ _points.write[p_index + 1].left_tangent = v.y / v.x;
}
}
}
#define MIN_Y_RANGE 0.01
-void Curve::set_min_value(float p_min) {
+void Curve::set_min_value(real_t p_min) {
if (_minmax_set_once & 0b11 && p_min > _max_value - MIN_Y_RANGE) {
_min_value = _max_value - MIN_Y_RANGE;
} else {
@@ -289,7 +289,7 @@ void Curve::set_min_value(float p_min) {
emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
-void Curve::set_max_value(float p_max) {
+void Curve::set_max_value(real_t p_max) {
if (_minmax_set_once & 0b11 && p_max < _min_value + MIN_Y_RANGE) {
_max_value = _min_value + MIN_Y_RANGE;
} else {
@@ -299,32 +299,32 @@ void Curve::set_max_value(float p_max) {
emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
-real_t Curve::interpolate(real_t offset) const {
+real_t Curve::interpolate(real_t p_offset) const {
if (_points.size() == 0) {
return 0;
}
if (_points.size() == 1) {
- return _points[0].pos.y;
+ return _points[0].position.y;
}
- int i = get_index(offset);
+ int i = get_index(p_offset);
if (i == _points.size() - 1) {
- return _points[i].pos.y;
+ return _points[i].position.y;
}
- real_t local = offset - _points[i].pos.x;
+ real_t local = p_offset - _points[i].position.x;
if (i == 0 && local <= 0) {
- return _points[0].pos.y;
+ return _points[0].position.y;
}
return interpolate_local_nocheck(i, local);
}
-real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
- const Point a = _points[index];
- const Point b = _points[index + 1];
+real_t Curve::interpolate_local_nocheck(int p_index, real_t p_local_offset) const {
+ const Point a = _points[p_index];
+ const Point b = _points[p_index + 1];
/* Cubic bezier
*
@@ -341,16 +341,16 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
*/
// Control points are chosen at equal distances
- real_t d = b.pos.x - a.pos.x;
- if (Math::abs(d) <= CMP_EPSILON) {
- return b.pos.y;
+ real_t d = b.position.x - a.position.x;
+ if (Math::is_zero_approx(d)) {
+ return b.position.y;
}
- local_offset /= d;
+ p_local_offset /= d;
d /= 3.0;
- real_t yac = a.pos.y + d * a.right_tangent;
- real_t ybc = b.pos.y - d * b.left_tangent;
+ real_t yac = a.position.y + d * a.right_tangent;
+ real_t ybc = b.position.y - d * b.left_tangent;
- real_t y = _bezier_interp(local_offset, a.pos.y, yac, ybc, b.pos.y);
+ real_t y = _bezier_interp(p_local_offset, a.position.y, yac, ybc, b.position.y);
return y;
}
@@ -369,7 +369,7 @@ Array Curve::get_data() const {
const Point p = _points[j];
int i = j * ELEMS;
- output[i] = p.pos;
+ output[i] = p.position;
output[i + 1] = p.left_tangent;
output[i + 2] = p.right_tangent;
output[i + 3] = p.left_mode;
@@ -379,39 +379,39 @@ Array Curve::get_data() const {
return output;
}
-void Curve::set_data(Array input) {
+void Curve::set_data(const Array p_input) {
const unsigned int ELEMS = 5;
- ERR_FAIL_COND(input.size() % ELEMS != 0);
+ ERR_FAIL_COND(p_input.size() % ELEMS != 0);
_points.clear();
// Validate input
- for (int i = 0; i < input.size(); i += ELEMS) {
- ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2);
- ERR_FAIL_COND(!input[i + 1].is_num());
- ERR_FAIL_COND(input[i + 2].get_type() != Variant::FLOAT);
+ for (int i = 0; i < p_input.size(); i += ELEMS) {
+ ERR_FAIL_COND(p_input[i].get_type() != Variant::VECTOR2);
+ ERR_FAIL_COND(!p_input[i + 1].is_num());
+ ERR_FAIL_COND(p_input[i + 2].get_type() != Variant::FLOAT);
- ERR_FAIL_COND(input[i + 3].get_type() != Variant::INT);
- int left_mode = input[i + 3];
+ ERR_FAIL_COND(p_input[i + 3].get_type() != Variant::INT);
+ int left_mode = p_input[i + 3];
ERR_FAIL_COND(left_mode < 0 || left_mode >= TANGENT_MODE_COUNT);
- ERR_FAIL_COND(input[i + 4].get_type() != Variant::INT);
- int right_mode = input[i + 4];
+ ERR_FAIL_COND(p_input[i + 4].get_type() != Variant::INT);
+ int right_mode = p_input[i + 4];
ERR_FAIL_COND(right_mode < 0 || right_mode >= TANGENT_MODE_COUNT);
}
- _points.resize(input.size() / ELEMS);
+ _points.resize(p_input.size() / ELEMS);
for (int j = 0; j < _points.size(); ++j) {
Point &p = _points.write[j];
int i = j * ELEMS;
- p.pos = input[i];
- p.left_tangent = input[i + 1];
- p.right_tangent = input[i + 2];
+ p.position = p_input[i];
+ p.left_tangent = p_input[i + 1];
+ p.right_tangent = p_input[i + 2];
// TODO For some reason the compiler won't convert from Variant to enum
- int left_mode = input[i + 3];
- int right_mode = input[i + 4];
+ int left_mode = p_input[i + 3];
+ int right_mode = p_input[i + 4];
p.left_mode = (TangentMode)left_mode;
p.right_mode = (TangentMode)right_mode;
}
@@ -431,8 +431,8 @@ void Curve::bake() {
}
if (_points.size() != 0) {
- _baked_cache.write[0] = _points[0].pos.y;
- _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].pos.y;
+ _baked_cache.write[0] = _points[0].position.y;
+ _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].position.y;
}
_baked_cache_dirty = false;
@@ -445,7 +445,7 @@ void Curve::set_bake_resolution(int p_resolution) {
_baked_cache_dirty = true;
}
-real_t Curve::interpolate_baked(real_t offset) const {
+real_t Curve::interpolate_baked(real_t p_offset) const {
if (_baked_cache_dirty) {
// Last-second bake if not done already
const_cast<Curve *>(this)->bake();
@@ -456,13 +456,13 @@ real_t Curve::interpolate_baked(real_t offset) const {
if (_points.size() == 0) {
return 0;
}
- return _points[0].pos.y;
+ return _points[0].position.y;
} else if (_baked_cache.size() == 1) {
return _baked_cache[0];
}
// Get interpolation index
- real_t fi = offset * _baked_cache.size();
+ real_t fi = p_offset * _baked_cache.size();
int i = Math::floor(fi);
if (i < 0) {
i = 0;
@@ -481,7 +481,7 @@ real_t Curve::interpolate_baked(real_t offset) const {
}
}
-void Curve::ensure_default_setup(float p_min, float p_max) {
+void Curve::ensure_default_setup(real_t p_min, real_t p_max) {
if (_points.size() == 0 && _min_value == 0 && _max_value == 1) {
add_point(Vector2(0, 1));
add_point(Vector2(1, 1));
@@ -535,9 +535,9 @@ int Curve2D::get_point_count() const {
return points.size();
}
-void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
+void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
Point n;
- n.pos = p_pos;
+ n.position = p_position;
n.in = p_in;
n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) {
@@ -550,17 +550,17 @@ void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) {
+void Curve2D::set_point_position(int p_index, const Vector2 &p_position) {
ERR_FAIL_INDEX(p_index, points.size());
- points.write[p_index].pos = p_pos;
+ points.write[p_index].position = p_position;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
Vector2 Curve2D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
- return points[p_index].pos;
+ return points[p_index].position;
}
void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
@@ -604,19 +604,19 @@ void Curve2D::clear_points() {
}
}
-Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
+Vector2 Curve2D::interpolate(int p_index, const real_t p_offset) const {
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector2());
if (p_index >= pc - 1) {
- return points[pc - 1].pos;
+ return points[pc - 1].position;
} else if (p_index < 0) {
- return points[0].pos;
+ return points[0].position;
}
- Vector2 p0 = points[p_index].pos;
+ Vector2 p0 = points[p_index].position;
Vector2 p1 = p0 + points[p_index].out;
- Vector2 p3 = points[p_index + 1].pos;
+ Vector2 p3 = points[p_index + 1].position;
Vector2 p2 = p3 + points[p_index + 1].in;
return _bezier_interp(p_offset, p0, p1, p2, p3);
@@ -632,15 +632,15 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const {
- float mp = p_begin + (p_end - p_begin) * 0.5;
+void Curve2D::_bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+ real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 na = (mid - beg).normalized();
Vector2 nb = (end - mid).normalized();
- float dp = na.dot(nb);
+ real_t dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
r_bake[mp] = mid;
@@ -668,47 +668,47 @@ void Curve2D::_bake() const {
if (points.size() == 1) {
baked_point_cache.resize(1);
- baked_point_cache.set(0, points[0].pos);
+ baked_point_cache.set(0, points[0].position);
baked_dist_cache.resize(1);
baked_dist_cache.set(0, 0.0);
return;
}
- Vector2 pos = points[0].pos;
- float dist = 0.0;
+ Vector2 position = points[0].position;
+ real_t dist = 0.0;
List<Vector2> pointlist;
- List<float> distlist;
+ List<real_t> distlist;
- pointlist.push_back(pos); //start always from origin
+ pointlist.push_back(position); //start always from origin
distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
- float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0.0;
+ real_t step = 0.1; // at least 10 substeps ought to be enough?
+ real_t p = 0.0;
while (p < 1.0) {
- float np = p + step;
+ real_t np = p + step;
if (np > 1.0) {
np = 1.0;
}
- Vector2 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- float d = pos.distance_to(npp);
+ Vector2 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ real_t d = position.distance_to(npp);
if (d > bake_interval) {
// OK! between P and NP there _has_ to be Something, let's go searching!
int iterations = 10; //lots of detail!
- float low = p;
- float hi = np;
- float mid = low + (hi - low) * 0.5;
+ real_t low = p;
+ real_t hi = np;
+ real_t mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
- npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- d = pos.distance_to(npp);
+ npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ d = position.distance_to(npp);
if (bake_interval < d) {
hi = mid;
@@ -718,11 +718,11 @@ void Curve2D::_bake() const {
mid = low + (hi - low) * 0.5;
}
- pos = npp;
+ position = npp;
p = mid;
dist += d;
- pointlist.push_back(pos);
+ pointlist.push_back(position);
distlist.push_back(dist);
} else {
p = np;
@@ -730,9 +730,9 @@ void Curve2D::_bake() const {
}
}
- Vector2 lastpos = points[points.size() - 1].pos;
+ Vector2 lastpos = points[points.size() - 1].position;
- float rem = pos.distance_to(lastpos);
+ real_t rem = position.distance_to(lastpos);
dist += rem;
baked_max_ofs = dist;
pointlist.push_back(lastpos);
@@ -742,7 +742,7 @@ void Curve2D::_bake() const {
baked_dist_cache.resize(distlist.size());
Vector2 *w = baked_point_cache.ptrw();
- float *wd = baked_dist_cache.ptrw();
+ real_t *wd = baked_dist_cache.ptrw();
for (int i = 0; i < pointlist.size(); i++) {
w[i] = pointlist[i];
@@ -750,7 +750,7 @@ void Curve2D::_bake() const {
}
}
-float Curve2D::get_baked_length() const {
+real_t Curve2D::get_baked_length() const {
if (baked_cache_dirty) {
_bake();
}
@@ -758,7 +758,7 @@ float Curve2D::get_baked_length() const {
return baked_max_ofs;
}
-Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
+Vector2 Curve2D::interpolate_baked(real_t p_offset, bool p_cubic) const {
if (baked_cache_dirty) {
_bake();
}
@@ -784,7 +784,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
int start = 0, end = bpc, idx = (end + start) / 2;
// binary search to find baked points
while (start < idx) {
- float offset = baked_dist_cache[idx];
+ real_t offset = baked_dist_cache[idx];
if (p_offset <= offset) {
end = idx;
} else {
@@ -793,13 +793,13 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
idx = (end + start) / 2;
}
- float offset_begin = baked_dist_cache[idx];
- float offset_end = baked_dist_cache[idx + 1];
+ real_t offset_begin = baked_dist_cache[idx];
+ real_t offset_end = baked_dist_cache[idx + 1];
- float idx_interval = offset_end - offset_begin;
+ real_t idx_interval = offset_end - offset_begin;
ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector2(), "failed to find baked segment");
- float frac = (p_offset - offset_begin) / idx_interval;
+ real_t frac = (p_offset - offset_begin) / idx_interval;
if (p_cubic) {
Vector2 pre = idx > 0 ? r[idx - 1] : r[idx];
@@ -818,13 +818,13 @@ PackedVector2Array Curve2D::get_baked_points() const {
return baked_point_cache;
}
-void Curve2D::set_bake_interval(float p_tolerance) {
+void Curve2D::set_bake_interval(real_t p_tolerance) {
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve2D::get_bake_interval() const {
+real_t Curve2D::get_bake_interval() const {
return bake_interval;
}
@@ -846,16 +846,16 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
const Vector2 *r = baked_point_cache.ptr();
Vector2 nearest;
- float nearest_dist = -1.0f;
+ real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) {
Vector2 origin = r[i];
Vector2 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector2 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = proj;
@@ -866,7 +866,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
return nearest;
}
-float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
+real_t Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
// Brute force method
if (baked_cache_dirty) {
@@ -883,18 +883,18 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
const Vector2 *r = baked_point_cache.ptr();
- float nearest = 0.0f;
- float nearest_dist = -1.0f;
- float offset = 0.0f;
+ real_t nearest = 0.0f;
+ real_t nearest_dist = -1.0f;
+ real_t offset = 0.0f;
for (int i = 0; i < pc - 1; i++) {
Vector2 origin = r[i];
Vector2 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector2 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = offset + d;
@@ -917,7 +917,7 @@ Dictionary Curve2D::_get_data() const {
for (int i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
- w[i * 3 + 2] = points[i].pos;
+ w[i * 3 + 2] = points[i].position;
}
dc["points"] = d;
@@ -937,42 +937,42 @@ void Curve2D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
- points.write[i].pos = r[i * 3 + 2];
+ points.write[i].position = r[i * 3 + 2];
}
baked_cache_dirty = true;
}
-PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const {
+PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) const {
PackedVector2Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector2>> midpoints;
+ Vector<Map<real_t, Vector2>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment2d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
Vector2 *bpw = tess.ptrw();
- bpw[0] = points[0].pos;
+ bpw[0] = points[0].position;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (const KeyValue<float, Vector2> &E : midpoints[i]) {
+ for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
}
pidx++;
- bpw[pidx] = points[i + 1].pos;
+ bpw[pidx] = points[i + 1].position;
}
return tess;
@@ -1026,9 +1026,9 @@ int Curve3D::get_point_count() const {
return points.size();
}
-void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
+void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
Point n;
- n.pos = p_pos;
+ n.position = p_position;
n.in = p_in;
n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) {
@@ -1041,20 +1041,20 @@ void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
+void Curve3D::set_point_position(int p_index, const Vector3 &p_position) {
ERR_FAIL_INDEX(p_index, points.size());
- points.write[p_index].pos = p_pos;
+ points.write[p_index].position = p_position;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
Vector3 Curve3D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
- return points[p_index].pos;
+ return points[p_index].position;
}
-void Curve3D::set_point_tilt(int p_index, float p_tilt) {
+void Curve3D::set_point_tilt(int p_index, real_t p_tilt) {
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].tilt = p_tilt;
@@ -1062,7 +1062,7 @@ void Curve3D::set_point_tilt(int p_index, float p_tilt) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_point_tilt(int p_index) const {
+real_t Curve3D::get_point_tilt(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), 0);
return points[p_index].tilt;
}
@@ -1108,19 +1108,19 @@ void Curve3D::clear_points() {
}
}
-Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
+Vector3 Curve3D::interpolate(int p_index, real_t p_offset) const {
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector3());
if (p_index >= pc - 1) {
- return points[pc - 1].pos;
+ return points[pc - 1].position;
} else if (p_index < 0) {
- return points[0].pos;
+ return points[0].position;
}
- Vector3 p0 = points[p_index].pos;
+ Vector3 p0 = points[p_index].position;
Vector3 p1 = p0 + points[p_index].out;
- Vector3 p3 = points[p_index + 1].pos;
+ Vector3 p3 = points[p_index + 1].position;
Vector3 p2 = p3 + points[p_index + 1].in;
return _bezier_interp(p_offset, p0, p1, p2, p3);
@@ -1136,15 +1136,15 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const {
- float mp = p_begin + (p_end - p_begin) * 0.5;
+void Curve3D::_bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+ real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 na = (mid - beg).normalized();
Vector3 nb = (end - mid).normalized();
- float dp = na.dot(nb);
+ real_t dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
r_bake[mp] = mid;
@@ -1173,7 +1173,7 @@ void Curve3D::_bake() const {
if (points.size() == 1) {
baked_point_cache.resize(1);
- baked_point_cache.set(0, points[0].pos);
+ baked_point_cache.set(0, points[0].position);
baked_tilt_cache.resize(1);
baked_tilt_cache.set(0, points[0].tilt);
baked_dist_cache.resize(1);
@@ -1189,39 +1189,39 @@ void Curve3D::_bake() const {
return;
}
- Vector3 pos = points[0].pos;
- float dist = 0.0;
+ Vector3 position = points[0].position;
+ real_t dist = 0.0;
List<Plane> pointlist;
- List<float> distlist;
+ List<real_t> distlist;
- pointlist.push_back(Plane(pos, points[0].tilt));
+ pointlist.push_back(Plane(position, points[0].tilt));
distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
- float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0.0;
+ real_t step = 0.1; // at least 10 substeps ought to be enough?
+ real_t p = 0.0;
while (p < 1.0) {
- float np = p + step;
+ real_t np = p + step;
if (np > 1.0) {
np = 1.0;
}
- Vector3 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- float d = pos.distance_to(npp);
+ Vector3 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ real_t d = position.distance_to(npp);
if (d > bake_interval) {
// OK! between P and NP there _has_ to be Something, let's go searching!
int iterations = 10; //lots of detail!
- float low = p;
- float hi = np;
- float mid = low + (hi - low) * 0.5;
+ real_t low = p;
+ real_t hi = np;
+ real_t mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
- npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- d = pos.distance_to(npp);
+ npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ d = position.distance_to(npp);
if (bake_interval < d) {
hi = mid;
@@ -1231,10 +1231,10 @@ void Curve3D::_bake() const {
mid = low + (hi - low) * 0.5;
}
- pos = npp;
+ position = npp;
p = mid;
Plane post;
- post.normal = pos;
+ post.normal = position;
post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid);
dist += d;
@@ -1246,10 +1246,10 @@ void Curve3D::_bake() const {
}
}
- Vector3 lastpos = points[points.size() - 1].pos;
- float lastilt = points[points.size() - 1].tilt;
+ Vector3 lastpos = points[points.size() - 1].position;
+ real_t lastilt = points[points.size() - 1].tilt;
- float rem = pos.distance_to(lastpos);
+ real_t rem = position.distance_to(lastpos);
dist += rem;
baked_max_ofs = dist;
pointlist.push_back(Plane(lastpos, lastilt));
@@ -1266,7 +1266,7 @@ void Curve3D::_bake() const {
Vector3 *up_write = baked_up_vector_cache.ptrw();
baked_dist_cache.resize(pointlist.size());
- float *wd = baked_dist_cache.ptrw();
+ real_t *wd = baked_dist_cache.ptrw();
Vector3 sideways;
Vector3 up;
@@ -1288,7 +1288,7 @@ void Curve3D::_bake() const {
forward = idx > 0 ? (w[idx] - w[idx - 1]).normalized() : prev_forward;
- float y_dot = prev_up.dot(forward);
+ real_t y_dot = prev_up.dot(forward);
if (y_dot > (1.0f - CMP_EPSILON)) {
sideways = prev_sideways;
@@ -1315,7 +1315,7 @@ void Curve3D::_bake() const {
}
}
-float Curve3D::get_baked_length() const {
+real_t Curve3D::get_baked_length() const {
if (baked_cache_dirty) {
_bake();
}
@@ -1323,7 +1323,7 @@ float Curve3D::get_baked_length() const {
return baked_max_ofs;
}
-Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
+Vector3 Curve3D::interpolate_baked(real_t p_offset, bool p_cubic) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1349,7 +1349,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
int start = 0, end = bpc, idx = (end + start) / 2;
// binary search to find baked points
while (start < idx) {
- float offset = baked_dist_cache[idx];
+ real_t offset = baked_dist_cache[idx];
if (p_offset <= offset) {
end = idx;
} else {
@@ -1358,13 +1358,13 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
idx = (end + start) / 2;
}
- float offset_begin = baked_dist_cache[idx];
- float offset_end = baked_dist_cache[idx + 1];
+ real_t offset_begin = baked_dist_cache[idx];
+ real_t offset_end = baked_dist_cache[idx + 1];
- float idx_interval = offset_end - offset_begin;
+ real_t idx_interval = offset_end - offset_begin;
ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector3(), "failed to find baked segment");
- float frac = (p_offset - offset_begin) / idx_interval;
+ real_t frac = (p_offset - offset_begin) / idx_interval;
if (p_cubic) {
Vector3 pre = idx > 0 ? r[idx - 1] : r[idx];
@@ -1375,7 +1375,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
}
}
-float Curve3D::interpolate_baked_tilt(float p_offset) const {
+real_t Curve3D::interpolate_baked_tilt(real_t p_offset) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1399,7 +1399,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
}
int idx = Math::floor((double)p_offset / (double)bake_interval);
- float frac = Math::fmod(p_offset, bake_interval);
+ real_t frac = Math::fmod(p_offset, bake_interval);
if (idx >= bpc - 1) {
return r[bpc - 1];
@@ -1414,7 +1414,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
return Math::lerp(r[idx], r[idx + 1], (real_t)frac);
}
-Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const {
+Vector3 Curve3D::interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1432,10 +1432,10 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
const Vector3 *rp = baked_point_cache.ptr();
const real_t *rt = baked_tilt_cache.ptr();
- float offset = CLAMP(p_offset, 0.0f, baked_max_ofs);
+ real_t offset = CLAMP(p_offset, 0.0f, baked_max_ofs);
int idx = Math::floor((double)offset / (double)bake_interval);
- float frac = Math::fmod(offset, bake_interval) / bake_interval;
+ real_t frac = Math::fmod(offset, bake_interval) / bake_interval;
if (idx == count - 1) {
return p_apply_tilt ? r[idx].rotated((rp[idx] - rp[idx - 1]).normalized(), rt[idx]) : r[idx];
@@ -1503,16 +1503,16 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
const Vector3 *r = baked_point_cache.ptr();
Vector3 nearest;
- float nearest_dist = -1.0f;
+ real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) {
Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector3 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = proj;
@@ -1523,7 +1523,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
return nearest;
}
-float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
+real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
// Brute force method
if (baked_cache_dirty) {
@@ -1540,18 +1540,18 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
const Vector3 *r = baked_point_cache.ptr();
- float nearest = 0.0f;
- float nearest_dist = -1.0f;
- float offset = 0.0f;
+ real_t nearest = 0.0f;
+ real_t nearest_dist = -1.0f;
+ real_t offset = 0.0f;
for (int i = 0; i < pc - 1; i++) {
Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector3 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = offset + d;
@@ -1564,13 +1564,13 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
return nearest;
}
-void Curve3D::set_bake_interval(float p_tolerance) {
+void Curve3D::set_bake_interval(real_t p_tolerance) {
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_bake_interval() const {
+real_t Curve3D::get_bake_interval() const {
return bake_interval;
}
@@ -1597,7 +1597,7 @@ Dictionary Curve3D::_get_data() const {
for (int i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
- w[i * 3 + 2] = points[i].pos;
+ w[i * 3 + 2] = points[i].position;
wt[i] = points[i].tilt;
}
@@ -1622,43 +1622,43 @@ void Curve3D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
- points.write[i].pos = r[i * 3 + 2];
+ points.write[i].position = r[i * 3 + 2];
points.write[i].tilt = rt[i];
}
baked_cache_dirty = true;
}
-PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const {
+PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) const {
PackedVector3Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector3>> midpoints;
+ Vector<Map<real_t, Vector3>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment3d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
Vector3 *bpw = tess.ptrw();
- bpw[0] = points[0].pos;
+ bpw[0] = points[0].position;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (const KeyValue<float, Vector3> &E : midpoints[i]) {
+ for (const KeyValue<real_t, Vector3> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
}
pidx++;
- bpw[pidx] = points[i + 1].pos;
+ bpw[pidx] = points[i + 1].position;
}
return tess;
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 5808fd6508..16facda85a 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -50,7 +50,7 @@ public:
};
struct Point {
- Vector2 pos;
+ Vector2 position;
real_t left_tangent = 0.0;
real_t right_tangent = 0.0;
TangentMode left_mode = TANGENT_FREE;
@@ -59,12 +59,12 @@ public:
Point() {
}
- Point(Vector2 p_pos,
+ Point(const Vector2 &p_position,
real_t p_left = 0.0,
real_t p_right = 0.0,
TangentMode p_left_mode = TANGENT_FREE,
TangentMode p_right_mode = TANGENT_FREE) {
- pos = p_pos;
+ position = p_position;
left_tangent = p_left;
right_tangent = p_right;
left_mode = p_left_mode;
@@ -76,7 +76,7 @@ public:
int get_point_count() const { return _points.size(); }
- int add_point(Vector2 p_pos,
+ int add_point(Vector2 p_position,
real_t left_tangent = 0,
real_t right_tangent = 0,
TangentMode left_mode = TANGENT_FREE,
@@ -85,34 +85,34 @@ public:
void remove_point(int p_index);
void clear_points();
- int get_index(real_t offset) const;
+ int get_index(real_t p_offset) const;
- void set_point_value(int p_index, real_t pos);
- int set_point_offset(int p_index, float offset);
+ void set_point_value(int p_index, real_t p_position);
+ int set_point_offset(int p_index, real_t p_offset);
Vector2 get_point_position(int p_index) const;
Point get_point(int p_index) const;
- float get_min_value() const { return _min_value; }
- void set_min_value(float p_min);
+ real_t get_min_value() const { return _min_value; }
+ void set_min_value(real_t p_min);
- float get_max_value() const { return _max_value; }
- void set_max_value(float p_max);
+ real_t get_max_value() const { return _max_value; }
+ void set_max_value(real_t p_max);
- real_t interpolate(real_t offset) const;
- real_t interpolate_local_nocheck(int index, real_t local_offset) const;
+ real_t interpolate(real_t p_offset) const;
+ real_t interpolate_local_nocheck(int p_index, real_t p_local_offset) const;
void clean_dupes();
- void set_point_left_tangent(int i, real_t tangent);
- void set_point_right_tangent(int i, real_t tangent);
- void set_point_left_mode(int i, TangentMode p_mode);
- void set_point_right_mode(int i, TangentMode p_mode);
+ void set_point_left_tangent(int p_index, real_t p_tangent);
+ void set_point_right_tangent(int p_index, real_t p_tangent);
+ void set_point_left_mode(int p_index, TangentMode p_mode);
+ void set_point_right_mode(int p_index, TangentMode p_mode);
- real_t get_point_left_tangent(int i) const;
- real_t get_point_right_tangent(int i) const;
- TangentMode get_point_left_mode(int i) const;
- TangentMode get_point_right_mode(int i) const;
+ real_t get_point_left_tangent(int p_index) const;
+ real_t get_point_right_tangent(int p_index) const;
+ TangentMode get_point_left_mode(int p_index) const;
+ TangentMode get_point_right_mode(int p_index) const;
void update_auto_tangents(int i);
@@ -122,9 +122,9 @@ public:
void bake();
int get_bake_resolution() const { return _bake_resolution; }
void set_bake_resolution(int p_resolution);
- real_t interpolate_baked(real_t offset) const;
+ real_t interpolate_baked(real_t p_offset) const;
- void ensure_default_setup(float p_min, float p_max);
+ void ensure_default_setup(real_t p_min, real_t p_max);
protected:
static void _bind_methods();
@@ -136,8 +136,8 @@ private:
bool _baked_cache_dirty = false;
Vector<real_t> _baked_cache;
int _bake_resolution = 100;
- float _min_value = 0.0;
- float _max_value = 1.0;
+ real_t _min_value = 0.0;
+ real_t _max_value = 1.0;
int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max.
};
@@ -149,26 +149,26 @@ class Curve2D : public Resource {
struct Point {
Vector2 in;
Vector2 out;
- Vector2 pos;
+ Vector2 position;
};
Vector<Point> points;
struct BakedPoint {
- float ofs = 0.0;
+ real_t ofs = 0.0;
Vector2 point;
};
mutable bool baked_cache_dirty = false;
mutable PackedVector2Array baked_point_cache;
- mutable PackedFloat32Array baked_dist_cache;
- mutable float baked_max_ofs = 0.0;
+ mutable Vector<real_t> baked_dist_cache;
+ mutable real_t baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval = 5.0;
+ real_t bake_interval = 5.0;
- void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const;
+ void _bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
@@ -177,8 +177,8 @@ protected:
public:
int get_point_count() const;
- void add_point(const Vector2 &p_pos, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1);
- void set_point_position(int p_index, const Vector2 &p_pos);
+ void add_point(const Vector2 &p_position, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1);
+ void set_point_position(int p_index, const Vector2 &p_position);
Vector2 get_point_position(int p_index) const;
void set_point_in(int p_index, const Vector2 &p_in);
Vector2 get_point_in(int p_index) const;
@@ -187,19 +187,19 @@ public:
void remove_point(int p_index);
void clear_points();
- Vector2 interpolate(int p_index, float p_offset) const;
+ Vector2 interpolate(int p_index, real_t p_offset) const;
Vector2 interpolatef(real_t p_findex) const;
- void set_bake_interval(float p_tolerance);
- float get_bake_interval() const;
+ void set_bake_interval(real_t p_tolerance);
+ real_t get_bake_interval() const;
- float get_baked_length() const;
- Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const;
+ real_t get_baked_length() const;
+ Vector2 interpolate_baked(real_t p_offset, bool p_cubic = false) const;
PackedVector2Array get_baked_points() const; //useful for going through
Vector2 get_closest_point(const Vector2 &p_to_point) const;
- float get_closest_offset(const Vector2 &p_to_point) const;
+ real_t get_closest_offset(const Vector2 &p_to_point) const;
- PackedVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector2Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display
Curve2D();
};
@@ -210,14 +210,14 @@ class Curve3D : public Resource {
struct Point {
Vector3 in;
Vector3 out;
- Vector3 pos;
- float tilt = 0.0;
+ Vector3 position;
+ real_t tilt = 0.0;
};
Vector<Point> points;
struct BakedPoint {
- float ofs = 0.0;
+ real_t ofs = 0.0;
Vector3 point;
};
@@ -225,15 +225,15 @@ class Curve3D : public Resource {
mutable PackedVector3Array baked_point_cache;
mutable Vector<real_t> baked_tilt_cache;
mutable PackedVector3Array baked_up_vector_cache;
- mutable PackedFloat32Array baked_dist_cache;
- mutable float baked_max_ofs = 0.0;
+ mutable Vector<real_t> baked_dist_cache;
+ mutable real_t baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval = 0.2;
+ real_t bake_interval = 0.2;
bool up_vector_enabled = true;
- void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const;
+ void _bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
@@ -242,11 +242,11 @@ protected:
public:
int get_point_count() const;
- void add_point(const Vector3 &p_pos, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1);
- void set_point_position(int p_index, const Vector3 &p_pos);
+ void add_point(const Vector3 &p_position, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1);
+ void set_point_position(int p_index, const Vector3 &p_position);
Vector3 get_point_position(int p_index) const;
- void set_point_tilt(int p_index, float p_tilt);
- float get_point_tilt(int p_index) const;
+ void set_point_tilt(int p_index, real_t p_tilt);
+ real_t get_point_tilt(int p_index) const;
void set_point_in(int p_index, const Vector3 &p_in);
Vector3 get_point_in(int p_index) const;
void set_point_out(int p_index, const Vector3 &p_out);
@@ -254,25 +254,25 @@ public:
void remove_point(int p_index);
void clear_points();
- Vector3 interpolate(int p_index, float p_offset) const;
+ Vector3 interpolate(int p_index, real_t p_offset) const;
Vector3 interpolatef(real_t p_findex) const;
- void set_bake_interval(float p_tolerance);
- float get_bake_interval() const;
+ void set_bake_interval(real_t p_tolerance);
+ real_t get_bake_interval() const;
void set_up_vector_enabled(bool p_enable);
bool is_up_vector_enabled() const;
- float get_baked_length() const;
- Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const;
- float interpolate_baked_tilt(float p_offset) const;
- Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const;
+ real_t get_baked_length() const;
+ Vector3 interpolate_baked(real_t p_offset, bool p_cubic = false) const;
+ real_t interpolate_baked_tilt(real_t p_offset) const;
+ Vector3 interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt = false) const;
PackedVector3Array get_baked_points() const; //useful for going through
Vector<real_t> get_baked_tilts() const; //useful for going through
PackedVector3Array get_baked_up_vectors() const;
Vector3 get_closest_point(const Vector3 &p_to_point) const;
- float get_closest_offset(const Vector3 &p_to_point) const;
+ real_t get_closest_offset(const Vector3 &p_to_point) const;
- PackedVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector3Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display
Curve3D();
};
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index d88a2c557b..e5740472c6 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -1152,11 +1152,11 @@ void Font::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_underline_position", "size"), &Font::get_underline_position, DEFVAL(DEFAULT_FONT_SIZE));
ClassDB::bind_method(D_METHOD("get_underline_thickness", "size"), &Font::get_underline_thickness, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("get_string_size", "text", "size", "align", "width", "flags"), &Font::get_string_size, DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("get_string_size", "text", "size", "alignment", "width", "flags"), &Font::get_string_size, DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "width", "size", "flags"), &Font::get_multiline_string_size, DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "align", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "align", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_multiline_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
ClassDB::bind_method(D_METHOD("get_char_size", "char", "next", "size"), &Font::get_char_size, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE));
ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &Font::draw_char, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)));
@@ -1449,7 +1449,7 @@ real_t Font::get_underline_thickness(int p_size) const {
return ret;
}
-Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint16_t p_flags) const {
+Size2 Font::get_string_size(const String &p_text, int p_size, HorizontalAlignment p_alignment, float p_width, uint16_t p_flags) const {
ERR_FAIL_COND_V(data.is_empty(), Size2());
for (int i = 0; i < data.size(); i++) {
@@ -1457,7 +1457,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re
}
uint64_t hash = p_text.hash64();
- if (p_align == HALIGN_FILL) {
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
hash = hash_djb2_one_64(hash_djb2_one_float(p_width), hash);
hash = hash_djb2_one_64(p_flags, hash);
}
@@ -1474,7 +1474,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re
return buffer->get_size();
}
-Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint16_t p_flags) const {
+Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p_size, uint16_t p_flags) const {
ERR_FAIL_COND_V(data.is_empty(), Size2());
for (int i = 0; i < data.size(); i++) {
@@ -1511,7 +1511,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int
return ret;
}
-void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND(data.is_empty());
for (int i = 0; i < data.size(); i++) {
@@ -1519,7 +1519,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
}
uint64_t hash = p_text.hash64();
- if (p_align == HALIGN_FILL) {
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
hash = hash_djb2_one_64(hash_djb2_one_float(p_width), hash);
hash = hash_djb2_one_64(p_flags, hash);
}
@@ -1542,7 +1542,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
}
buffer->set_width(p_width);
- buffer->set_align(p_align);
+ buffer->set_horizontal_alignment(p_alignment);
buffer->set_flags(p_flags);
if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) {
@@ -1551,7 +1551,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
buffer->draw(p_canvas_item, ofs, p_modulate);
}
-void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND(data.is_empty());
for (int i = 0; i < data.size(); i++) {
@@ -1574,7 +1574,7 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S
cache_wrap.insert(wrp_hash, lines_buffer);
}
- lines_buffer->set_align(p_align);
+ lines_buffer->set_alignment(p_alignment);
Vector2 lofs = p_pos;
for (int i = 0; i < lines_buffer->get_line_count(); i++) {
@@ -1588,7 +1588,7 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S
}
}
if (p_width > 0) {
- lines_buffer->set_align(p_align);
+ lines_buffer->set_alignment(p_alignment);
}
if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) {
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 4d9ee72c84..fb662037a1 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -273,11 +273,11 @@ public:
virtual real_t get_underline_thickness(int p_size = DEFAULT_FONT_SIZE) const;
// Drawing string.
- virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
+ virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ virtual Size2 get_multiline_string_size(const String &p_text, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
- virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
// Helper functions.
virtual bool has_char(char32_t p_char) const;
diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp
index fe7124de9e..4f9a055bfb 100644
--- a/scene/resources/immediate_mesh.cpp
+++ b/scene/resources/immediate_mesh.cpp
@@ -144,6 +144,7 @@ void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) {
active_surface_data.vertex_2d = true;
}
+
void ImmediateMesh::surface_end() {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface can't be created.");
@@ -185,7 +186,7 @@ void ImmediateMesh::surface_end() {
vtx[2] = vertices[i].z;
}
if (i == 0) {
- aabb.position = vertices[i];
+ aabb = AABB(vertices[i], SMALL_VEC3); // Must have a bit of size.
} else {
aabb.expand_to(vertices[i]);
}
diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h
index 6673ee6f3d..92bf91441d 100644
--- a/scene/resources/immediate_mesh.h
+++ b/scene/resources/immediate_mesh.h
@@ -75,6 +75,8 @@ class ImmediateMesh : public Mesh {
Vector<uint8_t> surface_vertex_create_cache;
Vector<uint8_t> surface_attribute_create_cache;
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
static void _bind_methods();
diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp
index 7afa4c91f0..b2b90f019e 100644
--- a/scene/resources/importer_mesh.cpp
+++ b/scene/resources/importer_mesh.cpp
@@ -485,7 +485,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli
raycaster->intersect(rays);
LocalVector<Vector3> ray_normals;
- LocalVector<float> ray_normal_weights;
+ LocalVector<real_t> ray_normal_weights;
ray_normals.resize(new_index_count);
ray_normal_weights.resize(new_index_count);
@@ -517,10 +517,10 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli
Vector3 normal = n0 * w + n1 * u + n2 * v;
Vector2 orig_uv = ray_uvs[j];
- float orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y };
+ real_t orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y };
for (int k = 0; k < 3; k++) {
int idx = orig_tri_id * 3 + k;
- float weight = orig_bary[k];
+ real_t weight = orig_bary[k];
ray_normals[idx] += normal * weight;
ray_normal_weights[idx] += weight;
}
@@ -653,7 +653,7 @@ Ref<ArrayMesh> ImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) {
if (surfaces[i].material.is_valid()) {
mesh->surface_set_material(mesh->get_surface_count() - 1, surfaces[i].material);
}
- if (surfaces[i].name != String()) {
+ if (!surfaces[i].name.is_empty()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, surfaces[i].name);
}
}
@@ -839,7 +839,7 @@ Dictionary ImporterMesh::_get_data() const {
d["material"] = surfaces[i].material;
}
- if (surfaces[i].name != String()) {
+ if (!surfaces[i].name.is_empty()) {
d["name"] = surfaces[i].name;
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 8399b14a56..98bda4ad1b 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1658,13 +1658,28 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
+
+ if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
+ // If no roughness texture is currently set, automatically set the recommended value
+ // for roughness when using a roughness map.
+ set_roughness(1.0);
+ }
+
+ if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
+ // If no metallic texture is currently set, automatically set the recommended value
+ // for metallic when using a metallic map.
+ set_metallic(1.0);
+ }
+
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+
if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
Vector2i(p_texture->get_width(), p_texture->get_height()));
}
+
notify_property_list_changed();
_queue_shader_change();
}
@@ -2884,7 +2899,7 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value)
idx++;
}
- print_line("remapped parameter not found: " + String(p_name));
+ WARN_PRINT("Godot 3.x SpatialMaterial remapped parameter not found: " + String(p_name));
return true;
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 51b4e1fbd8..bd63d17424 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -994,9 +994,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
}
//clear unused flags
- print_line("format pre: " + itos(old_format));
+ print_verbose("Mesh format pre-conversion: " + itos(old_format));
- print_line("format post: " + itos(new_format));
+ print_verbose("Mesh format post-conversion: " + itos(new_format));
ERR_FAIL_COND_V(!d.has("aabb"), false);
AABB aabb = d["aabb"];
@@ -1104,7 +1104,7 @@ Array ArrayMesh::_get_surfaces() const {
data["material"] = surfaces[i].material;
}
- if (surfaces[i].name != String()) {
+ if (!surfaces[i].name.is_empty()) {
data["name"] = surfaces[i].name;
}
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index c39f59d535..e6b499d4f1 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -417,7 +417,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
// save the child instantiated scenes that are chosen as editable, so they can be restored
// upon load back
- if (p_node != p_owner && p_node->get_scene_file_path() != String() && p_owner->is_editable_instance(p_node)) {
+ if (p_node != p_owner && !p_node->get_scene_file_path().is_empty() && p_owner->is_editable_instance(p_node)) {
editable_instances.push_back(p_owner->get_path_to(p_node));
// Node is the root of an editable instance.
is_editable_instance = true;
@@ -451,7 +451,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
bool instantiated_by_owner = false;
Vector<SceneState::PackState> states_stack = PropertyUtils::get_node_states_stack(p_node, p_owner, &instantiated_by_owner);
- if (p_node->get_scene_file_path() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) {
+ if (!p_node->get_scene_file_path().is_empty() && p_node->get_owner() == p_owner && instantiated_by_owner) {
if (p_node->get_scene_instance_load_placeholder()) {
//it's a placeholder, use the placeholder path
nd.instance = _vm_get_variant(p_node->get_scene_file_path(), variant_map);
@@ -656,7 +656,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
ERR_CONTINUE(!common_parent);
- if (common_parent != p_owner && common_parent->get_scene_file_path() == String()) {
+ if (common_parent != p_owner && common_parent->get_scene_file_path().is_empty()) {
common_parent = common_parent->get_owner();
}
@@ -716,7 +716,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
nl = nullptr;
} else {
- if (nl->get_scene_file_path() != String()) {
+ if (!nl->get_scene_file_path().is_empty()) {
//is an instance
Ref<SceneState> state = nl->get_scene_instance_state();
if (state.is_valid()) {
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 6b7eef3712..90ef78ccd9 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -596,7 +596,7 @@ void ParticlesMaterial::_update_shader() {
code += " float base_angle = (tex_angle) * mix(initial_angle_min, initial_angle_max, rand_from_seed(alt_seed));\n";
code += " base_angle += CUSTOM.y * LIFETIME * (tex_angular_velocity) * mix(angular_velocity_min,angular_velocity_max, rand_from_seed(alt_seed));\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
- code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + CUSTOM.y * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle
+ code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + tv * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle
// apply color
// apply hue rotation
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index cead42b4e2..0e354ebff4 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -274,12 +274,12 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
int nameidx = packed_scene->get_state()->add_name(assign);
int valueidx = packed_scene->get_state()->add_value(value);
packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx);
//it's assignment
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
break;
}
}
@@ -575,12 +575,12 @@ Error ResourceLoaderText::load() {
return error;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
if (do_assign) {
res->set(assign, value);
}
//it's assignment
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
error = OK;
break;
} else {
@@ -659,10 +659,10 @@ Error ResourceLoaderText::load() {
return error;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
resource->set(assign, value);
//it's assignment
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
error = ERR_FILE_CORRUPT;
error_text = "Extra tag found when parsing main resource file";
_printerr();
@@ -1166,13 +1166,13 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
return error;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
Map<StringName, int> empty_string_map; //unused
bs_save_unicode_string(wf2, assign, true);
ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map);
prop_count++;
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
error = OK;
break;
} else {
@@ -1350,7 +1350,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
ResourceLoaderText loader;
- String path = p_original_path != "" ? p_original_path : p_path;
+ String path = !p_original_path.is_empty() ? p_original_path : p_path;
loader.cache_mode = p_cache_mode;
loader.use_sub_threads = p_use_sub_threads;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
@@ -1369,7 +1369,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
}
void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "") {
+ if (p_type.is_empty()) {
get_recognized_extensions(p_extensions);
return;
}
@@ -1655,7 +1655,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
Set<String> cached_ids_found;
for (KeyValue<RES, String> &E : external_resources) {
String cached_id = E.key->get_id_for_path(local_path);
- if (cached_id == "" || cached_ids_found.has(cached_id)) {
+ if (cached_id.is_empty() || cached_ids_found.has(cached_id)) {
int sep_pos = E.value.find("_");
if (sep_pos != -1) {
E.value = E.value.substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance.
@@ -1729,7 +1729,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
RES res = E->get();
if (E->next() && res->is_built_in()) {
- if (res->get_scene_unique_id() != "") {
+ if (!res->get_scene_unique_id().is_empty()) {
if (used_unique_ids.has(res->get_scene_unique_id())) {
res->set_scene_unique_id(""); // Repeated.
} else {
@@ -1752,7 +1752,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_line("[resource]");
} else {
String line = "[sub_resource ";
- if (res->get_scene_unique_id() == "") {
+ if (res->get_scene_unique_id().is_empty()) {
String new_id;
while (true) {
new_id = res->get_class() + "_" + Resource::generate_scene_unique_id();
@@ -1866,7 +1866,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(header);
- if (instance_placeholder != String()) {
+ if (!instance_placeholder.is_empty()) {
String vars;
f->store_string(" instance_placeholder=");
VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this);
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index cfb5ac2ca6..800752d597 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -493,7 +493,7 @@ void CodeHighlighter::add_color_region(const String &p_start_key, const String &
color_region.color = p_color;
color_region.start_key = p_start_key;
color_region.end_key = p_end_key;
- color_region.line_only = p_line_only || p_end_key == "";
+ color_region.line_only = p_line_only || p_end_key.is_empty();
color_regions.insert(at, color_region);
clear_highlighting_cache();
}
@@ -529,7 +529,7 @@ void CodeHighlighter::set_color_regions(const Dictionary &p_color_regions) {
String start_key = key.get_slice(" ", 0);
String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String();
- add_color_region(start_key, end_key, p_color_regions[key], end_key == "");
+ add_color_region(start_key, end_key, p_color_regions[key], end_key.is_empty());
}
clear_highlighting_cache();
}
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index 33bb0a83e9..1dc46711f8 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -33,7 +33,7 @@
#include "core/io/file_access.h"
bool TextFile::has_text() const {
- return text != "";
+ return !text.is_empty();
}
String TextFile::get_text() const {
diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp
index 0094518967..cfd7e1d876 100644
--- a/scene/resources/text_line.cpp
+++ b/scene/resources/text_line.cpp
@@ -56,18 +56,18 @@ void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override);
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
- ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGN_CENTER));
+ ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("set_width", "width"), &TextLine::set_width);
ClassDB::bind_method(D_METHOD("get_width"), &TextLine::get_width);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width");
- ClassDB::bind_method(D_METHOD("set_align", "align"), &TextLine::set_align);
- ClassDB::bind_method(D_METHOD("get_align"), &TextLine::get_align);
+ ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &TextLine::set_horizontal_alignment);
+ ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &TextLine::get_horizontal_alignment);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ClassDB::bind_method(D_METHOD("tab_align", "tab_stops"), &TextLine::tab_align);
@@ -135,14 +135,14 @@ void TextLine::_shape() {
break;
}
- if (align == HALIGN_FILL) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(rid, width, flags);
overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags);
} else {
TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags);
}
- } else if (align == HALIGN_FILL) {
+ } else if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(rid, width, flags);
}
dirty = false;
@@ -209,13 +209,13 @@ bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_
return res;
}
-bool TextLine::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextLine::add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length);
dirty = true;
return res;
}
-bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
const_cast<TextLine *>(this)->_shape();
return TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align);
}
@@ -228,19 +228,19 @@ Rect2 TextLine::get_object_rect(Variant p_key) const {
return TS->shaped_text_get_object_rect(rid, p_key);
}
-void TextLine::set_align(HAlign p_align) {
- if (align != p_align) {
- if (align == HALIGN_FILL || p_align == HALIGN_FILL) {
- align = p_align;
+void TextLine::set_horizontal_alignment(HorizontalAlignment p_alignment) {
+ if (alignment != p_alignment) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ alignment = p_alignment;
dirty = true;
} else {
- align = p_align;
+ alignment = p_alignment;
}
}
}
-HAlign TextLine::get_align() const {
- return align;
+HorizontalAlignment TextLine::get_horizontal_alignment() const {
+ return alignment;
}
void TextLine::tab_align(const Vector<float> &p_tab_stops) {
@@ -272,7 +272,7 @@ TextLine::OverrunBehavior TextLine::get_text_overrun_behavior() const {
void TextLine::set_width(float p_width) {
width = p_width;
- if (align == HALIGN_FILL || overrun_behavior != OVERRUN_NO_TRIMMING) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL || overrun_behavior != OVERRUN_NO_TRIMMING) {
dirty = true;
}
}
@@ -322,18 +322,18 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co
float length = TS->shaped_text_get_width(rid);
if (width > 0) {
- switch (align) {
- case HALIGN_FILL:
- case HALIGN_LEFT:
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT:
break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += Math::floor((width - length) / 2.0);
} else {
ofs.y += Math::floor((width - length) / 2.0);
}
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += width - length;
} else {
@@ -361,18 +361,18 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si
float length = TS->shaped_text_get_width(rid);
if (width > 0) {
- switch (align) {
- case HALIGN_FILL:
- case HALIGN_LEFT:
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
+ case HORIZONTAL_ALIGNMENT_LEFT:
break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += Math::floor((width - length) / 2.0);
} else {
ofs.y += Math::floor((width - length) / 2.0);
}
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += width - length;
} else {
diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h
index 43739f27ec..bab17a3024 100644
--- a/scene/resources/text_line.h
+++ b/scene/resources/text_line.h
@@ -57,7 +57,7 @@ private:
float width = -1.0;
uint16_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
- HAlign align = HALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
OverrunBehavior overrun_behavior = OVERRUN_TRIM_ELLIPSIS;
Vector<float> tab_stops;
@@ -87,11 +87,11 @@ public:
bool get_preserve_control() const;
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
- bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1);
- bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER);
+ bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
+ bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
- void set_align(HAlign p_align);
- HAlign get_align() const;
+ void set_horizontal_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_horizontal_alignment() const;
void tab_align(const Vector<float> &p_tab_stops);
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 1b7fc64267..130b83ea99 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -64,13 +64,13 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
- ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGN_CENTER));
+ ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
- ClassDB::bind_method(D_METHOD("set_align", "align"), &TextParagraph::set_align);
- ClassDB::bind_method(D_METHOD("get_align"), &TextParagraph::get_align);
+ ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &TextParagraph::set_alignment);
+ ClassDB::bind_method(D_METHOD("get_alignment"), &TextParagraph::get_alignment);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_alignment", "get_alignment");
ClassDB::bind_method(D_METHOD("tab_align", "tab_stops"), &TextParagraph::tab_align);
@@ -223,7 +223,7 @@ void TextParagraph::_shape_lines() {
if (lines_hidden) {
overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
}
- if (align == HALIGN_FILL) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
for (int i = 0; i < lines_rid.size(); i++) {
if (i < visible_lines - 1 || lines_rid.size() == 1) {
TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
@@ -239,7 +239,7 @@ void TextParagraph::_shape_lines() {
} else {
// Autowrap disabled.
for (int i = 0; i < lines_rid.size(); i++) {
- if (align == HALIGN_FILL) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
@@ -366,31 +366,31 @@ void TextParagraph::set_bidi_override(const Array &p_override) {
lines_dirty = true;
}
-bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length);
lines_dirty = true;
return res;
}
-bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
bool res = TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align);
lines_dirty = true;
return res;
}
-void TextParagraph::set_align(HAlign p_align) {
- if (align != p_align) {
- if (align == HALIGN_FILL || p_align == HALIGN_FILL) {
- align = p_align;
+void TextParagraph::set_alignment(HorizontalAlignment p_alignment) {
+ if (alignment != p_alignment) {
+ if (alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ alignment = p_alignment;
lines_dirty = true;
} else {
- align = p_align;
+ alignment = p_alignment;
}
}
}
-HAlign TextParagraph::get_align() const {
- return align;
+HorizontalAlignment TextParagraph::get_alignment() const {
+ return alignment;
}
void TextParagraph::tab_align(const Vector<float> &p_tab_stops) {
@@ -596,8 +596,8 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
}
float line_width = TS->shaped_text_get_width(lines_rid[i]);
if (width > 0) {
- switch (align) {
- case HALIGN_FILL:
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - line_width;
@@ -606,16 +606,16 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
}
}
break;
- case HALIGN_LEFT:
+ case HORIZONTAL_ALIGNMENT_LEFT:
break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += Math::floor((l_width - line_width) / 2.0);
} else {
ofs.y += Math::floor((l_width - line_width) / 2.0);
}
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - line_width;
} else {
@@ -688,8 +688,8 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
}
float length = TS->shaped_text_get_width(lines_rid[i]);
if (width > 0) {
- switch (align) {
- case HALIGN_FILL:
+ switch (alignment) {
+ case HORIZONTAL_ALIGNMENT_FILL:
if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - length;
@@ -698,16 +698,16 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
}
}
break;
- case HALIGN_LEFT:
+ case HORIZONTAL_ALIGNMENT_LEFT:
break;
- case HALIGN_CENTER: {
+ case HORIZONTAL_ALIGNMENT_CENTER: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += Math::floor((l_width - length) / 2.0);
} else {
ofs.y += Math::floor((l_width - length) / 2.0);
}
} break;
- case HALIGN_RIGHT: {
+ case HORIZONTAL_ALIGNMENT_RIGHT: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - length;
} else {
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index 4c4af43d14..1faa3f3a7b 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -66,7 +66,7 @@ private:
uint16_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
OverrunBehavior overrun_behavior = OVERRUN_NO_TRIMMING;
- HAlign align = HALIGN_LEFT;
+ HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
Vector<float> tab_stops;
@@ -103,11 +103,11 @@ public:
void clear_dropcap();
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
- bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1);
- bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER);
+ bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
+ bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
- void set_align(HAlign p_align);
- HAlign get_align() const;
+ void set_alignment(HorizontalAlignment p_alignment);
+ HorizontalAlignment get_alignment() const;
void tab_align(const Vector<float> &p_tab_stops);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 311bd9524b..13c3f6ea1d 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -553,7 +553,7 @@ Error StreamTexture2D::load(const String &p_path) {
path_to_file = p_path;
format = image->get_format();
- if (get_path() == String()) {
+ if (get_path().is_empty()) {
//temporarily set path if no path set for resource, helps find errors
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -927,7 +927,7 @@ Error StreamTexture3D::load(const String &p_path) {
path_to_file = p_path;
- if (get_path() == String()) {
+ if (get_path().is_empty()) {
//temporarily set path if no path set for resource, helps find errors
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -2680,7 +2680,7 @@ Error StreamTextureLayered::load(const String &p_path) {
path_to_file = p_path;
- if (get_path() == String()) {
+ if (get_path().is_empty()) {
//temporarily set path if no path set for resource, helps find errors
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 41e78e0bc8..10e75fb023 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -979,7 +979,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
String VisualShader::validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const {
String name = p_port_name;
- if (name == String()) {
+ if (name.is_empty()) {
return String();
}
@@ -987,7 +987,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN
name = name.substr(1, name.length() - 1);
}
- if (name != String()) {
+ if (!name.is_empty()) {
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -1031,7 +1031,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
while (name.length() && !IS_INITIAL_CHAR(name[0])) {
name = name.substr(1, name.length() - 1);
}
- if (name != String()) {
+ if (!name.is_empty()) {
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -1045,7 +1045,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
name = valid_name;
}
- if (name == String()) {
+ if (name.is_empty()) {
name = p_uniform->get_caption();
}
@@ -1075,7 +1075,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
while (name.length() && name[name.length() - 1] >= '0' && name[name.length() - 1] <= '9') {
name = name.substr(0, name.length() - 1);
}
- ERR_FAIL_COND_V(name == String(), String());
+ ERR_FAIL_COND_V(name.is_empty(), String());
name += itos(attempt);
} else {
break;
@@ -1568,7 +1568,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
node_code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
- if (node_code != String()) {
+ if (!node_code.is_empty()) {
code += node_name;
code += node_code;
code += "\n";
@@ -1664,7 +1664,7 @@ void VisualShader::_update_shader() const {
String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
if (mode.begins_with(render_mode_enums[idx].string)) {
if (count == which) {
- if (render_mode != String()) {
+ if (!render_mode.is_empty()) {
render_mode += ", ";
}
render_mode += mode;
@@ -1682,7 +1682,7 @@ void VisualShader::_update_shader() const {
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
if (flags.has(mode)) {
- if (render_mode != String()) {
+ if (!render_mode.is_empty()) {
render_mode += ", ";
}
render_mode += mode;
@@ -1690,7 +1690,7 @@ void VisualShader::_update_shader() const {
}
}
- if (render_mode != String()) {
+ if (!render_mode.is_empty()) {
global_code += "render_mode " + render_mode + ";\n\n";
}
@@ -2468,7 +2468,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
idx++;
}
- if (code == String()) {
+ if (code.is_empty()) {
switch (get_output_port_type(0)) {
case PORT_TYPE_SCALAR: {
code = " " + p_output_vars[0] + " = 0.0;\n";
@@ -2502,7 +2502,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
idx++;
}
- if (code == String()) {
+ if (code.is_empty()) {
code = " " + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar
}
@@ -2605,7 +2605,7 @@ void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const {
while (ports[idx].mode != Shader::MODE_MAX) {
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
- if (port_list != String()) {
+ if (!port_list.is_empty()) {
port_list += ",";
}
port_list += ports[idx].name;
@@ -2613,7 +2613,7 @@ void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const {
idx++;
}
- if (port_list == "") {
+ if (port_list.is_empty()) {
port_list = TTR("None");
}
property.hint_string = port_list;
@@ -3063,7 +3063,7 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::
String code;
while (ports[idx].mode != Shader::MODE_MAX) {
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
- if (p_input_vars[count] != String()) {
+ if (!p_input_vars[count].is_empty()) {
String s = ports[idx].string;
if (s.find(":") != -1) {
code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 951870fe34..51e7ec8092 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -535,15 +535,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
if (source == SOURCE_TEXTURE) {
String id = make_unique_id(p_type, p_id, "tex");
String code;
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n";
} else {
code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
} else {
@@ -560,18 +560,18 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
String code;
code += " {\n";
- if (id == String()) {
+ if (id.is_empty()) {
code += " vec4 " + id + "_tex_read = vec4(0.0);\n";
} else {
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n";
} else {
code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
} else {
@@ -587,15 +587,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
String code = " {\n";
- if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default.
+ if (p_input_vars[0].is_empty() || p_for_preview) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", 0.0 );\n";
} else {
code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, 0.0);\n";
} else {
@@ -610,15 +610,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
String code = " {\n";
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 _tex_read = texture(TEXTURE, " + default_uv + ");\n";
} else {
code += " vec4 _tex_read = textureLod(TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ".xy);\n";
} else {
@@ -633,15 +633,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
String code = " {\n";
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + default_uv + ");\n";
} else {
code += " vec4 _tex_read = textureLod(NORMAL_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy);\n";
} else {
@@ -666,15 +666,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
String code = " {\n";
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " float _depth = texture(DEPTH_TEXTURE, " + default_uv + ").r;\n";
} else {
code += " float _depth = textureLod(DEPTH_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ").r;\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " float _depth = texture(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy).r;\n";
} else {
@@ -883,7 +883,7 @@ String VisualShaderNodeCurveTexture::generate_global(Shader::Mode p_mode, Visual
}
String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- if (p_input_vars[0] == String()) {
+ if (p_input_vars[0].is_empty()) {
return " " + p_output_vars[0] + " = 0.0;\n";
}
String id = make_unique_id(p_type, p_id, "curve");
@@ -968,7 +968,7 @@ String VisualShaderNodeCurveXYZTexture::generate_global(Shader::Mode p_mode, Vis
}
String VisualShaderNodeCurveXYZTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- if (p_input_vars[0] == String()) {
+ if (p_input_vars[0].is_empty()) {
return " " + p_output_vars[0] + " = vec3(0.0);\n";
}
String id = make_unique_id(p_type, p_id, "curve3d");
@@ -1076,14 +1076,14 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader
} else {
id = p_input_vars[2];
}
- if (id != String()) {
- if (p_input_vars[0] == String()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (!id.is_empty()) {
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
+ if (p_input_vars[1].is_empty()) {
code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n";
} else {
code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
} else {
@@ -1364,7 +1364,7 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader:
code += " {\n";
- if (id == String()) {
+ if (id.is_empty()) {
code += " vec4 " + id + "_read = vec4(0.0);\n";
code += " " + p_output_vars[0] + " = " + id + "_read.rgb;\n";
code += " " + p_output_vars[1] + " = " + id + "_read.a;\n";
@@ -1372,15 +1372,15 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader:
return code;
}
- if (p_input_vars[0] == String()) { // Use UV by default.
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n";
} else {
code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + " );\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
} else {
@@ -1647,6 +1647,21 @@ String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::T
case OP_MIN:
code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
break;
+ case OP_BITWISE_AND:
+ code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_OR:
+ code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_XOR:
+ code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_LEFT_SHIFT:
+ code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_RIGHT_SHIFT:
+ code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n";
+ break;
default:
break;
}
@@ -1677,7 +1692,7 @@ void VisualShaderNodeIntOp::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator");
BIND_ENUM_CONSTANT(OP_ADD);
BIND_ENUM_CONSTANT(OP_SUB);
@@ -1686,6 +1701,11 @@ void VisualShaderNodeIntOp::_bind_methods() {
BIND_ENUM_CONSTANT(OP_MOD);
BIND_ENUM_CONSTANT(OP_MAX);
BIND_ENUM_CONSTANT(OP_MIN);
+ BIND_ENUM_CONSTANT(OP_BITWISE_AND);
+ BIND_ENUM_CONSTANT(OP_BITWISE_OR);
+ BIND_ENUM_CONSTANT(OP_BITWISE_XOR);
+ BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT);
+ BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT);
BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
}
@@ -2333,7 +2353,8 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader:
static const char *functions[FUNC_MAX] = {
"abs($)",
"-($)",
- "sign($)"
+ "sign($)",
+ "~($)"
};
return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
@@ -2362,11 +2383,12 @@ void VisualShaderNodeIntFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign,Bitwise NOT"), "set_function", "get_function");
BIND_ENUM_CONSTANT(FUNC_ABS);
BIND_ENUM_CONSTANT(FUNC_NEGATE);
BIND_ENUM_CONSTANT(FUNC_SIGN);
+ BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT);
BIND_ENUM_CONSTANT(FUNC_MAX);
}
@@ -4880,13 +4902,13 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual
String id = get_uniform_name();
String code = " {\n";
- if (p_input_vars[0] == String()) { // Use UV by default.
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[0].is_empty()) { // Use UV by default.
+ if (p_input_vars[1].is_empty()) {
code += " vec4 n_tex_read = texture(" + id + ", " + default_uv + ");\n";
} else {
code += " vec4 n_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1] == String()) {
+ } else if (p_input_vars[1].is_empty()) {
//no lod
code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
} else {
@@ -5048,11 +5070,11 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod
String id = get_uniform_name();
String code = " {\n";
- if (p_input_vars[0] == String() && p_input_vars[1] == String()) {
+ if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n";
- } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) {
+ } else if (!p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n";
- } else if (p_input_vars[0] == String() && p_input_vars[1] != String()) {
+ } else if (p_input_vars[0].is_empty() && !p_input_vars[1].is_empty()) {
code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n";
} else {
code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
@@ -5578,12 +5600,12 @@ bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const {
String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String normal;
String view;
- if (p_input_vars[0] == String()) {
+ if (p_input_vars[0].is_empty()) {
normal = "NORMAL";
} else {
normal = p_input_vars[0];
}
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
view = "VIEW";
} else {
view = p_input_vars[1];
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 2c952300fe..2f3400404c 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -579,6 +579,11 @@ public:
OP_MOD,
OP_MAX,
OP_MIN,
+ OP_BITWISE_AND,
+ OP_BITWISE_OR,
+ OP_BITWISE_XOR,
+ OP_BITWISE_LEFT_SHIFT,
+ OP_BITWISE_RIGHT_SHIFT,
OP_ENUM_SIZE,
};
@@ -882,6 +887,7 @@ public:
FUNC_ABS,
FUNC_NEGATE,
FUNC_SIGN,
+ FUNC_BITWISE_NOT,
FUNC_MAX,
};
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 1a829968e3..a7c20b2cb9 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -318,26 +318,24 @@ String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) cons
String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code;
- if (mesh.is_valid()) {
- if (is_output_port_connected(0)) { // position
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
- }
+ if (is_output_port_connected(0)) { // position
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
+ }
- if (is_output_port_connected(1)) { // normal
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
- }
+ if (is_output_port_connected(1)) { // normal
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
+ }
- if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
- }
+ if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
+ }
- if (is_output_port_connected(4)) { // uv
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
- }
+ if (is_output_port_connected(4)) { // uv
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
+ }
- if (is_output_port_connected(5)) { // uv2
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
- }
+ if (is_output_port_connected(5)) { // uv2
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
}
return code;
@@ -503,67 +501,97 @@ void VisualShaderNodeParticleMeshEmitter::_update_textures() {
Vector<Vector2> uvs;
Vector<Vector2> uvs2;
+ const int surface_count = mesh->get_surface_count();
+
if (use_all_surfaces) {
- for (int i = 0; i < max_surface_index; i++) {
+ for (int i = 0; i < surface_count; i++) {
+ const Array surface_arrays = mesh->surface_get_arrays(i);
+ const int surface_arrays_size = surface_arrays.size();
+
// position
- Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX];
- for (int j = 0; j < vertex_array.size(); j++) {
- vertices.push_back((Vector3)vertex_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
+ Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
+ for (int j = 0; j < vertex_array.size(); j++) {
+ vertices.push_back((Vector3)vertex_array[j]);
+ }
}
// normal
- Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL];
- for (int j = 0; j < normal_array.size(); j++) {
- normals.push_back((Vector3)normal_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
+ Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
+ for (int j = 0; j < normal_array.size(); j++) {
+ normals.push_back((Vector3)normal_array[j]);
+ }
}
// color
- Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR];
- for (int j = 0; j < color_array.size(); j++) {
- colors.push_back((Color)color_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_COLOR) {
+ Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
+ for (int j = 0; j < color_array.size(); j++) {
+ colors.push_back((Color)color_array[j]);
+ }
}
// uv
- Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV];
- for (int j = 0; j < uv_array.size(); j++) {
- uvs.push_back((Vector2)uv_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
+ Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
+ }
}
// uv2
- Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV2];
- for (int j = 0; j < uv2_array.size(); j++) {
- uvs2.push_back((Vector2)uv2_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
+ Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
+ }
}
}
} else {
- // position
- Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX];
- for (int i = 0; i < vertex_array.size(); i++) {
- vertices.push_back((Vector3)vertex_array[i]);
- }
+ if (surface_index >= 0 && surface_index < surface_count) {
+ const Array surface_arrays = mesh->surface_get_arrays(surface_index);
+ const int surface_arrays_size = surface_arrays.size();
- // normal
- Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_NORMAL];
- for (int i = 0; i < normal_array.size(); i++) {
- normals.push_back((Vector3)normal_array[i]);
- }
+ // position
+ if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
+ Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
+ for (int i = 0; i < vertex_array.size(); i++) {
+ vertices.push_back((Vector3)vertex_array[i]);
+ }
+ }
- // color
- Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_COLOR];
- for (int i = 0; i < color_array.size(); i++) {
- colors.push_back((Color)color_array[i]);
- }
+ // normal
+ if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
+ Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
+ for (int i = 0; i < normal_array.size(); i++) {
+ normals.push_back((Vector3)normal_array[i]);
+ }
+ }
- // uv
- Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV];
- for (int j = 0; j < uv_array.size(); j++) {
- uvs.push_back((Vector2)uv_array[j]);
- }
+ // color
+ if (surface_arrays_size > Mesh::ARRAY_COLOR) {
+ Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
+ for (int i = 0; i < color_array.size(); i++) {
+ colors.push_back((Color)color_array[i]);
+ }
+ }
+
+ // uv
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
+ Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
+ }
+ }
- // uv2
- Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV2];
- for (int j = 0; j < uv2_array.size(); j++) {
- uvs2.push_back((Vector2)uv2_array[j]);
+ // uv2
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
+ Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
+ }
+ }
}
}
@@ -579,12 +607,6 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
return;
}
- if (p_mesh.is_valid()) {
- max_surface_index = p_mesh->get_surface_count();
- } else {
- max_surface_index = 0;
- }
-
if (mesh.is_valid()) {
Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures);
@@ -623,7 +645,16 @@ bool VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces() const {
}
void VisualShaderNodeParticleMeshEmitter::set_surface_index(int p_surface_index) {
- if (p_surface_index == surface_index || p_surface_index < 0 || p_surface_index >= max_surface_index) {
+ if (mesh.is_valid()) {
+ if (mesh->get_surface_count() > 0) {
+ p_surface_index = CLAMP(p_surface_index, 0, mesh->get_surface_count() - 1);
+ } else {
+ p_surface_index = 0;
+ }
+ } else if (p_surface_index < 0) {
+ p_surface_index = 0;
+ }
+ if (surface_index == p_surface_index) {
return;
}
surface_index = p_surface_index;
diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h
index 79459432f1..ae7ea69225 100644
--- a/scene/resources/visual_shader_particle_nodes.h
+++ b/scene/resources/visual_shader_particle_nodes.h
@@ -111,7 +111,6 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt
Ref<Mesh> mesh;
bool use_all_surfaces = true;
int surface_index = 0;
- int max_surface_index = 0;
Ref<ImageTexture> position_texture;
Ref<ImageTexture> normal_texture;
diff --git a/scene/resources/visual_shader_sdf_nodes.cpp b/scene/resources/visual_shader_sdf_nodes.cpp
index 14c655b129..0fe7c33396 100644
--- a/scene/resources/visual_shader_sdf_nodes.cpp
+++ b/scene/resources/visual_shader_sdf_nodes.cpp
@@ -61,7 +61,7 @@ String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
}
String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return " " + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+ return " " + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
}
VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() {
@@ -105,7 +105,7 @@ String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) co
}
String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return " " + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+ return " " + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
}
VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() {
@@ -142,7 +142,7 @@ String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
+ return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
}
VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() {
@@ -179,7 +179,7 @@ String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const
}
String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return " " + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+ return " " + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
}
VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() {
@@ -242,13 +242,13 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha
code += " {\n";
- if (p_input_vars[0] == String()) {
+ if (p_input_vars[0].is_empty()) {
code += " vec2 __from_pos = vec2(0.0f);\n";
} else {
code += " vec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
}
- if (p_input_vars[1] == String()) {
+ if (p_input_vars[1].is_empty()) {
code += " vec2 __to_pos = vec2(0.0f);\n";
} else {
code += " vec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index 186764e69e..a5ed27cb7b 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -61,6 +61,7 @@ SceneStringNames::SceneStringNames() {
animation_finished = StaticCString::create("animation_finished");
animation_changed = StaticCString::create("animation_changed");
animation_started = StaticCString::create("animation_started");
+ RESET = StaticCString::create("RESET");
pose_updated = StaticCString::create("pose_updated");
bone_pose_changed = StaticCString::create("bone_pose_changed");
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 67007c85e0..b1ace1748c 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -97,6 +97,7 @@ public:
StringName animation_finished;
StringName animation_changed;
StringName animation_started;
+ StringName RESET;
StringName pose_updated;
StringName bone_pose_changed;
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index d9c442facf..b37965a988 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -43,7 +43,7 @@ int AudioRBResampler::get_channel_count() const {
// Linear interpolation based sample rate conversion (low quality)
// Note that AudioStreamPlaybackResampled::mix has better algorithm,
-// but it wasn't obvious to integrate that with VideoPlayer
+// but it wasn't obvious to integrate that with VideoStreamPlayer
template <int C>
uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) {
uint32_t read = offset & MIX_FRAC_MASK;
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index d9ee91084f..0837e41db8 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -65,7 +65,11 @@ public:
Vector<DisplayServer::WindowID> get_window_list() const override { return Vector<DisplayServer::WindowID>(); }
- WindowID get_window_at_screen_position(const Point2i &p_position) const override { return -1; }
+ WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override { return 0; }
+ void show_window(WindowID p_id) override {}
+ void delete_sub_window(WindowID p_id) override {}
+
+ WindowID get_window_at_screen_position(const Point2i &p_position) const override { return 0; }
void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override {}
ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override { return ObjectID(); }
@@ -93,7 +97,7 @@ public:
Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {}
- Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); };
+ Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {}
Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
@@ -102,10 +106,13 @@ public:
void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override {}
WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override { return WINDOW_MODE_MINIMIZED; }
+ void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override {}
+ VSyncMode window_get_vsync_mode(WindowID p_window) const override { return VSyncMode::VSYNC_ENABLED; }
+
bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override {}
- virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
+ bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override {}
void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override {}
@@ -114,6 +121,9 @@ public:
bool can_any_window_draw() const override { return false; }
+ void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override {}
+ void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override {}
+
void process_events() override {}
void set_icon(const Ref<Image> &p_icon) override {}
diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp
index 6d1c5539aa..44da5d4f3b 100644
--- a/servers/physics_2d/godot_body_2d.cpp
+++ b/servers/physics_2d/godot_body_2d.cpp
@@ -549,6 +549,9 @@ void GodotBody2D::integrate_forces(real_t p_step) {
gravity *= gravity_scale;
+ prev_linear_velocity = linear_velocity;
+ prev_angular_velocity = angular_velocity;
+
Vector2 motion;
bool do_motion = false;
diff --git a/servers/physics_2d/godot_body_2d.h b/servers/physics_2d/godot_body_2d.h
index 0df93482dc..f00512fe92 100644
--- a/servers/physics_2d/godot_body_2d.h
+++ b/servers/physics_2d/godot_body_2d.h
@@ -50,6 +50,9 @@ class GodotBody2D : public GodotCollisionObject2D {
Vector2 linear_velocity;
real_t angular_velocity = 0.0;
+ Vector2 prev_linear_velocity;
+ real_t prev_angular_velocity = 0.0;
+
Vector2 constant_linear_velocity;
real_t constant_angular_velocity = 0.0;
@@ -209,6 +212,9 @@ public:
_FORCE_INLINE_ void set_angular_velocity(real_t p_velocity) { angular_velocity = p_velocity; }
_FORCE_INLINE_ real_t get_angular_velocity() const { return angular_velocity; }
+ _FORCE_INLINE_ Vector2 get_prev_linear_velocity() const { return prev_linear_velocity; }
+ _FORCE_INLINE_ real_t get_prev_angular_velocity() const { return prev_angular_velocity; }
+
_FORCE_INLINE_ void set_biased_linear_velocity(const Vector2 &p_velocity) { biased_linear_velocity = p_velocity; }
_FORCE_INLINE_ Vector2 get_biased_linear_velocity() const { return biased_linear_velocity; }
@@ -228,9 +234,15 @@ public:
angular_velocity += _inv_inertia * p_torque;
}
- _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) {
+ _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2(), real_t p_max_delta_av = -1.0) {
biased_linear_velocity += p_impulse * _inv_mass;
- biased_angular_velocity += _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av != 0.0) {
+ real_t delta_av = _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av > 0 && delta_av > p_max_delta_av) {
+ delta_av = p_max_delta_av;
+ }
+ biased_angular_velocity += delta_av;
+ }
}
void set_active(bool p_active);
diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp
index 97eeefbfe6..f8ec0b6512 100644
--- a/servers/physics_2d/godot_body_pair_2d.cpp
+++ b/servers/physics_2d/godot_body_pair_2d.cpp
@@ -32,9 +32,11 @@
#include "godot_collision_solver_2d.h"
#include "godot_space_2d.h"
-#define POSITION_CORRECTION
#define ACCUMULATE_IMPULSES
+#define MIN_VELOCITY 0.001
+#define MAX_BIAS_ROTATION (Math_PI / 8)
+
void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) {
GodotBodyPair2D *self = (GodotBodyPair2D *)p_self;
@@ -42,8 +44,6 @@ void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_po
}
void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) {
- // check if we already have the contact
-
Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A);
Vector2 local_B = B->get_inv_transform().basis_xform(p_point_B - offset_B);
@@ -52,46 +52,48 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_tangent_impulse = 0;
contact.local_A = local_A;
contact.local_B = local_B;
- contact.reused = true;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
-
- // attempt to determine if the contact will be reused
+ contact.used = true;
+ // Attempt to determine if the contact will be reused.
real_t recycle_radius_2 = space->get_contact_recycle_radius() * space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (
- c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
+ if (c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
c.local_B.distance_squared_to(local_B) < (recycle_radius_2)) {
contact.acc_normal_impulse = c.acc_normal_impulse;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
contact.acc_bias_impulse = c.acc_bias_impulse;
- new_index = i;
- break;
+ contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
-
- int least_deep = -1;
- real_t min_depth = 1e10;
+ // Remove the contact with the minimum depth.
const Transform2D &transform_A = A->get_transform();
const Transform2D &transform_B = B->get_transform();
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
+ int least_deep = -1;
+ real_t min_depth;
+
+ // Start with depth for new contact.
+ {
+ Vector2 global_A = transform_A.basis_xform(contact.local_A);
+ Vector2 global_B = transform_B.basis_xform(contact.local_B) + offset_B;
+
+ Vector2 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
+
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -104,10 +106,8 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -115,15 +115,11 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair2D::_validate_contacts() {
- //make sure to erase contacts that are no longer valid
-
+ // Make sure to erase contacts that are no longer valid.
real_t max_separation = space->get_contact_max_separation();
real_t max_separation2 = max_separation * max_separation;
@@ -134,11 +130,11 @@ void GodotBodyPair2D::_validate_contacts() {
Contact &c = contacts[i];
bool erase = false;
- if (!c.reused) {
- //was left behind in previous frame
+ if (!c.used) {
+ // Was left behind in previous frame.
erase = true;
} else {
- c.reused = false;
+ c.used = false;
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -151,10 +147,10 @@ void GodotBodyPair2D::_validate_contacts() {
}
if (erase) {
- // contact no longer needed, remove
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -303,9 +299,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted)
continue;
}
@@ -324,9 +317,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok)
continue;
}
@@ -351,7 +341,7 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = 0.3;
+ real_t bias = space->get_contact_bias();
GodotShape2D *shape_A_ptr = A->get_shape(shape_A);
GodotShape2D *shape_B_ptr = B->get_shape(shape_B);
@@ -390,7 +380,7 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
- if (depth <= 0.0 || !c.reused) {
+ if (depth <= 0.0) {
continue;
}
@@ -401,8 +391,8 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
}
#endif
- c.rA = global_A;
- c.rB = global_B - offset_B;
+ c.rA = global_A - A->get_center_of_mass();
+ c.rB = global_B - B->get_center_of_mass() - offset_B;
if (A->can_report_contacts()) {
Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x);
@@ -435,7 +425,6 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration);
c.depth = depth;
- //c.acc_bias_impulse=0;
#ifdef ACCUMULATE_IMPULSES
{
@@ -443,19 +432,19 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 P = c.acc_normal_impulse * c.normal + c.acc_tangent_impulse * tangent;
if (collide_A) {
- A->apply_impulse(-P, c.rA);
+ A->apply_impulse(-P, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(P, c.rB);
+ B->apply_impulse(P, c.rB + B->get_center_of_mass());
}
}
#endif
c.bounce = combine_bounce(A, B);
if (c.bounce) {
- Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x);
- Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x);
- Vector2 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
+ Vector2 crA(-A->get_prev_angular_velocity() * c.rA.y, A->get_prev_angular_velocity() * c.rA.x);
+ Vector2 crB(-B->get_prev_angular_velocity() * c.rB.y, B->get_prev_angular_velocity() * c.rB.x);
+ Vector2 dv = B->get_prev_linear_velocity() + crB - A->get_prev_linear_velocity() - crA;
c.bounce = c.bounce * dv.dot(c.normal);
}
@@ -471,6 +460,11 @@ void GodotBodyPair2D::solve(real_t p_step) {
return;
}
+ const real_t max_bias_av = MAX_BIAS_ROTATION / p_step;
+
+ real_t inv_mass_A = collide_A ? A->get_inv_mass() : 0.0;
+ real_t inv_mass_B = collide_B ? B->get_inv_mass() : 0.0;
+
for (int i = 0; i < contact_count; ++i) {
Contact &c = contacts[i];
@@ -490,6 +484,7 @@ void GodotBodyPair2D::solve(real_t p_step) {
real_t vn = dv.dot(c.normal);
real_t vbn = dbv.dot(c.normal);
+
Vector2 tangent = c.normal.orthogonal();
real_t vt = dv.dot(tangent);
@@ -500,10 +495,31 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 jb = c.normal * (c.acc_bias_impulse - jbnOld);
if (collide_A) {
- A->apply_bias_impulse(-jb, c.rA);
+ A->apply_bias_impulse(-jb, c.rA + A->get_center_of_mass(), max_bias_av);
}
if (collide_B) {
- B->apply_bias_impulse(jb, c.rB);
+ B->apply_bias_impulse(jb, c.rB + B->get_center_of_mass(), max_bias_av);
+ }
+
+ crbA = Vector2(-A->get_biased_angular_velocity() * c.rA.y, A->get_biased_angular_velocity() * c.rA.x);
+ crbB = Vector2(-B->get_biased_angular_velocity() * c.rB.y, B->get_biased_angular_velocity() * c.rB.x);
+ dbv = B->get_biased_linear_velocity() + crbB - A->get_biased_linear_velocity() - crbA;
+
+ vbn = dbv.dot(c.normal);
+
+ if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) {
+ real_t jbn_com = (-vbn + c.bias) / (inv_mass_A + inv_mass_B);
+ real_t jbnOld_com = c.acc_bias_impulse_center_of_mass;
+ c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f);
+
+ Vector2 jb_com = c.normal * (c.acc_bias_impulse_center_of_mass - jbnOld_com);
+
+ if (collide_A) {
+ A->apply_bias_impulse(-jb_com, A->get_center_of_mass(), 0.0f);
+ }
+ if (collide_B) {
+ B->apply_bias_impulse(jb_com, B->get_center_of_mass(), 0.0f);
+ }
}
real_t jn = -(c.bounce + vn) * c.mass_normal;
@@ -520,10 +536,10 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 j = c.normal * (c.acc_normal_impulse - jnOld) + tangent * (c.acc_tangent_impulse - jtOld);
if (collide_A) {
- A->apply_impulse(-j, c.rA);
+ A->apply_impulse(-j, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(j, c.rB);
+ B->apply_impulse(j, c.rB + B->get_center_of_mass());
}
}
}
diff --git a/servers/physics_2d/godot_body_pair_2d.h b/servers/physics_2d/godot_body_pair_2d.h
index 0938ab542b..aa1b5b7886 100644
--- a/servers/physics_2d/godot_body_pair_2d.h
+++ b/servers/physics_2d/godot_body_pair_2d.h
@@ -62,13 +62,14 @@ class GodotBodyPair2D : public GodotConstraint2D {
real_t acc_normal_impulse = 0.0; // accumulated normal impulse (Pn)
real_t acc_tangent_impulse = 0.0; // accumulated tangent impulse (Pt)
real_t acc_bias_impulse = 0.0; // accumulated normal impulse for position bias (Pnb)
+ real_t acc_bias_impulse_center_of_mass = 0.0; // accumulated normal impulse for position bias applied to com
real_t mass_normal, mass_tangent = 0.0;
real_t bias = 0.0;
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector2 rA, rB;
- bool reused = false;
real_t bounce = 0.0;
};
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index 8ac27077fc..c88fd39657 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -1214,21 +1214,16 @@ void GodotPhysicsServer2D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer2D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer2D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer2D::init() {
doing_sync = false;
- iterations = 8; // 8?
stepper = memnew(GodotStep2D);
-};
+}
void GodotPhysicsServer2D::step(real_t p_step) {
if (!active) {
@@ -1241,16 +1236,16 @@ void GodotPhysicsServer2D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace2D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace2D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
}
-};
+}
void GodotPhysicsServer2D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer2D::flush_queries() {
if (!active) {
@@ -1308,7 +1303,7 @@ void GodotPhysicsServer2D::end_sync() {
void GodotPhysicsServer2D::finish() {
memdelete(stepper);
-};
+}
void GodotPhysicsServer2D::_update_shapes() {
while (pending_shape_update_list.first()) {
@@ -1340,4 +1335,4 @@ GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) {
GodotBroadPhase2D::create_func = GodotBroadPhase2DBVH::_create;
using_threads = p_using_threads;
-};
+}
diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h
index 1f544fee72..ad6d5e0940 100644
--- a/servers/physics_2d/godot_physics_server_2d.h
+++ b/servers/physics_2d/godot_physics_server_2d.h
@@ -45,7 +45,6 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
friend class GodotPhysicsDirectSpaceState2D;
friend class GodotPhysicsDirectBodyState2D;
bool active = true;
- int iterations = 0;
bool doing_sync = false;
int island_count = 0;
@@ -283,8 +282,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp
index 7a5eb26bb3..5e6f233667 100644
--- a/servers/physics_2d/godot_space_2d.cpp
+++ b/servers/physics_2d/godot_space_2d.cpp
@@ -1138,9 +1138,12 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1153,6 +1156,9 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
constraint_bias = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
+ break;
}
}
@@ -1162,8 +1168,10 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
@@ -1172,6 +1180,8 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return body_time_to_sleep;
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
return constraint_bias;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
diff --git a/servers/physics_2d/godot_space_2d.h b/servers/physics_2d/godot_space_2d.h
index b155a834b6..c0d06706d8 100644
--- a/servers/physics_2d/godot_space_2d.h
+++ b/servers/physics_2d/godot_space_2d.h
@@ -96,9 +96,12 @@ private:
GodotArea2D *area = nullptr;
+ int solver_iterations = 16;
+
real_t contact_recycle_radius = 1.0;
real_t contact_max_separation = 1.5;
real_t contact_max_allowed_penetration = 0.3;
+ real_t contact_bias = 0.8;
real_t constraint_bias = 0.2;
enum {
@@ -155,9 +158,11 @@ public:
void remove_object(GodotCollisionObject2D *p_object);
const Set<GodotCollisionObject2D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 00d11acdab..bc604e380a 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -124,14 +124,14 @@ void GodotStep2D::_check_suspend(LocalVector<GodotBody2D *> &p_body_island) cons
}
}
-void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody2D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h
index efec243632..4038417854 100644
--- a/servers/physics_2d/godot_step_2d.h
+++ b/servers/physics_2d/godot_step_2d.h
@@ -55,7 +55,7 @@ class GodotStep2D {
void _check_suspend(LocalVector<GodotBody2D *> &p_body_island) const;
public:
- void step(GodotSpace2D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace2D *p_space, real_t p_delta);
GodotStep2D();
~GodotStep2D();
};
diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp
index 40d946655d..d5098a2a5f 100644
--- a/servers/physics_3d/godot_body_3d.cpp
+++ b/servers/physics_3d/godot_body_3d.cpp
@@ -604,6 +604,9 @@ void GodotBody3D::integrate_forces(real_t p_step) {
gravity *= gravity_scale;
+ prev_linear_velocity = linear_velocity;
+ prev_angular_velocity = angular_velocity;
+
Vector3 motion;
bool do_motion = false;
diff --git a/servers/physics_3d/godot_body_3d.h b/servers/physics_3d/godot_body_3d.h
index bba9ec6c3a..6ea6d1fcaa 100644
--- a/servers/physics_3d/godot_body_3d.h
+++ b/servers/physics_3d/godot_body_3d.h
@@ -45,6 +45,9 @@ class GodotBody3D : public GodotCollisionObject3D {
Vector3 linear_velocity;
Vector3 angular_velocity;
+ Vector3 prev_linear_velocity;
+ Vector3 prev_angular_velocity;
+
Vector3 constant_linear_velocity;
Vector3 constant_angular_velocity;
@@ -207,6 +210,9 @@ public:
_FORCE_INLINE_ void set_angular_velocity(const Vector3 &p_velocity) { angular_velocity = p_velocity; }
_FORCE_INLINE_ Vector3 get_angular_velocity() const { return angular_velocity; }
+ _FORCE_INLINE_ Vector3 get_prev_linear_velocity() const { return prev_linear_velocity; }
+ _FORCE_INLINE_ Vector3 get_prev_angular_velocity() const { return prev_angular_velocity; }
+
_FORCE_INLINE_ const Vector3 &get_biased_linear_velocity() const { return biased_linear_velocity; }
_FORCE_INLINE_ const Vector3 &get_biased_angular_velocity() const { return biased_angular_velocity; }
diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/servers/physics_3d/godot_body_pair_3d.cpp
index f0002870ae..5c25ba9537 100644
--- a/servers/physics_3d/godot_body_pair_3d.cpp
+++ b/servers/physics_3d/godot_body_pair_3d.cpp
@@ -35,18 +35,6 @@
#include "core/os/os.h"
-/*
-#define NO_ACCUMULATE_IMPULSES
-#define NO_SPLIT_IMPULSES
-
-#define NO_FRICTION
-*/
-
-#define NO_TANGENTIALS
-/* BODY PAIR */
-
-//#define ALLOWED_PENETRATION 0.01
-#define RELAXATION_TIMESTEPS 3
#define MIN_VELOCITY 0.0001
#define MAX_BIAS_ROTATION (Math_PI / 8)
@@ -56,11 +44,6 @@ void GodotBodyPair3D::_contact_added_callback(const Vector3 &p_point_A, int p_in
}
void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) {
- // check if we already have the contact
-
- //Vector3 local_A = A->get_inv_transform().xform(p_point_A);
- //Vector3 local_B = B->get_inv_transform().xform(p_point_B);
-
Vector3 local_A = A->get_inv_transform().basis.xform(p_point_A);
Vector3 local_B = B->get_inv_transform().basis.xform(p_point_B - offset_B);
@@ -69,19 +52,14 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.index_A = p_index_A;
contact.index_B = p_index_B;
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
+ contact.used = true;
- // attempt to determine if the contact will be reused
+ // Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
@@ -92,23 +70,34 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
contact.acc_bias_impulse = c.acc_bias_impulse;
contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
- new_index = i;
- break;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
+ // Remove the contact with the minimum depth.
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
int least_deep = -1;
- real_t min_depth = 1e10;
+ real_t min_depth;
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
+ // Start with depth for new contact.
+ {
+ Vector3 global_A = basis_A.xform(contact.local_A);
+ Vector3 global_B = basis_B.xform(contact.local_B) + offset_B;
+
+ Vector3 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
+
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
Vector3 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
@@ -119,10 +108,8 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -130,29 +117,41 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair3D::validate_contacts() {
- //make sure to erase contacts that are no longer valid
+ // Make sure to erase contacts that are no longer valid.
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
- real_t contact_max_separation = space->get_contact_max_separation();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
- // contact no longer needed, remove
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
+ if (erase) {
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -272,7 +271,7 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = 0.8;
GodotShape3D *shape_A_ptr = A->get_shape(shape_A);
GodotShape3D *shape_B_ptr = B->get_shape(shape_B);
@@ -365,15 +364,12 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) {
if (collide_B) {
B->apply_impulse(j_vec, c.rB + B->get_center_of_mass());
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = combine_bounce(A, B);
if (c.bounce) {
- Vector3 crA = A->get_angular_velocity().cross(c.rA);
- Vector3 crB = B->get_angular_velocity().cross(c.rB);
- Vector3 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
- //normal impule
+ Vector3 crA = A->get_prev_angular_velocity().cross(c.rA);
+ Vector3 crB = B->get_prev_angular_velocity().cross(c.rB);
+ Vector3 dv = B->get_prev_linear_velocity() + crB - A->get_prev_linear_velocity() - crA;
c.bounce = c.bounce * dv.dot(c.normal);
}
}
@@ -551,14 +547,10 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
Contact contact;
contact.index_A = p_index_A;
contact.index_B = p_index_B;
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0;
+ contact.used = true;
// Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
@@ -584,20 +576,33 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
void GodotBodySoftBodyPair3D::validate_contacts() {
// Make sure to erase contacts that are no longer valid.
- const Transform3D &transform_A = body->get_transform();
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
- real_t contact_max_separation = space->get_contact_max_separation();
+ const Transform3D &transform_A = body->get_transform();
uint32_t contact_count = contacts.size();
for (uint32_t contact_index = 0; contact_index < contact_count; ++contact_index) {
Contact &c = contacts[contact_index];
- Vector3 global_A = transform_A.xform(c.local_A);
- Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = transform_A.xform(c.local_A);
+ Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
+
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
+ if (erase) {
// Contact no longer needed, remove.
if ((contact_index + 1) < contact_count) {
// Swap with the last one.
@@ -653,7 +658,7 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = space->get_contact_bias();
GodotShape3D *shape_A_ptr = body->get_shape(body_shape);
@@ -736,8 +741,6 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
if (soft_body_collides) {
soft_body->apply_node_impulse(c.index_B, j_vec);
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = body->get_bounce();
diff --git a/servers/physics_3d/godot_body_pair_3d.h b/servers/physics_3d/godot_body_pair_3d.h
index c0a2424e05..7c2c31704b 100644
--- a/servers/physics_3d/godot_body_pair_3d.h
+++ b/servers/physics_3d/godot_body_pair_3d.h
@@ -54,6 +54,7 @@ protected:
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector3 rA, rB; // Offset in world orientation with respect to center of mass
};
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp
index 9acae62382..573a5d373f 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/servers/physics_3d/godot_physics_server_3d.cpp
@@ -1574,20 +1574,15 @@ void GodotPhysicsServer3D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer3D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer3D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer3D::init() {
- iterations = 8; // 8?
stepper = memnew(GodotStep3D);
-};
+}
void GodotPhysicsServer3D::step(real_t p_step) {
#ifndef _3D_DISABLED
@@ -1602,7 +1597,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace3D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace3D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
@@ -1612,7 +1607,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
void GodotPhysicsServer3D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer3D::flush_queries() {
#ifndef _3D_DISABLED
@@ -1665,15 +1660,15 @@ void GodotPhysicsServer3D::flush_queries() {
EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
-};
+}
void GodotPhysicsServer3D::end_sync() {
doing_sync = false;
-};
+}
void GodotPhysicsServer3D::finish() {
memdelete(stepper);
-};
+}
int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) {
switch (p_info) {
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h
index f5c8e0f60d..be9bbea76b 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/servers/physics_3d/godot_physics_server_3d.h
@@ -44,7 +44,6 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
friend class GodotPhysicsDirectSpaceState3D;
bool active = true;
- int iterations = 0;
int island_count = 0;
int active_objects = 0;
@@ -364,8 +363,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp
index f503273c88..b2a8b00bca 100644
--- a/servers/physics_3d/godot_space_3d.cpp
+++ b/servers/physics_3d/godot_space_3d.cpp
@@ -1173,9 +1173,12 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1191,6 +1194,9 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
constraint_bias = p_value;
break;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
+ break;
}
}
@@ -1200,8 +1206,10 @@ real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
@@ -1212,6 +1220,8 @@ real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const {
return body_angular_velocity_damp_ratio;
case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
return constraint_bias;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
diff --git a/servers/physics_3d/godot_space_3d.h b/servers/physics_3d/godot_space_3d.h
index aa5e965751..b9aeee7583 100644
--- a/servers/physics_3d/godot_space_3d.h
+++ b/servers/physics_3d/godot_space_3d.h
@@ -93,9 +93,12 @@ private:
GodotArea3D *area = nullptr;
+ int solver_iterations = 16;
+
real_t contact_recycle_radius = 0.01;
real_t contact_max_separation = 0.05;
real_t contact_max_allowed_penetration = 0.01;
+ real_t contact_bias = 0.8;
real_t constraint_bias = 0.01;
enum {
@@ -159,9 +162,11 @@ public:
void remove_object(GodotCollisionObject3D *p_object);
const Set<GodotCollisionObject3D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index 5453c4415c..6332532f6e 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -181,14 +181,14 @@ void GodotStep3D::_check_suspend(const LocalVector<GodotBody3D *> &p_body_island
}
}
-void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody3D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h
index 23ede4feff..10389713f6 100644
--- a/servers/physics_3d/godot_step_3d.h
+++ b/servers/physics_3d/godot_step_3d.h
@@ -56,7 +56,7 @@ class GodotStep3D {
void _check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const;
public:
- void step(GodotSpace3D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace3D *p_space, real_t p_delta);
GodotStep3D();
~GodotStep3D();
};
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 76f0b74c72..c660bd4d69 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -730,17 +730,17 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer2D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer2D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer2D::get_process_info);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
BIND_ENUM_CONSTANT(SHAPE_SEPARATION_RAY);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 2bff8f5dcb..6625be6d14 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -242,11 +242,13 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -566,8 +568,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -758,10 +758,9 @@ class PhysicsServer2DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index dda4eb6ffa..f65c8921ce 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -294,7 +294,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 373f216e01..658f7daf9f 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -890,8 +890,6 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer3D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer3D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer3D::get_process_info);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
@@ -963,12 +961,14 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_X);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Y);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 89a7eeee96..dfaefc5fbf 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -263,12 +263,14 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -768,8 +770,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -965,10 +965,9 @@ class PhysicsServer3DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index 507427ecec..e6dc2d8ed9 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -370,7 +370,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 7b70483571..591023c820 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -786,7 +786,7 @@ void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
if (p_tile) {
rect->flags |= RendererCanvasRender::CANVAS_RECT_TILE;
rect->flags |= RendererCanvasRender::CANVAS_RECT_REGION;
- rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height));
+ rect->source = Rect2(0, 0, ABS(p_rect.size.width), ABS(p_rect.size.height));
}
if (p_rect.size.x < 0) {
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index b952ecbff0..4a98cf0831 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -460,14 +460,6 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant));
uint32_t instances = 1;
-#if 0
- for (uint32_t j = i+1; j < element_count; j++) {
- if (elements[i].type!=elements[j].type) {
- break;
- }
- instances++;
- }
-#endif
RD::get_singleton()->draw_list_draw(draw_list, true, instances);
i += instances;
}
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 768bd1de9d..71753f9694 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
@@ -44,7 +44,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_screen_texture = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
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 e6d9a60f94..8807ebf134 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
@@ -47,7 +47,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_screen_texture = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index d013099cce..2ff7f27d33 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1953,7 +1953,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
uses_sdf = false;
uses_time = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 522a8e8112..d310becd1e 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -240,7 +240,7 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
RendererCompositorRD::RendererCompositorRD() {
{
String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path();
- if (shader_cache_dir == String()) {
+ if (shader_cache_dir.is_empty()) {
shader_cache_dir = "user://";
}
DirAccessRef da = DirAccess::open(shader_cache_dir);
@@ -261,7 +261,7 @@ RendererCompositorRD::RendererCompositorRD() {
shader_cache_dir = String(); //disable only if not editor
}
- if (shader_cache_dir != String()) {
+ if (!shader_cache_dir.is_empty()) {
bool compress = GLOBAL_GET("rendering/shader_compiler/shader_cache/compress");
bool use_zstd = GLOBAL_GET("rendering/shader_compiler/shader_cache/use_zstd_compression");
bool strip_debug = GLOBAL_GET("rendering/shader_compiler/shader_cache/strip_debug");
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index b6b5c90b39..d1085245c0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -1305,7 +1305,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
if (gi->sdfgi_debug_probe_dir != Vector3()) {
- print_line("CLICK DEBUG ME?");
uint32_t cascade = 0;
Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0);
Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);
@@ -1333,11 +1332,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
}
}
- if (gi->sdfgi_debug_probe_enabled) {
- print_line("found: " + gi->sdfgi_debug_probe_index);
- } else {
- print_line("no found");
- }
gi->sdfgi_debug_probe_dir = Vector3();
}
@@ -1864,7 +1858,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
Ref<Image> img;
img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i, 128 * 128 * (i + 1) - 1);
+ Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1));
img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);
img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");
}
@@ -1877,7 +1871,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
Ref<Image> img;
img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2 - 1);
+ Vector<uint8_t> subarr = data.slice(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2);
img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);
img->convert(Image::FORMAT_RGBA8);
img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index ae8d91a73b..7c35b01b50 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -3581,7 +3581,7 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
@@ -4417,9 +4417,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1;
uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1;
- params.cluster_type_size = cluster_screen_width * cluster_screen_height * (32 + 32);
- params.cluster_width = cluster_screen_width;
params.max_cluster_element_count_div_32 = max_cluster_elements / 32;
+ params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32);
+ params.cluster_width = cluster_screen_width;
params.screen_size[0] = rb->width;
params.screen_size[1] = rb->height;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index a9c39fb937..f595edb225 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -46,7 +46,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 04acc871b4..79728169ae 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -1089,7 +1089,7 @@ Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const {
const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i];
ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>());
ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>());
- Vector<uint8_t> sub_region = all_data.subarray(bs.offset, bs.offset + bs.buffer_size - 1);
+ Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size);
Ref<Image> img;
img.instantiate();
@@ -2652,7 +2652,17 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName
//regular uniform
uint32_t offset = p_uniform_offsets[E.value.order];
#ifdef DEBUG_ENABLED
- uint32_t size = ShaderLanguage::get_type_size(E.value.type);
+ uint32_t size = 0U;
+ // The following code enforces a 16-byte alignment of uniform arrays.
+ if (E.value.array_size > 0) {
+ size = ShaderLanguage::get_type_size(E.value.type) * E.value.array_size;
+ int m = (16 * E.value.array_size);
+ if ((size % m) != 0U) {
+ size += m - (size % m);
+ }
+ } else {
+ size = ShaderLanguage::get_type_size(E.value.type);
+ }
ERR_CONTINUE(offset + size > p_buffer_size);
#endif
uint8_t *data = &p_buffer[offset];
@@ -2851,7 +2861,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
}
}
#ifdef TOOLS_ENABLED
- if (roughness_detect_texture && normal_detect_texture && normal_detect_texture->path != String()) {
+ if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) {
roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
}
#endif
@@ -2891,7 +2901,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
}
#ifdef TOOLS_ENABLED
- if (roughness_detect_texture && normal_detect_texture && normal_detect_texture->path != String()) {
+ if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) {
roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
}
#endif
@@ -5810,7 +5820,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_collision = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
@@ -9255,7 +9265,6 @@ void RendererStorageRD::_update_global_variables() {
ERR_CONTINUE(!material); //wtf
_material_queue_update(material, false, true);
- print_line("update material texture?");
}
global_variables.must_update_texture_materials = false;
@@ -10023,7 +10032,7 @@ RendererStorageRD::RendererStorageRD() {
actions.renames["RESTART"] = "restart";
actions.renames["CUSTOM"] = "PARTICLE.custom";
actions.renames["TRANSFORM"] = "PARTICLE.xform";
- actions.renames["TIME"] = "FRAME.time";
+ actions.renames["TIME"] = "frame_history.data[0].time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index f7c8ca1487..794c999d1d 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -661,6 +661,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
} else {
+ // The following code enforces a 16-byte alignment of uniform arrays.
if (uniform.array_size > 0) {
int size = _get_datatype_size(uniform.type) * uniform.array_size;
int m = (16 * uniform.array_size);
@@ -668,10 +669,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
size += m - (size % m);
}
uniform_sizes.write[uniform.order] = size;
+ uniform_alignments.write[uniform.order] = 16;
} else {
uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type);
+ uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
}
- uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
}
}
@@ -1316,6 +1318,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
default: {
if (p_use_scope) {
@@ -1408,7 +1413,13 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &
}
Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
- Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_variable_type);
+ SL::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_variable_type;
+
+ Error err = parser.compile(p_code, info);
if (err != OK) {
Vector<String> shader = p_code.split("\n");
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 2568090918..438e78ba8c 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -79,7 +79,7 @@ void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
}
if (push_chunk) {
- if (text != String()) {
+ if (!text.is_empty()) {
StageTemplate::Chunk text_chunk;
text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
text_chunk.text = text.utf8();
@@ -90,7 +90,7 @@ void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
}
}
- if (text != String()) {
+ if (!text.is_empty()) {
StageTemplate::Chunk text_chunk;
text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
text_chunk.text = text.utf8();
@@ -638,7 +638,7 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String
variants_enabled.push_back(true);
}
- if (shader_cache_dir != String()) {
+ if (!shader_cache_dir.is_empty()) {
StringBuilder hash_build;
hash_build.append("[base_hash]");
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index 8e33610ae2..e4628b2d5a 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -1757,7 +1757,11 @@ void main() {
}
}
+#ifdef MOLTENVK_USED
+ imageStore(geom_facing_grid, grid_pos, uvec4(imageLoad(geom_facing_grid, grid_pos).r | facing_bits)); //store facing bits
+#else
imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
+#endif
if (length(emission) > 0.001) {
float lumas[6];
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
index 747f88960c..999e8d0844 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
@@ -581,16 +581,29 @@ void main() {
if (spot_lights.data[light_index].shadow_enabled) {
//has shadow
- vec4 v = vec4(view_pos, 1.0);
+ vec4 uv_rect = spot_lights.data[light_index].atlas_rect;
+ vec2 flip_offset = spot_lights.data[light_index].direction.xy;
- vec4 splane = (spot_lights.data[light_index].shadow_matrix * v);
- splane /= splane.w;
+ vec3 local_vert = (spot_lights.data[light_index].shadow_matrix * vec4(view_pos, 1.0)).xyz;
- float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
+ float shadow_len = length(local_vert); //need to remember shadow len from here
+ vec3 shadow_sample = normalize(local_vert);
- shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
- }
+ if (shadow_sample.z >= 0.0) {
+ uv_rect.xy += flip_offset;
+ }
+
+ shadow_sample.z = 1.0 + abs(shadow_sample.z);
+ vec3 pos = vec3(shadow_sample.xy / shadow_sample.z, shadow_len - spot_lights.data[light_index].shadow_bias);
+ pos.z *= spot_lights.data[light_index].inv_radius;
+
+ pos.xy = pos.xy * 0.5 + 0.5;
+ pos.xy = uv_rect.xy + pos.xy * uv_rect.zw;
+ float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r;
+
+ shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
+ }
total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g);
}
}
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 8a14834569..eddf5bf53d 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -85,14 +85,14 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
if ((scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) && (scaling_3d_scale > 1.0)) {
// FSR is not design for downsampling.
// Throw a warning and fallback to VIEWPORT_SCALING_3D_MODE_BILINEAR
- print_error("FSR does not support supersampling. Falling back to bilinear mode.");
+ WARN_PRINT_ONCE("FSR 3D resolution scaling does not support supersampling. Falling back to bilinear scaling.");
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
}
if ((scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) && !p_viewport->fsr_enabled) {
// FSR is not actually available.
// Throw a warning and fallback to disable scaling
- print_error("FSR is not available. Disabled FSR scaling 3D. Try bilinear mode.");
+ WARN_PRINT_ONCE("FSR 3D resolution scaling is not available. Disabling 3D resolution scaling.");
scaling_enabled = false;
}
@@ -123,7 +123,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
break;
default:
// This is an unknown mode.
- print_error(vformat("Unknown scaling mode: %d, disabling scaling 3D", scaling_3d_mode));
+ WARN_PRINT_ONCE(vformat("Unknown scaling mode: %d. Disabling 3D resolution scaling.", scaling_3d_mode));
width = p_viewport->size.width;
height = p_viewport->size.height;
render_width = width;
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index dcbc5f5c8e..38f57b4624 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -185,9 +185,13 @@ Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<
String error;
ShaderStage stage = ShaderStage(i);
- Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
- bytecode->set_stage_bytecode(stage, spirv);
- bytecode->set_stage_compile_error(stage, error);
+ String source = p_source->get_stage_source(stage);
+
+ if (!source.is_empty()) {
+ Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, source, p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
}
return bytecode;
}
@@ -201,7 +205,7 @@ Vector<uint8_t> RenderingDevice::_shader_compile_binary_from_spirv(const Ref<RDS
ShaderStageSPIRVData sd;
sd.shader_stage = stage;
String error = p_spirv->get_stage_compile_error(stage);
- ERR_FAIL_COND_V_MSG(error != String(), Vector<uint8_t>(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
+ ERR_FAIL_COND_V_MSG(!error.is_empty(), Vector<uint8_t>(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_spirv->get_stage_bytecode(stage);
if (sd.spir_v.is_empty()) {
continue;
@@ -221,7 +225,7 @@ RID RenderingDevice::_shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv
ShaderStageSPIRVData sd;
sd.shader_stage = stage;
String error = p_spirv->get_stage_compile_error(stage);
- ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
+ ERR_FAIL_COND_V_MSG(!error.is_empty(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_spirv->get_stage_bytecode(stage);
if (sd.spir_v.is_empty()) {
continue;
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
index a21f28989b..3d09d83601 100644
--- a/servers/rendering/rendering_device_binds.cpp
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -80,7 +80,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
}
- if (base_error != String()) {
+ if (!base_error.is_empty()) {
break;
}
}
@@ -89,7 +89,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
}
- if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ if (stage == RD::SHADER_STAGE_MAX && !line.strip_edges().is_empty()) {
line = line.strip_edges();
if (line.begins_with("//") || line.begins_with("/*")) {
continue; //assuming comment (single line)
@@ -98,7 +98,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
if (reading_versions) {
String l = line.strip_edges();
- if (l != "") {
+ if (!l.is_empty()) {
if (l.find("=") == -1) {
base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break;
@@ -124,7 +124,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
version_texts[version] = define + "\n" + p_defines;
}
} else {
- if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ if (stage == RD::SHADER_STAGE_MAX && !line.strip_edges().is_empty()) {
base_error = "Text was found that does not belong to a valid section: " + line;
break;
}
@@ -140,7 +140,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
include = include.substr(1, include.length() - 2).strip_edges();
String include_text = p_include_func(include, p_include_func_userdata);
- if (include_text != String()) {
+ if (!include_text.is_empty()) {
stage_code[stage] += "\n" + include_text + "\n";
} else {
base_error = "#include failed for file '" + include + "'";
@@ -158,7 +158,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
Ref<RDShaderFile> shader_file;
shader_file.instantiate();
- if (base_error == "") {
+ if (base_error.is_empty()) {
if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) {
ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
}
@@ -177,14 +177,14 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
String code = stage_code[i];
- if (code == String()) {
+ if (code.is_empty()) {
continue;
}
code = code.replace("VERSION_DEFINES", E.value);
String error;
Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_spirv_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false);
bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv);
- if (error != "") {
+ if (!error.is_empty()) {
error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n";
Vector<String> sclines = code.split("\n");
for (int j = 0; j < sclines.size(); j++) {
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 2cf7821668..651c9b0090 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -368,13 +368,13 @@ public:
}
void print_errors(const String &p_file) {
- if (base_error != "") {
+ if (!base_error.is_empty()) {
ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error);
} else {
for (KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) {
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
String error = E.value->get_stage_compile_error(RD::ShaderStage(i));
- if (error != String()) {
+ if (!error.is_empty()) {
static const char *stage_str[RD::SHADER_STAGE_MAX] = {
"vertex",
"fragment",
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index c7a7ed154e..ca911d995a 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -88,7 +88,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"--",
"()",
"construct",
- "index" };
+ "index",
+ "empty" };
return op_names[p_op];
}
@@ -474,6 +475,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
case ':':
return _make_token(TK_COLON);
case '^':
+ if (GETCHAR(0) == '=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_XOR);
+ }
return _make_token(TK_OP_BIT_XOR);
case '~':
return _make_token(TK_OP_BIT_INVERT);
@@ -909,8 +914,10 @@ void ShaderLanguage::clear() {
completion_type = COMPLETION_NONE;
completion_block = nullptr;
completion_function = StringName();
- completion_class = SubClassTag::TAG_GLOBAL;
+ completion_class = TAG_GLOBAL;
completion_struct = StringName();
+ completion_base = TYPE_VOID;
+ completion_base_array = false;
unknown_varying_usages.clear();
@@ -2994,7 +3001,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
FunctionNode *pfunc = shader->functions[i].function;
- if (arg_list == "") {
+ if (arg_list.is_empty()) {
for (int j = 0; j < pfunc->arguments.size(); j++) {
if (j > 0) {
arg_list += ", ";
@@ -3230,6 +3237,10 @@ bool ShaderLanguage::is_token_operator_assign(TokenType p_type) {
p_type == TK_OP_ASSIGN_BIT_XOR);
}
+bool ShaderLanguage::is_token_hint(TokenType p_type) {
+ return int(p_type) > int(TK_RENDER_MODE) && int(p_type) < int(TK_SHADER_TYPE);
+}
+
bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) {
if (p_constant->datatype == p_to_type) {
if (p_value) {
@@ -4293,7 +4304,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, cons
return n;
}
-Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
+Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) {
if (r_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
@@ -4305,7 +4316,7 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
- Node *n = _parse_array_size(nullptr, FunctionInfo(), array_size);
+ Node *n = _parse_array_size(nullptr, p_function_info, array_size);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5208,9 +5219,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
} else {
- _set_error("Expected expression, found: " + get_token_text(tk));
- return nullptr;
- //nothing
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected expression, found: " + get_token_text(tk));
+ return nullptr;
+ } else {
+#if DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
+ }
+#endif // DEBUG_ENABLED
+ _set_tkpos(prepos);
+
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op = OP_EMPTY;
+ expr = func;
+ }
}
ERR_FAIL_COND_V(!expr, nullptr);
@@ -6386,7 +6409,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ArrayDeclarationNode::Declaration adecl;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '[' after type.");
+ _set_error("Expected identifier or '[' after datatype.");
return ERR_PARSE_ERROR;
}
@@ -7219,7 +7242,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_SEMICOLON) {
//all is good
if (b->parent_function->return_type != TYPE_VOID) {
- _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
return ERR_PARSE_ERROR;
}
} else {
@@ -7231,7 +7254,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) {
- _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
return ERR_PARSE_ERROR;
}
@@ -7353,7 +7376,7 @@ String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types)
// Return a list of shader types as an human-readable string
String valid_types;
for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
- if (valid_types != String()) {
+ if (!valid_types.is_empty()) {
valid_types += ", ";
}
@@ -7441,10 +7464,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int texture_uniforms = 0;
int texture_binding = 0;
+ int uniforms = 0;
int instance_index = 0;
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
stages = &p_functions;
+ const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
while (tk.type != TK_EOF) {
switch (tk.type) {
@@ -7488,7 +7513,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
- if (shader->structs.has(st.name)) {
+ if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
_set_error("Redefinition of '" + String(st.name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7560,7 +7585,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int array_size = 0;
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7587,7 +7612,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(member->array_size);
+ Error error = _parse_global_array_size(member->array_size, constants);
if (error != OK) {
return error;
}
@@ -7714,7 +7739,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7729,7 +7754,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7762,7 +7787,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(uniform2.array_size);
+ Error error = _parse_global_array_size(uniform2.array_size, constants);
if (error != OK) {
return error;
}
@@ -7791,6 +7816,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
uniform2.texture_order = -1;
+ if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
+ uniform2.order = uniforms++;
+ }
}
if (uniform2.array_size > 0) {
@@ -7807,9 +7835,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int custom_instance_index = -1;
if (tk.type == TK_COLON) {
+ completion_type = COMPLETION_HINT;
+ completion_base = type;
+ completion_base_array = uniform2.array_size > 0;
+
//hint
do {
tk = _get_token();
+ completion_line = tk.line;
+
+ if (!is_token_hint(tk.type)) {
+ _set_error("Expected valid type hint after ':'.");
+ return ERR_PARSE_ERROR;
+ }
if (uniform2.array_size > 0) {
if (tk.type != TK_HINT_COLOR) {
@@ -7979,8 +8017,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.repeat = REPEAT_DISABLE;
} else if (tk.type == TK_REPEAT_ENABLE) {
uniform2.repeat = REPEAT_ENABLE;
- } else {
- _set_error("Expected valid type hint after ':'.");
}
if (uniform2.hint != ShaderNode::Uniform::HINT_RANGE && uniform2.hint != ShaderNode::Uniform::HINT_NONE && uniform2.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) {
@@ -8013,7 +8049,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8047,6 +8083,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_set_error("Expected ';'");
return ERR_PARSE_ERROR;
}
+
+ completion_type = COMPLETION_NONE;
} else { // varying
ShaderNode::Varying varying;
varying.type = type;
@@ -8109,7 +8147,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
DataPrecision precision = PRECISION_DEFAULT;
DataType type;
StringName name;
- int return_array_size = 0;
+ int array_size = 0;
if (tk.type == TK_CONST) {
is_constant = true;
@@ -8148,13 +8186,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
tk = _get_token();
+ bool unknown_size = false;
+
if (tk.type == TK_BRACKET_OPEN) {
+ if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
bool error = false;
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- return_array_size = (int)tk.constant;
- if (return_array_size > 0) {
+ array_size = (int)tk.constant;
+ if (array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8163,11 +8207,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
error = true;
}
+ } else if (tk.type == TK_BRACKET_CLOSE) {
+ unknown_size = true;
} else {
error = true;
}
if (error) {
- _set_error("Expected integer constant > 0");
+ _set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
@@ -8179,16 +8225,15 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
if (name == StringName()) {
- _set_error("Expected function name after datatype");
- return ERR_PARSE_ERROR;
- }
-
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ if (is_constant) {
+ _set_error("Expected identifier or '[' after datatype.");
+ } else {
+ _set_error("Expected function name after datatype.");
+ }
return ERR_PARSE_ERROR;
}
- if (has_builtin(p_functions, name)) {
+ if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8201,7 +8246,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
//variable
-
+ bool first = true;
while (true) {
ShaderNode::Constant constant;
constant.name = name;
@@ -8209,16 +8254,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
- constant.array_size = 0;
-
- bool unknown_size = false;
+ constant.array_size = (first ? array_size : 0);
+ first = false;
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are supported only on high-end platform!");
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+ if (constant.array_size > 0 || unknown_size) {
+ _set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
-
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
@@ -8296,7 +8343,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(prev_pos);
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -8377,7 +8424,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -8432,7 +8479,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8448,7 +8495,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
- if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) {
+ if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
return ERR_PARSE_ERROR;
}
}
@@ -8479,7 +8526,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8513,6 +8560,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
+ if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ builtins.built_ins.insert(E.key, E.value);
+ }
+ }
+
ShaderNode::Function function;
function.callable = !p_functions.has(name);
@@ -8528,7 +8581,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
func_node->return_type = type;
func_node->return_struct_name = struct_name;
func_node->return_precision = precision;
- func_node->return_array_size = return_array_size;
+ func_node->return_array_size = array_size;
if (p_functions.has(name)) {
func_node->can_discard = p_functions[name].can_discard;
@@ -8582,7 +8635,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
StringName param_struct_name;
DataPrecision pprecision = PRECISION_DEFAULT;
bool use_precision = false;
- int array_size = 0;
+ int arg_array_size = 0;
if (is_token_precision(tk.type)) {
pprecision = get_token_precision(tk.type);
@@ -8633,9 +8686,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8687,7 +8740,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (array_size > 0) {
+ if (arg_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
@@ -8695,9 +8748,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8717,7 +8770,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- arg.array_size = array_size;
+ arg.array_size = arg_array_size;
func_node->arguments.push_back(arg);
if (tk.type == TK_COMMA) {
@@ -8769,20 +8822,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- int uniforms = 0;
-
- // Need to push arrays to first place in a uniform buffer in order to correct work.
- for (Map<StringName, ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order == -1 && E->get().scope != ShaderNode::Uniform::SCOPE_INSTANCE && E->get().array_size > 0) {
- E->get().order = uniforms++;
- }
- }
- for (Map<StringName, ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order == -1 && E->get().scope != ShaderNode::Uniform::SCOPE_INSTANCE && E->get().array_size == 0) {
- E->get().order = uniforms++;
- }
- }
-
int error_line;
String error_message;
if (!_check_varying_usages(&error_line, &error_message)) {
@@ -8910,7 +8949,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
break;
} else if (p_code[i] <= 32) {
- if (cur_identifier != String()) {
+ if (!cur_identifier.is_empty()) {
if (!reading_type) {
if (cur_identifier != "shader_type") {
return String();
@@ -8970,17 +9009,17 @@ uint32_t ShaderLanguage::get_warning_flags() const {
}
#endif // DEBUG_ENABLED
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
+Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_info) {
clear();
code = p_code;
- global_var_get_type_func = p_global_variable_type_func;
- varying_function_names = p_varying_function_names;
+ global_var_get_type_func = p_info.global_variable_type_func;
+ varying_function_names = p_info.varying_function_names;
nodes = nullptr;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
+ Error err = _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
#ifdef DEBUG_ENABLED
if (check_warnings) {
@@ -8994,17 +9033,17 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
clear();
code = p_code;
- varying_function_names = p_varying_function_names;
+ varying_function_names = p_info.varying_function_names;
nodes = nullptr;
- global_var_get_type_func = p_global_variable_type_func;
+ global_var_get_type_func = p_info.global_variable_type_func;
shader = alloc_node<ShaderNode>();
- _parse_shader(p_functions, p_render_modes, p_shader_types);
+ _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
switch (completion_type) {
case COMPLETION_NONE: {
@@ -9012,8 +9051,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_RENDER_MODE: {
- for (int i = 0; i < p_render_modes.size(); i++) {
- ScriptCodeCompletionOption option(p_render_modes[i], ScriptCodeCompletionOption::KIND_ENUM);
+ for (int i = 0; i < p_info.render_modes.size(); i++) {
+ ScriptCodeCompletionOption option(p_info.render_modes[i], ScriptCodeCompletionOption::KIND_ENUM);
r_options->push_back(option);
}
@@ -9031,7 +9070,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_MAIN_FUNCTION: {
- for (const KeyValue<StringName, FunctionInfo> &E : p_functions) {
+ for (const KeyValue<StringName, FunctionInfo> &E : p_info.functions) {
ScriptCodeCompletionOption option(E.key, ScriptCodeCompletionOption::KIND_FUNCTION);
r_options->push_back(option);
}
@@ -9067,8 +9106,18 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (comp_ident) {
- if (p_functions.has("global")) {
- for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) {
+ if (p_info.functions.has("global")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) {
+ ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
+ if (E.value.constant) {
+ kind = ScriptCodeCompletionOption::KIND_CONSTANT;
+ }
+ matches.insert(E.key, kind);
+ }
+ }
+
+ if (p_info.functions.has("constants")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
if (E.value.constant) {
kind = ScriptCodeCompletionOption::KIND_CONSTANT;
@@ -9077,8 +9126,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
}
- if (skip_function != StringName() && p_functions.has(skip_function)) {
- for (const KeyValue<StringName, BuiltInInfo> &E : p_functions[skip_function].built_ins) {
+ if (skip_function != StringName() && p_info.functions.has(skip_function)) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
if (E.value.constant) {
kind = ScriptCodeCompletionOption::KIND_CONSTANT;
@@ -9393,6 +9442,57 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
} break;
+ case COMPLETION_HINT: {
+ if (completion_base == DataType::TYPE_VEC4) {
+ ScriptCodeCompletionOption option("hint_color", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ r_options->push_back(option);
+ } else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
+ ScriptCodeCompletionOption option("hint_range", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+
+ if (completion_base == DataType::TYPE_INT) {
+ option.insert_text = "hint_range(0, 100, 1)";
+ } else {
+ option.insert_text = "hint_range(0.0, 1.0, 0.1)";
+ }
+
+ r_options->push_back(option);
+ } else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT)) && !completion_base_array) {
+ static Vector<String> options;
+
+ if (options.is_empty()) {
+ options.push_back("filter_linear");
+ options.push_back("filter_linear_mipmap");
+ options.push_back("filter_linear_mipmap_aniso");
+ options.push_back("filter_nearest");
+ options.push_back("filter_nearest_mipmap");
+ options.push_back("filter_nearest_mipmap_aniso");
+ options.push_back("hint_albedo");
+ options.push_back("hint_aniso");
+ options.push_back("hint_black");
+ options.push_back("hint_black_albedo");
+ options.push_back("hint_normal");
+ options.push_back("hint_roughness_a");
+ options.push_back("hint_roughness_b");
+ options.push_back("hint_roughness_g");
+ options.push_back("hint_roughness_gray");
+ options.push_back("hint_roughness_normal");
+ options.push_back("hint_roughness_r");
+ options.push_back("hint_white");
+ options.push_back("repeat_enable");
+ options.push_back("repeat_disable");
+ }
+
+ for (int i = 0; i < options.size(); i++) {
+ ScriptCodeCompletionOption option(options[i], ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ r_options->push_back(option);
+ }
+ }
+ if (!completion_base_array) {
+ ScriptCodeCompletionOption option("instance_index", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ option.insert_text = "instance_index(0)";
+ r_options->push_back(option);
+ }
+ } break;
}
return ERR_PARSE_ERROR;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index c82f71d10d..9c456d56ba 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -287,6 +287,7 @@ public:
OP_CONSTRUCT,
OP_STRUCT,
OP_INDEX,
+ OP_EMPTY,
OP_MAX
};
@@ -747,6 +748,7 @@ public:
COMPLETION_CALL_ARGUMENTS,
COMPLETION_INDEX,
COMPLETION_STRUCT,
+ COMPLETION_HINT,
};
struct Token {
@@ -771,6 +773,7 @@ public:
static bool is_token_nonvoid_datatype(TokenType p_type);
static bool is_token_operator(TokenType p_type);
static bool is_token_operator_assign(TokenType p_type);
+ static bool is_token_hint(TokenType p_type);
static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = nullptr);
static DataType get_scalar_type(DataType p_type);
@@ -965,10 +968,12 @@ private:
int completion_line;
BlockNode *completion_block;
DataType completion_base;
+ bool completion_base_array;
SubClassTag completion_class;
StringName completion_function;
StringName completion_struct;
int completion_argument;
+
const Map<StringName, FunctionInfo> *stages = nullptr;
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
@@ -989,7 +994,7 @@ private:
bool _check_node_constness(const Node *p_node) const;
Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
- Error _parse_global_array_size(int &r_array_size);
+ Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
@@ -1023,8 +1028,17 @@ public:
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func);
- Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
+
+ struct ShaderCompileInfo {
+ Map<StringName, FunctionInfo> functions;
+ Vector<StringName> render_modes;
+ VaryingFunctionNames varying_function_names = VaryingFunctionNames();
+ Set<String> shader_types;
+ GlobalVariableGetTypeFunc global_variable_type_func = nullptr;
+ };
+
+ Error compile(const String &p_code, const ShaderCompileInfo &p_info);
+ Error complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index eb5c9e66e8..359196e096 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -59,9 +59,9 @@ ShaderTypes::ShaderTypes() {
/*************** SPATIAL ***********************/
shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -241,9 +241,9 @@ ShaderTypes::ShaderTypes() {
/************ CANVAS ITEM **************************/
shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
@@ -334,9 +334,9 @@ ShaderTypes::ShaderTypes() {
/************ PARTICLES **************************/
shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
@@ -367,7 +367,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT);
- shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT);
@@ -400,9 +400,9 @@ ShaderTypes::ShaderTypes() {
/************ SKY **************************/
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
@@ -446,9 +446,9 @@ ShaderTypes::ShaderTypes() {
/************ FOG **************************/
shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["WORLD_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["OBJECT_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index 0b8476478c..bffae484a8 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -61,6 +61,8 @@ String ShaderWarning::get_message() const {
return vformat("The varying '%s' is declared but never used.", subject);
case UNUSED_LOCAL_VARIABLE:
return vformat("The local variable '%s' is declared but never used.", subject);
+ case FORMATTING_ERROR:
+ return subject;
default:
break;
}
@@ -82,6 +84,7 @@ String ShaderWarning::get_name_from_code(Code p_code) {
"UNUSED_UNIFORM",
"UNUSED_VARYING",
"UNUSED_LOCAL_VARIABLE",
+ "FORMATTING_ERROR",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
@@ -110,6 +113,7 @@ static void init_code_to_flags_map() {
code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
+ code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
}
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h
index db872d8fb1..18915fffd8 100644
--- a/servers/rendering/shader_warnings.h
+++ b/servers/rendering/shader_warnings.h
@@ -47,6 +47,7 @@ public:
UNUSED_UNIFORM,
UNUSED_VARYING,
UNUSED_LOCAL_VARIABLE,
+ FORMATTING_ERROR,
WARNING_MAX,
};
@@ -59,6 +60,7 @@ public:
UNUSED_UNIFORM_FLAG = 16U,
UNUSED_VARYING_FLAG = 32U,
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
+ FORMATTING_ERROR_FLAG = 128U,
};
private:
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 7a958546b6..23d3bf030f 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -199,11 +199,11 @@ RID RenderingServer::_make_test_cube() {
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
}
- //tri 1
+ // Tri 1
ADD_VTX(0);
ADD_VTX(1);
ADD_VTX(2);
- //tri 2
+ // Tri 2
ADD_VTX(2);
ADD_VTX(3);
ADD_VTX(0);
@@ -317,9 +317,6 @@ RID RenderingServer::get_white_texture() {
return white_texture;
}
-#define SMALL_VEC2 Vector2(0.00001, 0.00001)
-#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
-
Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
uint8_t *vw = r_vertex_array.ptrw();
uint8_t *aw = r_attrib_array.ptrw();
@@ -333,7 +330,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
int max_bone = 0;
for (int ai = 0; ai < RS::ARRAY_MAX; ai++) {
- if (!(p_format & (1 << ai))) { // no array
+ if (!(p_format & (1 << ai))) { // No array
continue;
}
@@ -345,7 +342,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
Rect2 aabb;
{
@@ -355,7 +352,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 2);
if (i == 0) {
- aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size
+ aabb = Rect2(src[i], SMALL_VEC2); // Must have a bit of size.
} else {
aabb.expand_to(src[i]);
}
@@ -370,7 +367,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector3 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
AABB aabb;
{
@@ -505,7 +502,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF: {
- //size 4
+ // Size 4
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -520,7 +517,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 8
+ // Size 8
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -537,7 +534,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RG_FLOAT:
case ARRAY_CUSTOM_RGB_FLOAT:
case ARRAY_CUSTOM_RGBA_FLOAT: {
- //RF
+ // RF
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<float> array = p_arrays[ai];
@@ -646,7 +643,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
if (p_format & RS::ARRAY_FORMAT_BONES) {
- //create AABBs for each detected bone
+ // Create AABBs for each detected bone.
int total_bones = max_bone + 1;
bool first = r_bone_aabb.size() == 0;
@@ -657,7 +654,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
if (first) {
for (int i = 0; i < total_bones; i++) {
- r_bone_aabb.write[i].size = Vector3(-1, -1, -1); //negative means unused
+ r_bone_aabb.write[i].size = Vector3(-1, -1, -1); // Negative means unused.
}
}
@@ -686,7 +683,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
if (bptr[idx].size.x < 0) {
- //first
+ // First
bptr[idx] = AABB(v, SMALL_VEC3);
any_valid = true;
} else {
@@ -749,7 +746,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
uint32_t *size_accum;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
- r_offsets[i] = 0; //reset
+ r_offsets[i] = 0; // Reset
if (i == RS::ARRAY_VERTEX) {
size_accum = &r_vertex_element_size;
@@ -759,7 +756,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
size_accum = &r_skin_element_size;
}
- if (!(p_format & (1 << i))) { // no array
+ if (!(p_format & (1 << i))) { // No array
continue;
}
@@ -873,7 +870,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
uint32_t format = 0;
- // validation
+ // Validation
int index_array_len = 0;
int array_len = 0;
@@ -921,10 +918,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
- ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // mandatory
+ ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // Mandatory
if (p_blend_shapes.size()) {
- //validate format for morphs
+ // Validate format for morphs.
for (int i = 0; i < p_blend_shapes.size(); i++) {
uint32_t bsformat = 0;
Array arr = p_blend_shapes[i];
@@ -939,7 +936,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
for (uint32_t i = 0; i < RS::ARRAY_CUSTOM_COUNT; ++i) {
- // include custom array format type.
+ // Include custom array format type.
if (format & (1 << (ARRAY_CUSTOM0 + i))) {
format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
}
@@ -954,7 +951,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
mesh_surface_make_offsets_from_format(format, array_len, index_array_len, offsets, vertex_element_size, attrib_element_size, skin_element_size);
uint32_t mask = (1 << ARRAY_MAX) - 1;
- format |= (~mask) & p_compress_format; //make the full format
+ format |= (~mask) & p_compress_format; // Make the full format.
int vertex_array_size = vertex_element_size * array_len;
int attrib_array_size = attrib_element_size * array_len;
@@ -1010,13 +1007,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
Vector<int> indices = p_lods[E];
ERR_CONTINUE(indices.size() == 0);
uint32_t index_count = indices.size();
- ERR_CONTINUE(index_count >= (uint32_t)index_array_len); //should be smaller..
+ ERR_CONTINUE(index_count >= (uint32_t)index_array_len); // Should be smaller..
const int *r = indices.ptr();
Vector<uint8_t> data;
if (array_len <= 65536) {
- //16 bits indices
+ // 16 bits indices
data.resize(indices.size() * 2);
uint8_t *w = data.ptrw();
uint16_t *index_ptr = (uint16_t *)w;
@@ -1024,7 +1021,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
index_ptr[i] = r[i];
}
} else {
- //32 bits indices
+ // 32 bits indices
data.resize(indices.size() * 4);
uint8_t *w = data.ptrw();
uint32_t *index_ptr = (uint32_t *)w;
@@ -1204,7 +1201,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF:
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 4
+ // Size 4
int s = type == ARRAY_CUSTOM_RGBA_HALF ? 8 : 4;
Vector<uint8_t> arr;
arr.resize(p_vertex_len * s);
@@ -1376,7 +1373,7 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur
Array blend_shape_array;
blend_shape_array.resize(mesh_get_blend_shape_count(p_mesh));
for (uint32_t i = 0; i < blend_shape_count; i++) {
- Vector<uint8_t> bs_data = blend_shape_data.subarray(i * divisor, (i + 1) * divisor - 1);
+ Vector<uint8_t> bs_data = blend_shape_data.slice(i * divisor, (i + 1) * divisor);
Vector<uint8_t> unused;
blend_shape_array.set(i, _get_array_from_surface(bs_format, bs_data, unused, unused, sd.vertex_count, unused, 0));
}
@@ -1472,12 +1469,12 @@ ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_dataty
case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE:
return ShaderLanguage::TYPE_SAMPLERCUBE;
default:
- return ShaderLanguage::TYPE_MAX; //invalid or not found
+ return ShaderLanguage::TYPE_MAX; // Invalid or not found.
}
}
RenderingDevice *RenderingServer::get_rendering_device() const {
- // return the rendering device we're using globally
+ // Return the rendering device we're using globally.
return RenderingDevice::get_singleton();
}
@@ -2221,8 +2218,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_DISABLED);
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); //then goes to disabled); must be manually updated
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // default
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); // Then goes to disabled); must be manually updated.
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // Default
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ALWAYS);
@@ -2553,7 +2550,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_set_modulate", "item", "color"), &RenderingServer::canvas_item_set_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_self_modulate", "item", "color"), &RenderingServer::canvas_item_set_self_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_draw_behind_parent", "item", "enabled"), &RenderingServer::canvas_item_set_draw_behind_parent);
- //primitives
+
+ /* Primitives */
ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width"), &RenderingServer::canvas_item_add_line, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false));
@@ -2704,7 +2702,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
/* Free */
- ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // shouldn't conflict with Object::free()
+ ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // Shouldn't conflict with Object::free().
/* Misc */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 85f92bc003..230132651f 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -55,6 +55,9 @@ class RenderingServer : public Object {
RendererThreadPool *thread_pool = nullptr;
+ const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON);
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
RID _make_test_cube();
void _free_internal_rids();
@@ -108,7 +111,7 @@ public:
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
- //these two APIs can be used together or in combination with the others.
+ // These two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create() = 0;
virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
@@ -210,18 +213,18 @@ public:
enum ArrayType {
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
- ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored
- ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
+ ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
+ ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TEX_UV2 = 5, // RG32F
- ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
+ ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
ARRAY_CUSTOM1 = 7,
ARRAY_CUSTOM2 = 8,
ARRAY_CUSTOM3 = 9,
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
- ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
+ ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF.
ARRAY_MAX = 13
};
@@ -243,7 +246,7 @@ public:
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
- ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory
+ ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // Mandatory
ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL,
ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT,
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
@@ -287,9 +290,9 @@ public:
PrimitiveType primitive = PRIMITIVE_MAX;
uint32_t format = 0;
- Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
- Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
- Vector<uint8_t> skin_data; // bone index, bone weight
+ Vector<uint8_t> vertex_data; // Vertex, Normal, Tangent (change with skinning, blendshape).
+ Vector<uint8_t> attribute_data; // Color, UV, UV2, Custom0-3.
+ Vector<uint8_t> skin_data; // Bone index, Bone weight.
uint32_t vertex_count = 0;
Vector<uint8_t> index_data;
uint32_t index_count = 0;
@@ -452,7 +455,7 @@ public:
virtual void light_set_bake_mode(RID p_light, LightBakeMode p_bake_mode) = 0;
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
- // omni light
+ // Omni light
enum LightOmniShadowMode {
LIGHT_OMNI_SHADOW_DUAL_PARABOLOID,
LIGHT_OMNI_SHADOW_CUBE,
@@ -460,7 +463,7 @@ public:
virtual void light_omni_set_shadow_mode(RID p_light, LightOmniShadowMode p_mode) = 0;
- // directional light
+ // Directional light
enum LightDirectionalShadowMode {
LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS,
@@ -671,7 +674,7 @@ public:
virtual AABB particles_get_current_aabb(RID p_particles) = 0;
- virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+ virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; // This is only used for 2D, in 3D it's automatic.
/* PARTICLES COLLISION API */
@@ -689,16 +692,16 @@ public:
virtual void particles_collision_set_collision_type(RID p_particles_collision, ParticlesCollisionType p_type) = 0;
virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
- virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; //for spheres
- virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres
+ virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; // For spheres.
+ virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; // For non-spheres.
virtual void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) = 0;
virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) = 0;
virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) = 0;
- virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic
+ virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; // For SDF and vector field, heightfield is dynamic.
- virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field
+ virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; // For SDF and vector field.
- enum ParticlesCollisionHeightfieldResolution { //longest axis resolution
+ enum ParticlesCollisionHeightfieldResolution { // Longest axis resolution.
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_256,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_512,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024,
@@ -708,7 +711,7 @@ public:
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX,
};
- virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
+ virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; // For SDF and vector field.
/* FOG VOLUME API */
@@ -750,7 +753,7 @@ public:
/* VIEWPORT API */
enum CanvasItemTextureFilter {
- CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
@@ -761,7 +764,7 @@ public:
};
enum CanvasItemTextureRepeat {
- CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
@@ -791,8 +794,8 @@ public:
enum ViewportUpdateMode {
VIEWPORT_UPDATE_DISABLED,
- VIEWPORT_UPDATE_ONCE, //then goes to disabled, must be manually updated
- VIEWPORT_UPDATE_WHEN_VISIBLE, // default
+ VIEWPORT_UPDATE_ONCE, // Then goes to disabled, must be manually updated.
+ VIEWPORT_UPDATE_WHEN_VISIBLE, // Default
VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE,
VIEWPORT_UPDATE_ALWAYS
};
@@ -1171,7 +1174,7 @@ public:
virtual void instance_set_ignore_culling(RID p_instance, bool p_enabled) = 0;
- // don't use these in a game!
+ // Don't use these in a game!
virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
@@ -1245,7 +1248,7 @@ public:
virtual void canvas_texture_set_channel(RID p_canvas_texture, CanvasTextureChannel p_channel, RID p_texture) = 0;
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
- //takes effect only for new draw commands
+ // Takes effect only for new draw commands.
virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, CanvasItemTextureFilter p_filter) = 0;
virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, CanvasItemTextureRepeat p_repeat) = 0;
@@ -1443,7 +1446,7 @@ public:
/* FREE */
- virtual void free(RID p_rid) = 0; ///< free RIDs associated with the rendering server
+ virtual void free(RID p_rid) = 0; // Free RIDs associated with the rendering server.
/* EVENT QUEUING */
@@ -1529,7 +1532,7 @@ public:
virtual ~RenderingServer();
private:
- //binder helpers
+ // Binder helpers
RID _texture_2d_layered_create(const TypedArray<Image> &p_layers, TextureLayeredType p_layered_type);
RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data);
@@ -1543,7 +1546,7 @@ private:
void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses);
};
-// make variant understand the enums
+// Make variant understand the enums.
VARIANT_ENUM_CAST(RenderingServer::TextureLayeredType);
VARIANT_ENUM_CAST(RenderingServer::CubeMapLayer);
VARIANT_ENUM_CAST(RenderingServer::ShaderMode);
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index d6d98b4f8f..5f83fc4206 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -1003,7 +1003,7 @@ bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_t
return false;
}
-bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
bool ret;
if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) {
return ret;
@@ -1011,7 +1011,7 @@ bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, co
return false;
}
-bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
bool ret;
if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) {
return ret;
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index a2dbd25e05..91d1a6b97e 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -337,11 +337,11 @@ public:
GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID);
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &);
- GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlign, int);
- GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlign);
+ GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlignment, int);
+ GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlignment);
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 3b71dc1d92..2303f27495 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -360,8 +360,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_preserve_control", "shaped"), &TextServer::shaped_text_get_preserve_control);
ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
- ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGN_CENTER));
+ ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("shaped_text_substr", "shaped", "start", "length"), &TextServer::shaped_text_substr);
ClassDB::bind_method(D_METHOD("shaped_text_get_parent", "shaped"), &TextServer::shaped_text_get_parent);
@@ -649,13 +649,13 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
+PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
PackedInt32Array lines;
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
const Vector2i &range = shaped_text_get_range(p_shaped);
- real_t width = 0.f;
+ float width = 0.f;
int line_start = MAX(p_start, range.x);
int last_safe_break = -1;
int word_count = 0;
@@ -1035,9 +1035,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
return ranges;
}
-int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const {
+int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const {
// Exact grapheme hit test, return -1 if missed.
- real_t off = 0.0f;
+ float off = 0.0f;
int v_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1053,7 +1053,7 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) con
return -1;
}
-int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const {
+int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) const {
int v_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1165,7 +1165,7 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
return p_pos;
}
-void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, const Color &p_color) const {
+void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped);
@@ -1262,7 +1262,7 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p
}
}
-void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, int p_outline_size, const Color &p_color) const {
+void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool rtl = (shaped_text_get_direction(p_shaped) == DIRECTION_RTL);
diff --git a/servers/text_server.h b/servers/text_server.h
index 5c994feaae..56b1919c51 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -170,7 +170,7 @@ protected:
struct EmbeddedObject {
int pos = 0;
- InlineAlign inline_align = INLINE_ALIGN_CENTER;
+ InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
Rect2 rect;
};
Map<Variant, EmbeddedObject> objects;
@@ -383,8 +383,8 @@ public:
virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0;
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") = 0;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) = 0;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) = 0;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) = 0;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
diff --git a/tests/core/io/test_file_access.h b/tests/core/io/test_file_access.h
index 4ffc57afe4..f566899c9b 100644
--- a/tests/core/io/test_file_access.h
+++ b/tests/core/io/test_file_access.h
@@ -53,7 +53,7 @@ TEST_CASE("[FileAccess] CSV read") {
REQUIRE(row2.size() == 3);
CHECK(row2[0] == "GOOD_EVENING");
CHECK(row2[1] == "Good Evening");
- CHECK(row2[2] == ""); // Use case: not yet translated!
+ CHECK(row2[2].is_empty()); // Use case: not yet translated!
// https://github.com/godotengine/godot/issues/44269
CHECK_MESSAGE(row2[2] != "\"", "Should not parse empty string as a single double quote.");
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index b838bed171..f5076ce1ed 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -349,14 +349,27 @@ TEST_CASE("[AABB] Has point") {
aabb.has_point(Vector3(2, 3, 0)),
"has_point() with contained point should return the expected value.");
CHECK_MESSAGE(
+ !aabb.has_point(Vector3(-20, 0, 0)),
+ "has_point() with non-contained point should return the expected value.");
+
+ CHECK_MESSAGE(
aabb.has_point(Vector3(-1.5, 3, 0)),
- "has_point() with contained point on negative edge should return the expected value.");
+ "has_point() with positive size should include point on near face (X axis).");
CHECK_MESSAGE(
aabb.has_point(Vector3(2.5, 3, 0)),
- "has_point() with contained point on positive edge should return the expected value.");
+ "has_point() with positive size should include point on far face (X axis).");
CHECK_MESSAGE(
- !aabb.has_point(Vector3(-20, 0, 0)),
- "has_point() with non-contained point should return the expected value.");
+ aabb.has_point(Vector3(0, 2, 0)),
+ "has_point() with positive size should include point on near face (Y axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 7, 0)),
+ "has_point() with positive size should include point on far face (Y axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 3, -2.5)),
+ "has_point() with positive size should include point on near face (Z axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 3, 3.5)),
+ "has_point() with positive size should include point on far face (Z axis).");
}
TEST_CASE("[AABB] Expanding") {
diff --git a/tests/core/math/test_math.cpp b/tests/core/math/test_math.cpp
index 6ec9bc2473..97e6055130 100644
--- a/tests/core/math/test_math.cpp
+++ b/tests/core/math/test_math.cpp
@@ -312,7 +312,7 @@ public:
}
}
- if (name != String()) {
+ if (!name.is_empty()) {
namespace_stack[at_level] = name;
}
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index 00a9a8779a..eef1cac894 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -157,10 +157,10 @@ TEST_CASE("[String] Invalid UTF8") {
String s;
bool err = s.parse_utf8((const char *)u8str);
CHECK(err);
- CHECK(s == String());
+ CHECK(s.is_empty());
CharString cs = (const char *)u8str;
- CHECK(String::utf8(cs) == String());
+ CHECK(String::utf8(cs).is_empty());
ERR_PRINT_ON
}
@@ -170,10 +170,10 @@ TEST_CASE("[String] Invalid UTF16") {
String s;
bool err = s.parse_utf16(u16str);
CHECK(err);
- CHECK(s == String());
+ CHECK(s.is_empty());
Char16String cs = u16str;
- CHECK(String::utf16(cs) == String());
+ CHECK(String::utf16(cs).is_empty());
ERR_PRINT_ON
}
@@ -1439,6 +1439,24 @@ TEST_CASE("[String] Variant ptr indexed set") {
CHECK_EQ(s, String("azcd"));
}
+
+TEST_CASE("[Stress][String] Empty via ' == String()'") {
+ for (int i = 0; i < 100000; ++i) {
+ String str = "Hello World!";
+ if (str.is_empty()) {
+ continue;
+ }
+ }
+}
+
+TEST_CASE("[Stress][String] Empty via `is_empty()`") {
+ for (int i = 0; i < 100000; ++i) {
+ String str = "Hello World!";
+ if (str.is_empty()) {
+ continue;
+ }
+ }
+}
} // namespace TestString
#endif // TEST_STRING_H
diff --git a/tests/core/templates/test_oa_hash_map.cpp b/tests/core/templates/test_oa_hash_map.cpp
index 904c01642d..f7b2b7cdb0 100644
--- a/tests/core/templates/test_oa_hash_map.cpp
+++ b/tests/core/templates/test_oa_hash_map.cpp
@@ -55,7 +55,10 @@ struct CountedItem {
count++;
}
- CountedItem &operator=(const CountedItem &p_other) = default;
+ void operator=(const CountedItem &p_other) {
+ id = p_other.id;
+ count++;
+ }
~CountedItem() {
CRASH_COND(destroyed);
diff --git a/tests/core/templates/test_vector.h b/tests/core/templates/test_vector.h
index 658ca5adf1..6ea865dacc 100644
--- a/tests/core/templates/test_vector.h
+++ b/tests/core/templates/test_vector.h
@@ -238,7 +238,7 @@ TEST_CASE("[Vector] To byte array") {
CHECK(byte_array[15] == 59);
}
-TEST_CASE("[Vector] Subarray") {
+TEST_CASE("[Vector] Slice") {
Vector<int> vector;
vector.push_back(0);
vector.push_back(1);
@@ -246,27 +246,27 @@ TEST_CASE("[Vector] Subarray") {
vector.push_back(3);
vector.push_back(4);
- Vector<int> subarray1 = vector.subarray(1, 2);
- CHECK(subarray1.size() == 2);
- CHECK(subarray1[0] == 1);
- CHECK(subarray1[1] == 2);
-
- Vector<int> subarray2 = vector.subarray(1, -1);
- CHECK(subarray2.size() == 4);
- CHECK(subarray2[0] == 1);
- CHECK(subarray2[1] == 2);
- CHECK(subarray2[2] == 3);
- CHECK(subarray2[3] == 4);
-
- Vector<int> subarray3 = vector.subarray(-2, -1);
- CHECK(subarray3.size() == 2);
- CHECK(subarray3[0] == 3);
- CHECK(subarray3[1] == 4);
-
- Vector<int> subarray4 = vector.subarray(-3, 3);
- CHECK(subarray4.size() == 2);
- CHECK(subarray4[0] == 2);
- CHECK(subarray4[1] == 3);
+ Vector<int> slice1 = vector.slice(1, 3);
+ CHECK(slice1.size() == 2);
+ CHECK(slice1[0] == 1);
+ CHECK(slice1[1] == 2);
+
+ Vector<int> slice2 = vector.slice(1, -1);
+ CHECK(slice2.size() == 4);
+ CHECK(slice2[0] == 1);
+ CHECK(slice2[1] == 2);
+ CHECK(slice2[2] == 3);
+ CHECK(slice2[3] == 4);
+
+ Vector<int> slice3 = vector.slice(3, -1);
+ CHECK(slice3.size() == 2);
+ CHECK(slice3[0] == 3);
+ CHECK(slice3[1] == 4);
+
+ Vector<int> slice4 = vector.slice(2, -2);
+ CHECK(slice4.size() == 2);
+ CHECK(slice4[0] == 2);
+ CHECK(slice4[1] == 3);
}
TEST_CASE("[Vector] Find, has") {
diff --git a/tests/core/variant/test_array.h b/tests/core/variant/test_array.h
index e2e84f2962..d02b3d0e39 100644
--- a/tests/core/variant/test_array.h
+++ b/tests/core/variant/test_array.h
@@ -246,6 +246,37 @@ TEST_CASE("[Array] max() and min()") {
CHECK(min == 2);
}
+TEST_CASE("[Array] slice()") {
+ Array array;
+ array.push_back(0);
+ array.push_back(1);
+ array.push_back(2);
+ array.push_back(3);
+ array.push_back(4);
+
+ Array slice1 = array.slice(1, 3);
+ CHECK(slice1.size() == 2);
+ CHECK(slice1[0] == Variant(1));
+ CHECK(slice1[1] == Variant(2));
+
+ Array slice2 = array.slice(1, -1);
+ CHECK(slice2.size() == 4);
+ CHECK(slice2[0] == Variant(1));
+ CHECK(slice2[1] == Variant(2));
+ CHECK(slice2[2] == Variant(3));
+ CHECK(slice2[3] == Variant(4));
+
+ Array slice3 = array.slice(3, -1);
+ CHECK(slice3.size() == 2);
+ CHECK(slice3[0] == Variant(3));
+ CHECK(slice3[1] == Variant(4));
+
+ Array slice4 = array.slice(2, -2);
+ CHECK(slice4.size() == 2);
+ CHECK(slice4[0] == Variant(2));
+ CHECK(slice4[1] == Variant(3));
+}
+
TEST_CASE("[Array] Duplicate array") {
// a = [1, [2, 2], {3: 3}]
Array a = build_array(1, build_array(2, 2), build_dictionary(3, 3));
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index a95dd02ba5..4b5a049a07 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -2332,6 +2332,20 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
CHECK_FALSE(code_edit->is_line_folded(2));
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+ // Indent with blank lines.
+ code_edit->set_text("line1\n\tline2\n\n\nline3");
+ CHECK(code_edit->can_fold_line(0));
+ for (int i = 1; i < 2; i++) {
+ CHECK_FALSE(code_edit->can_fold_line(i));
+ code_edit->fold_line(i);
+ CHECK_FALSE(code_edit->is_line_folded(i));
+ }
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
// Nested indents.
code_edit->set_text("line1\n\tline2\n\t\tline3\nline4");
CHECK(code_edit->can_fold_line(0));
@@ -2408,7 +2422,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
for (int i = 1; i < code_edit->get_line_count(); i++) {
CHECK_FALSE(code_edit->is_line_folded(i));
}
- CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 6);
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 5);
// End of file.
code_edit->set_text("line1\n\tline2");
@@ -2490,7 +2504,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
// Multiline blocks.
code_edit->add_comment_delimiter("&", "&", false);
- code_edit->set_text("&line1\n\tline2&");
+ code_edit->set_text("&line1\n\tline2&\nline3");
CHECK(code_edit->can_fold_line(0));
CHECK_FALSE(code_edit->can_fold_line(1));
code_edit->fold_line(1);
@@ -2498,7 +2512,17 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
code_edit->fold_line(0);
CHECK(code_edit->is_line_folded(0));
CHECK_FALSE(code_edit->is_line_folded(1));
- CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+ // Multiline comment before last line.
+ code_edit->set_text("&line1\nline2&\ntest");
+ CHECK(code_edit->can_fold_line(0));
+ CHECK_FALSE(code_edit->can_fold_line(2));
+ code_edit->fold_line(1);
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
// Has to be full line.
code_edit->set_text("test &line1\n\tline2&");
@@ -2554,7 +2578,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
CHECK_FALSE(code_edit->is_line_folded(1));
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
- // Non-indented comments/ strings.
+ // Non-indented comments/strings.
// Single line
code_edit->set_text("test\n\tline1\n#line1\n#line2\n\ttest");
CHECK(code_edit->can_fold_line(0));
@@ -2576,6 +2600,50 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
CHECK_FALSE(code_edit->is_line_folded(1));
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
+ // Indent level 0->1, comment after lines
+ code_edit->set_text("line1\n\tline2\n#test");
+ CHECK(code_edit->can_fold_line(0));
+ CHECK_FALSE(code_edit->can_fold_line(1));
+ code_edit->fold_line(1);
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+ // Indent level 0->1, comment between lines
+ code_edit->set_text("line1\n#test\n\tline2\nline3");
+ CHECK(code_edit->can_fold_line(0));
+ CHECK_FALSE(code_edit->can_fold_line(2));
+ code_edit->fold_line(2);
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
+
+ // Indent level 1->2, comment after lines
+ code_edit->set_text("\tline1\n\t\tline2\n#test");
+ CHECK(code_edit->can_fold_line(0));
+ CHECK_FALSE(code_edit->can_fold_line(1));
+ code_edit->fold_line(1);
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+ // Indent level 1->2, comment between lines
+ code_edit->set_text("\tline1\n#test\n\t\tline2\nline3");
+ CHECK(code_edit->can_fold_line(0));
+ CHECK_FALSE(code_edit->can_fold_line(2));
+ code_edit->fold_line(2);
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
+
// Multiline
code_edit->set_text("test\n\tline1\n&line1\nline2&\n\ttest");
CHECK(code_edit->can_fold_line(0));
@@ -3167,7 +3235,7 @@ TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
code_edit->insert_text_at_caret("line 1\nline 2\nline 3");
code_edit->select_all();
code_edit->backspace();
- CHECK(code_edit->get_text() == "");
+ CHECK(code_edit->get_text().is_empty());
/* Backspace at the beginning without selection has no effect. */
code_edit->set_text("");
diff --git a/tests/scene/test_curve.h b/tests/scene/test_curve.h
index 60eafad460..4ee1a1c15c 100644
--- a/tests/scene/test_curve.h
+++ b/tests/scene/test_curve.h
@@ -219,35 +219,33 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
TEST_CASE("[Curve2D] Linear sampling should return exact value") {
Ref<Curve2D> curve = memnew(Curve2D);
- int len = 2048;
+ real_t len = 2048.0;
curve->add_point(Vector2(0, 0));
- curve->add_point(Vector2((float)len, 0));
+ curve->add_point(Vector2(len, 0));
- float baked_length = curve->get_baked_length();
- CHECK((float)len == baked_length);
+ real_t baked_length = curve->get_baked_length();
+ CHECK(len == baked_length);
for (int i = 0; i < len; i++) {
- float expected = (float)i;
- Vector2 pos = curve->interpolate_baked(expected);
- CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ Vector2 pos = curve->interpolate_baked(i);
+ CHECK_MESSAGE(pos.x == i, "interpolate_baked should return exact value");
}
}
TEST_CASE("[Curve3D] Linear sampling should return exact value") {
Ref<Curve3D> curve = memnew(Curve3D);
- int len = 2048;
+ real_t len = 2048.0;
curve->add_point(Vector3(0, 0, 0));
- curve->add_point(Vector3((float)len, 0, 0));
+ curve->add_point(Vector3(len, 0, 0));
- float baked_length = curve->get_baked_length();
- CHECK((float)len == baked_length);
+ real_t baked_length = curve->get_baked_length();
+ CHECK(len == baked_length);
for (int i = 0; i < len; i++) {
- float expected = (float)i;
- Vector3 pos = curve->interpolate_baked(expected);
- CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ Vector3 pos = curve->interpolate_baked(i);
+ CHECK_MESSAGE(pos.x == i, "interpolate_baked should return exact value");
}
}
diff --git a/tests/scene/test_gui.cpp b/tests/scene/test_gui.cpp
index 5bd9390cb7..086943838c 100644
--- a/tests/scene/test_gui.cpp
+++ b/tests/scene/test_gui.cpp
@@ -69,7 +69,7 @@ public:
label->set_position(Point2(80, 90));
label->set_size(Point2(170, 80));
- label->set_align(Label::ALIGN_FILL);
+ label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_FILL);
label->set_text("There was once upon a time a beautiful unicorn that loved to play with little girls...");
frame->add_child(label);
diff --git a/tests/servers/test_shader_lang.cpp b/tests/servers/test_shader_lang.cpp
index 0591bf6adf..1f8f395e64 100644
--- a/tests/servers/test_shader_lang.cpp
+++ b/tests/servers/test_shader_lang.cpp
@@ -261,6 +261,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
}
code += ")";
break;
+ case SL::OP_EMPTY:
+ break;
default: {
code = "(" + dump_node_code(onode->arguments[0], p_level) + _opstr(onode->op) + dump_node_code(onode->arguments[1], p_level) + ")";
break;
@@ -344,7 +346,12 @@ MainLoop *test() {
Set<String> types;
types.insert("spatial");
- Error err = sl.compile(code, dt, rm, ShaderLanguage::VaryingFunctionNames(), types, nullptr);
+ ShaderLanguage::ShaderCompileInfo info;
+ info.functions = dt;
+ info.render_modes = rm;
+ info.shader_types = types;
+
+ Error err = sl.compile(code, info);
if (err) {
print_line("Error at line: " + rtos(sl.get_error_line()) + ": " + sl.get_error_text());
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 03e9885bd0..f8055ac3e7 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -201,7 +201,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 3.1.1 (cd5c6cd0419ac5e4de975d6c476fb760bf06d2ce, 2021)
+- Version: 3.1.2 (8aed5c21a31eece6a9f3cd775fda8facb6c28b9b, 2021)
- License: MIT
Files extracted from upstream source:
@@ -359,6 +359,19 @@ instead of a combination of distance and attribute errors. Patches for both chan
found in the `patches` directory.
+## minimp3
+
+- Upstream: https://github.com/lieff/minimp3
+- Version: git (afb604c06bc8beb145fecd42c0ceb5bda8795144, 2021)
+- License: CC0 1.0
+
+Files extracted from upstream repository:
+
+- `minimp3.h`
+- `minimp3_ex.h`
+- `LICENSE`
+
+
## miniupnpc
- Upstream: https://github.com/miniupnp/miniupnp
diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh
index dd61509b2e..0beffb078f 100644
--- a/thirdparty/harfbuzz/src/hb-array.hh
+++ b/thirdparty/harfbuzz/src/hb-array.hh
@@ -51,13 +51,19 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
* Constructors.
*/
hb_array_t () = default;
- hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
+ hb_array_t (const hb_array_t&) = default;
+ ~hb_array_t () = default;
+ hb_array_t& operator= (const hb_array_t&) = default;
+ hb_array_t& operator= (hb_array_t&&) = default;
+
+ constexpr hb_array_t (std::nullptr_t) : hb_array_t () {}
+ constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
template <unsigned int length_>
- hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
+ constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_array_t (const hb_array_t<U> &o) :
+ constexpr hb_array_t (const hb_array_t<U> &o) :
hb_iter_with_fallback_t<hb_array_t, Type&> (),
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
template <typename U,
@@ -303,13 +309,19 @@ struct hb_sorted_array_t :
static constexpr bool is_sorted_iterator = true;
hb_sorted_array_t () = default;
- hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
+ hb_sorted_array_t (const hb_sorted_array_t&) = default;
+ ~hb_sorted_array_t () = default;
+ hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default;
+ hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default;
+
+ constexpr hb_sorted_array_t (std::nullptr_t) : hb_sorted_array_t () {}
+ constexpr hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
template <unsigned int length_>
- hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+ constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_sorted_array_t (const hb_array_t<U> &o) :
+ constexpr hb_sorted_array_t (const hb_array_t<U> &o) :
hb_iter_t<hb_sorted_array_t, Type&> (),
hb_array_t<Type> (o) {}
template <typename U,
diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh
index bb4a0eb5d1..793dcf22ca 100644
--- a/thirdparty/harfbuzz/src/hb-map.hh
+++ b/thirdparty/harfbuzz/src/hb-map.hh
@@ -35,8 +35,10 @@
*/
template <typename K, typename V,
- K kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
- V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
+ typename k_invalid_t = K,
+ typename v_invalid_t = V,
+ k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+ v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
struct hb_hashmap_t
{
static constexpr K INVALID_KEY = kINVALID;
@@ -62,8 +64,10 @@ struct hb_hashmap_t
hb_copy (o, *this);
}
- static_assert (std::is_integral<K>::value || hb_is_pointer (K), "");
- static_assert (std::is_integral<V>::value || hb_is_pointer (V), "");
+ static_assert (std::is_trivially_copyable<K>::value, "");
+ static_assert (std::is_trivially_copyable<V>::value, "");
+ static_assert (std::is_trivially_destructible<K>::value, "");
+ static_assert (std::is_trivially_destructible<V>::value, "");
struct item_t
{
@@ -348,19 +352,23 @@ struct hb_hashmap_t
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
+ hb_codepoint_t,
+ hb_codepoint_t,
HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID>
{
using hashmap = hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
+ hb_codepoint_t,
+ hb_codepoint_t,
HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID>;
hb_map_t () = default;
~hb_map_t () = default;
- hb_map_t (hb_map_t& o) = default;
- hb_map_t& operator= (const hb_map_t& other) = default;
- hb_map_t& operator= (hb_map_t&& other) = default;
+ hb_map_t (hb_map_t&) = default;
+ hb_map_t& operator= (const hb_map_t&) = default;
+ hb_map_t& operator= (hb_map_t&&) = default;
hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
index 03476faba7..a3c55fa8f4 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
@@ -38,8 +38,8 @@
*/
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
-#ifndef COLRV1_MAX_NESTING_LEVEL
-#define COLRV1_MAX_NESTING_LEVEL 100
+#ifndef HB_COLRV1_MAX_NESTING_LEVEL
+#define HB_COLRV1_MAX_NESTING_LEVEL 100
#endif
#ifndef COLRV1_ENABLE_SUBSETTING
@@ -102,7 +102,7 @@ struct hb_colrv1_closure_context_t :
hb_set_t *glyphs_,
hb_set_t *layer_indices_,
hb_set_t *palette_indices_,
- unsigned nesting_level_left_ = COLRV1_MAX_NESTING_LEVEL) :
+ unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) :
base (base_),
glyphs (glyphs_),
layer_indices (layer_indices_),
@@ -985,7 +985,7 @@ struct ClipList
for (const hb_codepoint_t _ : gids.iter ())
{
if (_ == start_gid) continue;
-
+
offset = gid_offset_map.get (_);
if (_ == prev_gid + 1 && offset == prev_offset)
{
@@ -1027,7 +1027,7 @@ struct ClipList
const hb_set_t& glyphset = *c->plan->_glyphset;
const hb_map_t &glyph_map = *c->plan->glyph_map;
-
+
hb_map_t new_gid_offset_map;
hb_set_t new_gids;
for (const ClipRecord& record : clips.iter ())
@@ -1062,6 +1062,18 @@ struct ClipList
struct Paint
{
+
+ template <typename ...Ts>
+ bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL)))
+ return_trace (c->no_dispatch_return_value ());
+
+ return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
+ }
+
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index 5d98278bed..882c3ae96f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -98,7 +98,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
struct hb_prune_langsys_context_t
{
hb_prune_langsys_context_t (const void *table_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
const hb_map_t *duplicate_feature_map_,
hb_set_t *new_collected_feature_indexes_)
:table (table_),
@@ -137,7 +137,7 @@ struct hb_prune_langsys_context_t
public:
const void *table;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
const hb_map_t *duplicate_feature_map;
hb_set_t *new_feature_indexes;
@@ -179,14 +179,14 @@ struct hb_subset_layout_context_t :
hb_subset_context_t *subset_context;
const hb_tag_t table_tag;
const hb_map_t *lookup_index_map;
- const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+ const hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
const hb_map_t *feature_index_map;
unsigned cur_script_index;
hb_subset_layout_context_t (hb_subset_context_t *c_,
hb_tag_t tag_,
hb_map_t *lookup_map_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
hb_map_t *feature_index_map_) :
subset_context (c_),
table_tag (tag_),
@@ -1357,7 +1357,7 @@ struct Lookup
if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
return_trace (false);
- if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
+ if (unlikely (get_type () == TSubTable::Extension && subtables && !c->get_edit_count ()))
{
/* The spec says all subtables of an Extension lookup should
* have the same type, which shall not be the Extension type
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index c0ed2bcc03..6bc06b50ed 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -163,7 +163,7 @@ struct hb_closure_context_t :
hb_set_t *glyphs_,
hb_set_t *cur_intersected_glyphs_,
hb_map_t *done_lookups_glyph_count_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set_,
+ hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
glyphs (glyphs_),
@@ -192,7 +192,7 @@ struct hb_closure_context_t :
private:
hb_map_t *done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set;
unsigned int lookup_count;
};
@@ -1642,9 +1642,8 @@ struct Rule
const hb_map_t *klass_map = nullptr) const
{
TRACE_SUBSET (this);
-
- const hb_array_t<const HBUINT16> input = inputZ.as_array ((inputCount ? inputCount - 1 : 0));
- if (!input.length) return_trace (false);
+ if (unlikely (!inputCount)) return_trace (false);
+ const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1);
const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map;
if (!hb_all (input, mapping)) return_trace (false);
@@ -3631,7 +3630,7 @@ struct GSUBGPOS
}
void prune_langsys (const hb_map_t *duplicate_feature_map,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map,
hb_set_t *new_feature_indexes /* OUT */) const
{
hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
@@ -3689,7 +3688,7 @@ struct GSUBGPOS
hb_map_t *duplicate_feature_map /* OUT */) const
{
if (feature_indices->is_empty ()) return;
- hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
+ hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features;
//find out duplicate features after subset
for (unsigned i : feature_indices->iter ())
{
@@ -3784,8 +3783,12 @@ struct GSUBGPOS
// http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html
continue;
- if (f.featureParams.is_null ()
- && !f.intersects_lookup_indexes (lookup_indices)
+
+ if (!f.featureParams.is_null () &&
+ tag == HB_TAG ('s', 'i', 'z', 'e'))
+ continue;
+
+ if (!f.intersects_lookup_indexes (lookup_indices)
#ifndef HB_NO_VAR
&& !alternate_feature_indices.has (i)
#endif
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index fbdedd0e20..4e1d23eba5 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -1493,7 +1493,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
{
hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
@@ -1522,7 +1522,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
{
hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::GSUB& gsub = *face->table.GSUB->table;
diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
index 94450eb53a..504de2de74 100644
--- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
@@ -79,6 +79,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
post::accelerator_t _post;
_post.init (c->plan->source);
+ hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -90,22 +91,28 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
else
{
hb_bytes_t s = _post.find_glyph_name (old_gid);
- int standard_glyph_index = -1;
- for (unsigned i = 0; i < format1_names_length; i++)
+ new_index = glyph_name_to_new_index.get (s);
+ if (new_index == (unsigned)-1)
{
- if (s == format1_names (i))
+ int standard_glyph_index = -1;
+ for (unsigned i = 0; i < format1_names_length; i++)
{
- standard_glyph_index = i;
- break;
+ if (s == format1_names (i))
+ {
+ standard_glyph_index = i;
+ break;
+ }
}
+
+ if (standard_glyph_index == -1)
+ {
+ new_index = 258 + i;
+ i++;
+ }
+ else
+ { new_index = standard_glyph_index; }
+ glyph_name_to_new_index.set (s, new_index);
}
- if (standard_glyph_index == -1)
- {
- new_index = 258 + i;
- i++;
- }
- else
- { new_index = standard_glyph_index; }
old_new_index_map.set (old_index, new_index);
}
old_gid_new_index_map.set (old_gid, new_index);
diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh
index 2e536c7a81..65c2772201 100644
--- a/thirdparty/harfbuzz/src/hb-sanitize.hh
+++ b/thirdparty/harfbuzz/src/hb-sanitize.hh
@@ -123,6 +123,7 @@ struct hb_sanitize_context_t :
hb_sanitize_context_t () :
start (nullptr), end (nullptr),
max_ops (0), max_subtables (0),
+ recursion_depth (0),
writable (false), edit_count (0),
blob (nullptr),
num_glyphs (65536),
@@ -205,6 +206,7 @@ struct hb_sanitize_context_t :
(unsigned) HB_SANITIZE_MAX_OPS_MAX);
this->edit_count = 0;
this->debug_depth = 0;
+ this->recursion_depth = 0;
DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
"start [%p..%p] (%lu bytes)",
@@ -278,6 +280,18 @@ struct hb_sanitize_context_t :
return this->check_range (base, a, b, hb_static_size (T));
}
+ bool check_start_recursion (int max_depth)
+ {
+ if (unlikely (recursion_depth >= max_depth)) return false;
+ return ++recursion_depth;
+ }
+
+ bool end_recursion (bool result)
+ {
+ recursion_depth--;
+ return result;
+ }
+
template <typename Type>
bool check_struct (const Type *obj) const
{ return likely (this->check_range (obj, obj->min_size)); }
@@ -389,6 +403,7 @@ struct hb_sanitize_context_t :
const char *start, *end;
mutable int max_ops, max_subtables;
private:
+ int recursion_depth;
bool writable;
unsigned int edit_count;
hb_blob_t *blob;
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index 57689916f6..d22ae06087 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -652,7 +652,9 @@ struct hb_serialize_context_t
hb_vector_t<object_t *> packed;
/* Map view of packed objects. */
- hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map;
+ hb_hashmap_t<const object_t *, objidx_t,
+ const object_t *, objidx_t,
+ nullptr, 0> packed_map;
};
#endif /* HB_SERIALIZE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh
index 8841427189..af02e9e12b 100644
--- a/thirdparty/harfbuzz/src/hb-set.hh
+++ b/thirdparty/harfbuzz/src/hb-set.hh
@@ -157,9 +157,9 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
{
hb_set_t () = default;
~hb_set_t () = default;
- hb_set_t (hb_set_t& o) = default;
- hb_set_t& operator= (const hb_set_t& other) = default;
- hb_set_t& operator= (hb_set_t&& other) = default;
+ hb_set_t (hb_set_t&) = default;
+ hb_set_t& operator= (const hb_set_t&) = default;
+ hb_set_t& operator= (hb_set_t&&) = default;
hb_set_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index 1e195ff660..53f8664d92 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -41,7 +41,7 @@
#include "hb-ot-math-table.hh"
-typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
+typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map;
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
@@ -100,11 +100,23 @@ static void _collect_layout_indices (hb_face_t *face,
if (!features.alloc (table.get_feature_count () + 1))
return;
+ hb_set_t visited_features;
+ bool retain_all_features = true;
for (unsigned i = 0; i < table.get_feature_count (); i++)
{
hb_tag_t tag = table.get_feature_tag (i);
- if (tag && layout_features_to_retain->has (tag))
- features.push (tag);
+ if (!tag) continue;
+ if (!layout_features_to_retain->has (tag))
+ {
+ retain_all_features = false;
+ continue;
+ }
+
+ if (visited_features.has (tag))
+ continue;
+
+ features.push (tag);
+ visited_features.add (tag);
}
if (!features)
@@ -113,7 +125,7 @@ static void _collect_layout_indices (hb_face_t *face,
// The collect function needs a null element to signal end of the array.
features.push (0);
- if (features.get_size () == table.get_feature_count () + 1)
+ if (retain_all_features)
{
// Looking for all features, trigger the faster collection method.
layout_collect_func (face,
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh
index c30feeb42f..c0232480bf 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh
@@ -84,8 +84,8 @@ struct hb_subset_plan_t
hb_map_t *gpos_lookups;
//active langsys we'd like to retain
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gsub_langsys;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gpos_langsys;
+ hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys;
+ hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys;
//active features after removing redundant langsys and prune_features
hb_map_t *gsub_features;
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index 1a4f0bf62a..c9fefa1df6 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -53,14 +53,14 @@ HB_BEGIN_DECLS
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MICRO 2
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "3.1.1"
+#define HB_VERSION_STRING "3.1.2"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/minimp3/minimp3.h b/thirdparty/minimp3/minimp3.h
index 796cbc1f8e..3220ae1a85 100644
--- a/thirdparty/minimp3/minimp3.h
+++ b/thirdparty/minimp3/minimp3.h
@@ -881,12 +881,22 @@ static void L3_midside_stereo(float *left, int n)
int i = 0;
float *right = left + 576;
#if HAVE_SIMD
- if (have_simd()) for (; i < n - 3; i += 4)
+ if (have_simd())
{
- f4 vl = VLD(left + i);
- f4 vr = VLD(right + i);
- VSTORE(left + i, VADD(vl, vr));
- VSTORE(right + i, VSUB(vl, vr));
+ for (; i < n - 3; i += 4)
+ {
+ f4 vl = VLD(left + i);
+ f4 vr = VLD(right + i);
+ VSTORE(left + i, VADD(vl, vr));
+ VSTORE(right + i, VSUB(vl, vr));
+ }
+#ifdef __GNUC__
+ /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
+ * For more info see: https://github.com/lieff/minimp3/issues/88
+ */
+ if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
+ return;
+#endif
}
#endif /* HAVE_SIMD */
for (; i < n; i++)
@@ -1353,7 +1363,7 @@ static void mp3d_DCT_II(float *grbuf, int n)
} else
#endif /* HAVE_SIMD */
#ifdef MINIMP3_ONLY_SIMD
- {}
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else /* MINIMP3_ONLY_SIMD */
for (; k < n; k++)
{
@@ -1583,7 +1593,7 @@ static void mp3d_synth(float *xl, mp3d_sample_t *dstl, int nch, float *lins)
} else
#endif /* HAVE_SIMD */
#ifdef MINIMP3_ONLY_SIMD
- {}
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else /* MINIMP3_ONLY_SIMD */
for (i = 14; i >= 0; i--)
{
diff --git a/thirdparty/minimp3/minimp3_ex.h b/thirdparty/minimp3/minimp3_ex.h
index e29dd15b2e..2871705df3 100644
--- a/thirdparty/minimp3/minimp3_ex.h
+++ b/thirdparty/minimp3/minimp3_ex.h
@@ -6,6 +6,7 @@
This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
+#include <stddef.h>
#include "minimp3.h"
/* flags for mp3dec_ex_open_* functions */
@@ -128,8 +129,10 @@ int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags);
#endif
#endif /*MINIMP3_EXT_H*/
-#ifdef MINIMP3_IMPLEMENTATION
+#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_EX_IMPLEMENTATION_GUARD)
+#define _MINIMP3_EX_IMPLEMENTATION_GUARD
#include <limits.h>
+#include "minimp3.h"
static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
{
@@ -1391,4 +1394,4 @@ void mp3dec_ex_close(mp3dec_ex_t *dec)
}
#endif
-#endif /*MINIMP3_IMPLEMENTATION*/
+#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_EX_IMPLEMENTATION_GUARD */