diff options
43 files changed, 526 insertions, 541 deletions
diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp index 19c6fc3383..c7eb32c020 100644 --- a/core/object/script_language_extension.cpp +++ b/core/object/script_language_extension.cpp @@ -36,6 +36,7 @@ void ScriptExtension::_bind_methods() { GDVIRTUAL_BIND(_can_instantiate); GDVIRTUAL_BIND(_get_base_script); + GDVIRTUAL_BIND(_get_global_name); GDVIRTUAL_BIND(_inherits_script, "script"); GDVIRTUAL_BIND(_get_instance_base_type); diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index 92fd8bcc6a..c6d03fb6d8 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -171,6 +171,8 @@ - [code]type[/code]: Always [constant NavigationPathQueryResult2D.PATH_SEGMENT_TYPE_LINK]. - [code]rid[/code]: The [RID] of the link. - [code]owner[/code]: The object which manages the link (usually [NavigationLink2D]). + - [code]link_entry_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point the agent is entering. + - [code]link_exit_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point which the agent is exiting. </description> </signal> <signal name="navigation_finished"> diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index 0ed11bc477..294fe49408 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -174,6 +174,8 @@ - [code]type[/code]: Always [constant NavigationPathQueryResult3D.PATH_SEGMENT_TYPE_LINK]. - [code]rid[/code]: The [RID] of the link. - [code]owner[/code]: The object which manages the link (usually [NavigationLink3D]). + - [code]link_entry_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point the agent is entering. + - [code]link_exit_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point which the agent is exiting. </description> </signal> <signal name="navigation_finished"> diff --git a/doc/classes/NavigationLink2D.xml b/doc/classes/NavigationLink2D.xml index b3f4367675..3f5b1fb184 100644 --- a/doc/classes/NavigationLink2D.xml +++ b/doc/classes/NavigationLink2D.xml @@ -10,6 +10,18 @@ <link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link> </tutorials> <methods> + <method name="get_global_end_position" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the [member end_position] that is relative to the link as a global position. + </description> + </method> + <method name="get_global_start_position" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the [member start_position] that is relative to the link as a global position. + </description> + </method> <method name="get_navigation_layer_value" qualifiers="const"> <return type="bool" /> <param index="0" name="layer_number" type="int" /> @@ -17,6 +29,20 @@ Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. </description> </method> + <method name="set_global_end_position"> + <return type="void" /> + <param index="0" name="position" type="Vector2" /> + <description> + Sets the [member end_position] that is relative to the link from a global [param position]. + </description> + </method> + <method name="set_global_start_position"> + <return type="void" /> + <param index="0" name="position" type="Vector2" /> + <description> + Sets the [member start_position] that is relative to the link from a global [param position]. + </description> + </method> <method name="set_navigation_layer_value"> <return type="void" /> <param index="0" name="layer_number" type="int" /> diff --git a/doc/classes/NavigationLink3D.xml b/doc/classes/NavigationLink3D.xml index 4dff226042..4081426dcd 100644 --- a/doc/classes/NavigationLink3D.xml +++ b/doc/classes/NavigationLink3D.xml @@ -10,6 +10,18 @@ <link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link> </tutorials> <methods> + <method name="get_global_end_position" qualifiers="const"> + <return type="Vector3" /> + <description> + Returns the [member end_position] that is relative to the link as a global position. + </description> + </method> + <method name="get_global_start_position" qualifiers="const"> + <return type="Vector3" /> + <description> + Returns the [member start_position] that is relative to the link as a global position. + </description> + </method> <method name="get_navigation_layer_value" qualifiers="const"> <return type="bool" /> <param index="0" name="layer_number" type="int" /> @@ -17,6 +29,20 @@ Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. </description> </method> + <method name="set_global_end_position"> + <return type="void" /> + <param index="0" name="position" type="Vector3" /> + <description> + Sets the [member end_position] that is relative to the link from a global [param position]. + </description> + </method> + <method name="set_global_start_position"> + <return type="void" /> + <param index="0" name="position" type="Vector3" /> + <description> + Sets the [member start_position] that is relative to the link from a global [param position]. + </description> + </method> <method name="set_navigation_layer_value"> <return type="void" /> <param index="0" name="layer_number" type="int" /> diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index e7a2b99172..103de8eddb 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -126,6 +126,12 @@ Destroys the given RID. </description> </method> + <method name="get_debug_enabled" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] when the NavigationServer has debug enabled. + </description> + </method> <method name="get_maps" qualifiers="const"> <return type="RID[]" /> <description> @@ -520,6 +526,13 @@ Sets the [param travel_cost] for this [param region]. </description> </method> + <method name="set_debug_enabled"> + <return type="void" /> + <param index="0" name="enabled" type="bool" /> + <description> + If [code]true[/code] enables debug mode on the NavigationServer. + </description> + </method> </methods> <signals> <signal name="map_changed"> diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 1feb363999..0d8cb78ff9 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -126,6 +126,12 @@ Destroys the given RID. </description> </method> + <method name="get_debug_enabled" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] when the NavigationServer has debug enabled. + </description> + </method> <method name="get_maps" qualifiers="const"> <return type="RID[]" /> <description> @@ -575,6 +581,13 @@ Control activation of this server. </description> </method> + <method name="set_debug_enabled"> + <return type="void" /> + <param index="0" name="enabled" type="bool" /> + <description> + If [code]true[/code] enables debug mode on the NavigationServer. + </description> + </method> </methods> <signals> <signal name="map_changed"> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index 1aa71113e9..c199c1aae6 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -4,7 +4,7 @@ Most basic 3D game object, parent of all 3D-related nodes. </brief_description> <description> - Most basic 3D game object, with a 3D [Transform3D] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. + Most basic 3D game object, with a [Transform3D] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system. [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg_to_rad]. </description> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 986810edf2..dcc4248682 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -667,7 +667,7 @@ Main window initial position. [code]0[/code] - "Absolute", [member display/window/size/initial_position] is used to set window position. [code]1[/code] - "Primary Screen Center". - [code]2[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set window position. + [code]2[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set the screen. </member> <member name="display/window/size/initial_screen" type="int" setter="" getter="" default="0"> Main window initial screen, this settings is used only if [member display/window/size/initial_position_type] is set to "Other Screen Center" ([code]2[/code]). @@ -1147,9 +1147,6 @@ <member name="input_devices/pointing/emulate_touch_from_mouse" type="bool" setter="" getter="" default="false"> If [code]true[/code], sends touch input events when clicking or dragging the mouse. </member> - <member name="input_devices/pointing/ios/touch_delay" type="float" setter="" getter="" default="0.15"> - Default delay for touch events. This only affects iOS devices. - </member> <member name="internationalization/locale/fallback" type="String" setter="" getter="" default=""en""> The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used. </member> diff --git a/doc/classes/ScriptExtension.xml b/doc/classes/ScriptExtension.xml index 045eadda41..61034f8e4a 100644 --- a/doc/classes/ScriptExtension.xml +++ b/doc/classes/ScriptExtension.xml @@ -32,6 +32,11 @@ <description> </description> </method> + <method name="_get_global_name" qualifiers="virtual const"> + <return type="StringName" /> + <description> + </description> + </method> <method name="_get_instance_base_type" qualifiers="virtual const"> <return type="StringName" /> <description> diff --git a/doc/classes/VisibleOnScreenEnabler2D.xml b/doc/classes/VisibleOnScreenEnabler2D.xml index 8590e9cc9f..68e510a6dc 100644 --- a/doc/classes/VisibleOnScreenEnabler2D.xml +++ b/doc/classes/VisibleOnScreenEnabler2D.xml @@ -24,7 +24,7 @@ Corresponds to [constant Node.PROCESS_MODE_ALWAYS]. </constant> <constant name="ENABLE_MODE_WHEN_PAUSED" value="2" enum="EnableMode"> - Corresponds to [constant Node.PROCESS_MODE_WHEN_PAUSED. + Corresponds to [constant Node.PROCESS_MODE_WHEN_PAUSED]. </constant> </constants> </class> diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index db65ce62f2..cdada35970 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -210,7 +210,7 @@ This interface supports quad rendering (not yet supported by Godot). </constant> <constant name="XR_VR" value="8" enum="Capabilities"> - this interface supports VR. + This interface supports VR. </constant> <constant name="XR_AR" value="16" enum="Capabilities"> This interface supports AR (video background and real world tracking). diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl index 0b76c4334a..92bf2d87e4 100644 --- a/drivers/gles3/shaders/stdlib_inc.glsl +++ b/drivers/gles3/shaders/stdlib_inc.glsl @@ -14,11 +14,7 @@ uint float2half(uint f) { uint half2float(uint h) { uint h_e = h & uint(0x7c00); - if (h_e == uint(0x0000)) { - return uint(0); - } else { - return ((h & uint(0x8000)) << uint(16)) | ((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13)); - } + return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); } uint packHalf2x16(vec2 v) { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 9f3893a5db..9eabc31621 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1522,6 +1522,8 @@ void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation, boo animation = p_animation; read_only = p_read_only; + length->set_read_only(read_only); + if (animation.is_valid()) { len_hb->show(); if (read_only) { diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index dd912eac42..4533bcc51c 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -693,7 +693,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { bool is_valid_revert = false; Variant revert_value = EditorPropertyRevert::get_property_revert_value(object, property, &is_valid_revert); ERR_FAIL_COND(!is_valid_revert); - emit_changed(property, revert_value); + emit_changed(_get_revert_property(), revert_value); update_property(); } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 33bba90c70..30c7d2b85f 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -4174,9 +4174,12 @@ struct EditorPropertyRangeHint { bool radians = false; }; -static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const String &p_hint_text, double p_default_step) { +static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const String &p_hint_text, double p_default_step, bool is_int = false) { EditorPropertyRangeHint hint; hint.step = p_default_step; + if (is_int) { + hint.hide_slider = false; // Always show slider for ints, unless specified in hint range. + } Vector<String> slices = p_hint_text.split(","); if (p_hint == PROPERTY_HINT_RANGE) { ERR_FAIL_COND_V_MSG(slices.size() < 2, hint, @@ -4294,7 +4297,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ } else { EditorPropertyInteger *editor = memnew(EditorPropertyInteger); - EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1, true); editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.or_greater, hint.or_less, hint.suffix); return editor; @@ -4383,7 +4386,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ } break; case Variant::VECTOR2I: { EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide)); - EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1, true); editor->setup(hint.min, hint.max, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; @@ -4396,7 +4399,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ } break; case Variant::RECT2I: { EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i(p_wide)); - EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1, true); editor->setup(hint.min, hint.max, hint.suffix); return editor; @@ -4410,7 +4413,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ } break; case Variant::VECTOR3I: { EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide)); - EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1, true); editor->setup(hint.min, hint.max, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; @@ -4424,7 +4427,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ } break; case Variant::VECTOR4I: { EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i); - EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1, true); editor->setup(hint.min, hint.max, hint.suffix); return editor; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 6d747ba6a8..ccbc7c3d74 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2518,7 +2518,7 @@ void ScriptEditor::save_all_scripts() { } else { // For built-in scripts, save their scenes instead. const String scene_path = edited_res->get_path().get_slice("::", 0); - if (!scenes_to_save.has(scene_path)) { + if (!scene_path.is_empty() && !scenes_to_save.has(scene_path)) { scenes_to_save.push_back(scene_path); } } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 04a09a97e7..4d9e2db682 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -2055,7 +2055,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { select_tool_button->set_flat(true); select_tool_button->set_toggle_mode(true); select_tool_button->set_button_group(tool_buttons_group); - select_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/selection_tool", "Selection", Key::S)); + select_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/selection_tool", TTR("Selection"), Key::S)); select_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(select_tool_button); @@ -2063,7 +2063,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { paint_tool_button->set_flat(true); paint_tool_button->set_toggle_mode(true); paint_tool_button->set_button_group(tool_buttons_group); - paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", "Paint", Key::D)); + paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", TTR("Paint"), Key::D)); paint_tool_button->set_tooltip_text(TTR("Shift: Draw line.") + "\n" + TTR("Shift+Ctrl: Draw rectangle.")); paint_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(paint_tool_button); @@ -2072,7 +2072,8 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { line_tool_button->set_flat(true); line_tool_button->set_toggle_mode(true); line_tool_button->set_button_group(tool_buttons_group); - line_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/line_tool", "Line", Key::L)); + // TRANSLATORS: This refers to the line tool in the tilemap editor. + line_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/line_tool", TTR("Line", "Tool"), Key::L)); line_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(line_tool_button); @@ -2080,7 +2081,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { rect_tool_button->set_flat(true); rect_tool_button->set_toggle_mode(true); rect_tool_button->set_button_group(tool_buttons_group); - rect_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/rect_tool", "Rect", Key::R)); + rect_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/rect_tool", TTR("Rect"), Key::R)); rect_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(rect_tool_button); @@ -2088,7 +2089,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { bucket_tool_button->set_flat(true); bucket_tool_button->set_toggle_mode(true); bucket_tool_button->set_button_group(tool_buttons_group); - bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", "Bucket", Key::B)); + bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", TTR("Bucket"), Key::B)); bucket_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(bucket_tool_button); toolbar->add_child(tilemap_tiles_tools_buttons); @@ -2104,7 +2105,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { picker_button = memnew(Button); picker_button->set_flat(true); picker_button->set_toggle_mode(true); - picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", "Picker", Key::P)); + picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", TTR("Picker"), Key::P)); picker_button->set_tooltip_text(TTR("Alternatively hold Ctrl with other tools to pick tile.")); picker_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport)); tools_settings->add_child(picker_button); @@ -2113,7 +2114,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { erase_button = memnew(Button); erase_button->set_flat(true); erase_button->set_toggle_mode(true); - erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", "Eraser", Key::E)); + erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", TTR("Eraser"), Key::E)); erase_button->set_tooltip_text(TTR("Alternatively use RMB to erase tiles.")); erase_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport)); tools_settings->add_child(erase_button); @@ -3180,7 +3181,7 @@ void TileMapEditorTerrainsPlugin::_update_terrains_tree() { terrain_set_tree_item->set_icon(0, main_vbox_container->get_theme_icon(SNAME("TerrainMatchSides"), SNAME("EditorIcons"))); matches = String(TTR("Matches Sides Only")); } - terrain_set_tree_item->set_text(0, vformat("Terrain Set %d (%s)", terrain_set_index, matches)); + terrain_set_tree_item->set_text(0, vformat(TTR("Terrain Set %d (%s)"), terrain_set_index, matches)); terrain_set_tree_item->set_selectable(0, false); for (int terrain_index = 0; terrain_index < tile_set->get_terrains_count(terrain_set_index); terrain_index++) { @@ -3329,7 +3330,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { main_vbox_container = memnew(VBoxContainer); main_vbox_container->connect("tree_entered", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme)); main_vbox_container->connect("theme_changed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme)); - main_vbox_container->set_name("Terrains"); + main_vbox_container->set_name(TTR("Terrains")); HSplitContainer *tilemap_tab_terrains = memnew(HSplitContainer); tilemap_tab_terrains->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -3365,7 +3366,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { paint_tool_button->set_toggle_mode(true); paint_tool_button->set_button_group(tool_buttons_group); paint_tool_button->set_pressed(true); - paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", "Paint", Key::D)); + paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", TTR("Paint"), Key::D)); paint_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(paint_tool_button); @@ -3373,7 +3374,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { line_tool_button->set_flat(true); line_tool_button->set_toggle_mode(true); line_tool_button->set_button_group(tool_buttons_group); - line_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/line_tool", "Line", Key::L)); + line_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/line_tool", TTR("Line"), Key::L)); line_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(line_tool_button); @@ -3381,7 +3382,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { rect_tool_button->set_flat(true); rect_tool_button->set_toggle_mode(true); rect_tool_button->set_button_group(tool_buttons_group); - rect_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/rect_tool", "Rect", Key::R)); + rect_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/rect_tool", TTR("Rect"), Key::R)); rect_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(rect_tool_button); @@ -3389,7 +3390,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { bucket_tool_button->set_flat(true); bucket_tool_button->set_toggle_mode(true); bucket_tool_button->set_button_group(tool_buttons_group); - bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", "Bucket", Key::B)); + bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", TTR("Bucket"), Key::B)); bucket_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(bucket_tool_button); @@ -3406,7 +3407,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { picker_button = memnew(Button); picker_button->set_flat(true); picker_button->set_toggle_mode(true); - picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", "Picker", Key::P)); + picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", TTR("Picker"), Key::P)); picker_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport)); tools_settings->add_child(picker_button); @@ -3414,7 +3415,7 @@ TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { erase_button = memnew(Button); erase_button->set_flat(true); erase_button->set_toggle_mode(true); - erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", "Eraser", Key::E)); + erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", TTR("Eraser"), Key::E)); erase_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport)); tools_settings->add_child(erase_button); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index e56541b50d..fcefbb7d06 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -34,6 +34,7 @@ #include "editor/editor_inspector.h" #include "editor/editor_node.h" +#include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" @@ -106,13 +107,13 @@ bool TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get(const StringN void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::NIL, TTR("Atlas"), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); - p_list->push_back(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0," + itos(INT_MAX) + ",1")); - p_list->push_back(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "margins", PROPERTY_HINT_NONE, "suffix:px")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "separation", PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "texture_region_size", PROPERTY_HINT_NONE, "suffix:px")); - p_list->push_back(PropertyInfo(Variant::BOOL, "use_texture_padding", PROPERTY_HINT_NONE, "")); + p_list->push_back(PropertyInfo(Variant::INT, PNAME("id"), PROPERTY_HINT_RANGE, "0," + itos(INT_MAX) + ",1")); + p_list->push_back(PropertyInfo(Variant::STRING, PNAME("name"))); + p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("texture"), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("margins"), PROPERTY_HINT_NONE, "suffix:px")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("separation"))); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("texture_region_size"), PROPERTY_HINT_NONE, "suffix:px")); + p_list->push_back(PropertyInfo(Variant::BOOL, PNAME("use_texture_padding"))); } void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_bind_methods() { @@ -392,11 +393,11 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro if (tiles.size() == 1) { if (tiles.front()->get().alternative == 0) { p_list->push_back(PropertyInfo(Variant::NIL, TTR("Base Tile"), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "atlas_coords")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "size_in_atlas")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("atlas_coords"))); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("size_in_atlas"))); } else { p_list->push_back(PropertyInfo(Variant::NIL, TTR("Alternative Tile"), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); - p_list->push_back(PropertyInfo(Variant::INT, "alternative_id")); + p_list->push_back(PropertyInfo(Variant::INT, PNAME("alternative_id"))); } } else { p_list->push_back(PropertyInfo(Variant::NIL, TTR("Tiles"), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); @@ -413,17 +414,17 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro } if (all_alternatve_id_zero) { - p_list->push_back(PropertyInfo(Variant::NIL, "Animation", PROPERTY_HINT_NONE, "animation_", PROPERTY_USAGE_GROUP)); - p_list->push_back(PropertyInfo(Variant::INT, "animation_columns", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "animation_separation", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_speed", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Frames,animation_frame_")); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Animation", "animation_"), PROPERTY_HINT_NONE, "animation_", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::INT, PNAME("animation_columns"))); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, PNAME("animation_separation"))); + p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("animation_speed"))); + p_list->push_back(PropertyInfo(Variant::INT, PNAME("animation_frames_count"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Frames,animation_frame_")); // Not optimal, but returns value for the first tile. This is similar to what MultiNodeEdit does. if (tile_set_atlas_source->get_tile_animation_frames_count(tiles.front()->get().tile) == 1) { p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_frame_0/duration", PROPERTY_HINT_NONE, "suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY)); } else { for (int i = 0; i < tile_set_atlas_source->get_tile_animation_frames_count(tiles.front()->get().tile); i++) { - p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/duration", i), PROPERTY_HINT_NONE, "suffix:s")); + p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/%s", i, PNAME("duration")), PROPERTY_HINT_NONE, "suffix:s")); } } } @@ -641,9 +642,9 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { // List of editors. // --- Rendering --- - ADD_TILE_DATA_EDITOR_GROUP("Rendering"); + ADD_TILE_DATA_EDITOR_GROUP(TTR("Rendering")); - ADD_TILE_DATA_EDITOR(group, "Texture Origin", "texture_origin"); + ADD_TILE_DATA_EDITOR(group, TTR("Texture Origin"), "texture_origin"); if (!tile_data_editors.has("texture_origin")) { TileDataTextureOriginEditor *tile_data_texture_origin_editor = memnew(TileDataTextureOriginEditor); tile_data_texture_origin_editor->hide(); @@ -653,7 +654,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { tile_data_editors["texture_origin"] = tile_data_texture_origin_editor; } - ADD_TILE_DATA_EDITOR(group, "Modulate", "modulate"); + ADD_TILE_DATA_EDITOR(group, TTR("Modulate"), "modulate"); if (!tile_data_editors.has("modulate")) { TileDataDefaultEditor *tile_data_modulate_editor = memnew(TileDataDefaultEditor()); tile_data_modulate_editor->hide(); @@ -663,7 +664,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { tile_data_editors["modulate"] = tile_data_modulate_editor; } - ADD_TILE_DATA_EDITOR(group, "Z Index", "z_index"); + ADD_TILE_DATA_EDITOR(group, TTR("Z Index"), "z_index"); if (!tile_data_editors.has("z_index")) { TileDataDefaultEditor *tile_data_z_index_editor = memnew(TileDataDefaultEditor()); tile_data_z_index_editor->hide(); @@ -673,7 +674,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { tile_data_editors["z_index"] = tile_data_z_index_editor; } - ADD_TILE_DATA_EDITOR(group, "Y Sort Origin", "y_sort_origin"); + ADD_TILE_DATA_EDITOR(group, TTR("Y Sort Origin"), "y_sort_origin"); if (!tile_data_editors.has("y_sort_origin")) { TileDataYSortEditor *tile_data_y_sort_editor = memnew(TileDataYSortEditor); tile_data_y_sort_editor->hide(); @@ -684,7 +685,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) { - ADD_TILE_DATA_EDITOR(group, vformat("Occlusion Layer %d", i), vformat("occlusion_layer_%d", i)); + ADD_TILE_DATA_EDITOR(group, vformat(TTR("Occlusion Layer %d"), i), vformat("occlusion_layer_%d", i)); if (!tile_data_editors.has(vformat("occlusion_layer_%d", i))) { TileDataOcclusionShapeEditor *tile_data_occlusion_shape_editor = memnew(TileDataOcclusionShapeEditor()); tile_data_occlusion_shape_editor->hide(); @@ -700,7 +701,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // --- Rendering --- - ADD_TILE_DATA_EDITOR(root, "Terrains", "terrain_set"); + ADD_TILE_DATA_EDITOR(root, TTR("Terrains"), "terrain_set"); if (!tile_data_editors.has("terrain_set")) { TileDataTerrainsEditor *tile_data_terrains_editor = memnew(TileDataTerrainsEditor); tile_data_terrains_editor->hide(); @@ -710,7 +711,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // --- Miscellaneous --- - ADD_TILE_DATA_EDITOR(root, "Probability", "probability"); + ADD_TILE_DATA_EDITOR(root, TTR("Probability"), "probability"); if (!tile_data_editors.has("probability")) { TileDataDefaultEditor *tile_data_probability_editor = memnew(TileDataDefaultEditor()); tile_data_probability_editor->hide(); @@ -721,9 +722,9 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // --- Physics --- - ADD_TILE_DATA_EDITOR_GROUP("Physics"); + ADD_TILE_DATA_EDITOR_GROUP(TTR("Physics")); for (int i = 0; i < tile_set->get_physics_layers_count(); i++) { - ADD_TILE_DATA_EDITOR(group, vformat("Physics Layer %d", i), vformat("physics_layer_%d", i)); + ADD_TILE_DATA_EDITOR(group, vformat(TTR("Physics Layer %d"), i), vformat("physics_layer_%d", i)); if (!tile_data_editors.has(vformat("physics_layer_%d", i))) { TileDataCollisionEditor *tile_data_collision_editor = memnew(TileDataCollisionEditor()); tile_data_collision_editor->hide(); @@ -739,9 +740,9 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // --- Navigation --- - ADD_TILE_DATA_EDITOR_GROUP("Navigation"); + ADD_TILE_DATA_EDITOR_GROUP(TTR("Navigation")); for (int i = 0; i < tile_set->get_navigation_layers_count(); i++) { - ADD_TILE_DATA_EDITOR(group, vformat("Navigation Layer %d", i), vformat("navigation_layer_%d", i)); + ADD_TILE_DATA_EDITOR(group, vformat(TTR("Navigation Layer %d"), i), vformat("navigation_layer_%d", i)); if (!tile_data_editors.has(vformat("navigation_layer_%d", i))) { TileDataNavigationEditor *tile_data_navigation_editor = memnew(TileDataNavigationEditor()); tile_data_navigation_editor->hide(); @@ -757,14 +758,14 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // --- Custom Data --- - ADD_TILE_DATA_EDITOR_GROUP("Custom Data"); + ADD_TILE_DATA_EDITOR_GROUP(TTR("Custom Data")); for (int i = 0; i < tile_set->get_custom_data_layers_count(); i++) { String editor_name = vformat("custom_data_%d", i); String prop_name = tile_set->get_custom_data_layer_name(i); Variant::Type prop_type = tile_set->get_custom_data_layer_type(i); if (prop_name.is_empty()) { - ADD_TILE_DATA_EDITOR(group, vformat("Custom Data %d", i), editor_name); + ADD_TILE_DATA_EDITOR(group, vformat(TTR("Custom Data %d"), i), editor_name); } else { ADD_TILE_DATA_EDITOR(group, prop_name, editor_name); } @@ -2414,6 +2415,14 @@ void TileSetAtlasSourceEditor::_notification(int p_what) { } } } break; + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/localize_settings")) { + EditorPropertyNameProcessor::Style style = EditorPropertyNameProcessor::get_singleton()->get_settings_style(); + atlas_source_inspector->set_property_name_style(style); + tile_inspector->set_property_name_style(style); + } + } break; } } @@ -2483,6 +2492,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_inspector->edit(tile_proxy_object); tile_inspector->set_use_folding(true); tile_inspector->connect("property_selected", callable_mp(this, &TileSetAtlasSourceEditor::_inspector_property_selected)); + tile_inspector->set_property_name_style(EditorPropertyNameProcessor::get_singleton()->get_settings_style()); middle_vbox_container->add_child(tile_inspector); tile_inspector_no_tile_selected_label = memnew(Label); @@ -2534,6 +2544,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { atlas_source_inspector->set_v_size_flags(SIZE_EXPAND_FILL); atlas_source_inspector->set_show_categories(true); atlas_source_inspector->edit(atlas_source_proxy_object); + atlas_source_inspector->set_property_name_style(EditorPropertyNameProcessor::get_singleton()->get_settings_style()); middle_vbox_container->add_child(atlas_source_inspector); // -- Right side -- 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 cc276597fa..101ec5f66c 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -32,6 +32,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_property_name_processor.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -362,6 +363,14 @@ void TileSetScenesCollectionSourceEditor::_notification(int p_what) { _update_scenes_list(); _update_action_buttons(); } break; + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/localize_settings")) { + EditorPropertyNameProcessor::Style style = EditorPropertyNameProcessor::get_singleton()->get_settings_style(); + scenes_collection_source_inspector->set_property_name_style(style); + tile_inspector->set_property_name_style(style); + } + } break; } } @@ -503,6 +512,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { scenes_collection_source_inspector = memnew(EditorInspector); scenes_collection_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object); + scenes_collection_source_inspector->set_property_name_style(EditorPropertyNameProcessor::get_singleton()->get_settings_style()); middle_vbox_container->add_child(scenes_collection_source_inspector); // Tile inspector. @@ -519,6 +529,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); tile_inspector->edit(tile_proxy_object); tile_inspector->set_use_folding(true); + tile_inspector->set_property_name_style(EditorPropertyNameProcessor::get_singleton()->get_settings_style()); middle_vbox_container->add_child(tile_inspector); // Scenes list. diff --git a/main/main.cpp b/main/main.cpp index 81f2c101a1..ae3a6d2a94 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1843,7 +1843,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF("display/window/ios/hide_home_indicator", true); GLOBAL_DEF("display/window/ios/hide_status_bar", true); GLOBAL_DEF("display/window/ios/suppress_ui_gesture", true); - GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "input_devices/pointing/ios/touch_delay", PROPERTY_HINT_RANGE, "0,1,0.001"), 0.15); // XR project settings. GLOBAL_DEF_RST_BASIC("xr/openxr/enabled", false); diff --git a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs index 3226ca79e5..6b000cc89b 100644 --- a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs +++ b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs @@ -168,7 +168,9 @@ using Godot.NativeInterop; { var parameter = callback.Parameters[i]; - source.Append(parameter.ToDisplayString()); + AppendRefKind(source, parameter.RefKind); + source.Append(' '); + source.Append(parameter.Type.FullQualifiedNameIncludeGlobal()); source.Append(' '); source.Append(parameter.Name); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index fdd2fed836..641258a26c 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -251,7 +251,7 @@ 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 = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' +static const int OPENGL_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' static const int VULKAN_MIN_SDK_VERSION = 24; static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' @@ -1706,7 +1706,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "gradle_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK)); // Using String instead of int to default to an empty string (no override) with placeholder for instructions (see GH-62465). // This implies doing validation that the string is a proper int. - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_MIN_SDK_VERSION)), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", VULKAN_MIN_SDK_VERSION)), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "gradle_build/target_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_TARGET_SDK_VERSION)), "")); Vector<PluginConfigAndroid> plugins_configs = get_plugins(); @@ -2337,7 +2337,7 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit // Check the min sdk version. String min_sdk_str = p_preset->get("gradle_build/min_sdk"); - int min_sdk_int = DEFAULT_MIN_SDK_VERSION; + int min_sdk_int = VULKAN_MIN_SDK_VERSION; if (!min_sdk_str.is_empty()) { // Empty means no override, nothing to do. if (!gradle_build_enabled) { valid = false; @@ -2350,9 +2350,9 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit err += "\n"; } else { min_sdk_int = min_sdk_str.to_int(); - if (min_sdk_int < DEFAULT_MIN_SDK_VERSION) { + if (min_sdk_int < OPENGL_MIN_SDK_VERSION) { valid = false; - err += vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), DEFAULT_MIN_SDK_VERSION); + err += vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), OPENGL_MIN_SDK_VERSION); err += "\n"; } } @@ -2808,7 +2808,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP String version_name = p_preset->get("version/name"); String min_sdk_version = p_preset->get("gradle_build/min_sdk"); if (!min_sdk_version.is_valid_int()) { - min_sdk_version = itos(DEFAULT_MIN_SDK_VERSION); + min_sdk_version = itos(VULKAN_MIN_SDK_VERSION); } String target_sdk_version = p_preset->get("gradle_build/target_sdk"); if (!target_sdk_version.is_valid_int()) { diff --git a/platform/ios/SCsub b/platform/ios/SCsub index f3925c146f..18ba6617af 100644 --- a/platform/ios/SCsub +++ b/platform/ios/SCsub @@ -17,7 +17,6 @@ ios_lib = [ "display_layer.mm", "godot_app_delegate.m", "godot_view_renderer.mm", - "godot_view_gesture_recognizer.mm", "device_metrics.m", "keyboard_input_view.mm", "key_mapping_ios.mm", diff --git a/platform/ios/godot_view.h b/platform/ios/godot_view.h index 077584baa6..b00ca37ebe 100644 --- a/platform/ios/godot_view.h +++ b/platform/ios/godot_view.h @@ -59,9 +59,4 @@ class String; - (void)stopRendering; - (void)startRendering; -- (void)godotTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; -- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; - @end diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index 4b10f95ab8..fafec79bf6 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -35,7 +35,6 @@ #include "core/string/ustring.h" #import "display_layer.h" #include "display_server_ios.h" -#import "godot_view_gesture_recognizer.h" #import "godot_view_renderer.h" #import <CoreMotion/CoreMotion.h> @@ -60,8 +59,6 @@ static const float earth_gravity = 9.80665; @property(strong, nonatomic) CMMotionManager *motionManager; -@property(strong, nonatomic) GodotViewGestureRecognizer *delayGestureRecognizer; - @end @implementation GodotView @@ -148,10 +145,6 @@ static const float earth_gravity = 9.80665; [self.animationTimer invalidate]; self.animationTimer = nil; } - - if (self.delayGestureRecognizer) { - self.delayGestureRecognizer = nil; - } } - (void)godot_commonInit { @@ -171,11 +164,6 @@ static const float earth_gravity = 9.80665; self.motionManager = nil; } } - - // Initialize delay gesture recognizer - GodotViewGestureRecognizer *gestureRecognizer = [[GodotViewGestureRecognizer alloc] init]; - self.delayGestureRecognizer = gestureRecognizer; - [self addGestureRecognizer:self.delayGestureRecognizer]; } - (void)stopRendering { @@ -347,58 +335,42 @@ static const float earth_gravity = 9.80665; } } -- (void)godotTouchesBegan:(NSSet *)touchesSet withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touchesSet containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); - } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + CGPoint touchPoint = [touch locationInView:self]; + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); } } -- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - CGPoint touchPoint = [touch locationInView:self]; - CGPoint prev_point = [touch previousLocationInView:self]; - CGFloat alt = [touch altitudeAngle]; - CGVector azim = [touch azimuthUnitVectorInView:self]; - DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt)); - } +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + CGPoint touchPoint = [touch locationInView:self]; + CGPoint prev_point = [touch previousLocationInView:self]; + CGFloat alt = [touch altitudeAngle]; + CGVector azim = [touch azimuthUnitVectorInView:self]; + DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt)); } } -- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - [self removeTouch:touch]; - CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); - } +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + [self removeTouch:touch]; + CGPoint touchPoint = [touch locationInView:self]; + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); } } -- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray *tlist = [event.allTouches allObjects]; - for (unsigned int i = 0; i < [tlist count]; i++) { - if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch *touch = [tlist objectAtIndex:i]; - int tid = [self getTouchIDForTouch:touch]; - ERR_FAIL_COND(tid == -1); - DisplayServerIOS::get_singleton()->touches_canceled(tid); - } +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + for (UITouch *touch in touches) { + int tid = [self getTouchIDForTouch:touch]; + ERR_FAIL_COND(tid == -1); + DisplayServerIOS::get_singleton()->touches_canceled(tid); } [self clearTouches]; } diff --git a/platform/ios/godot_view_gesture_recognizer.h b/platform/ios/godot_view_gesture_recognizer.h deleted file mode 100644 index 57bfc75568..0000000000 --- a/platform/ios/godot_view_gesture_recognizer.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************/ -/* godot_view_gesture_recognizer.h */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -// GLViewGestureRecognizer allows iOS gestures to work correctly by -// emulating UIScrollView's UIScrollViewDelayedTouchesBeganGestureRecognizer. -// It catches all gestures incoming to UIView and delays them for 150ms -// (the same value used by UIScrollViewDelayedTouchesBeganGestureRecognizer) -// If touch cancellation or end message is fired it fires delayed -// begin touch immediately as well as last touch signal - -#import <UIKit/UIKit.h> - -@interface GodotViewGestureRecognizer : UIGestureRecognizer - -@property(nonatomic, readonly, assign) NSTimeInterval delayTimeInterval; - -- (instancetype)init; - -@end diff --git a/platform/ios/godot_view_gesture_recognizer.mm b/platform/ios/godot_view_gesture_recognizer.mm deleted file mode 100644 index 9b71228864..0000000000 --- a/platform/ios/godot_view_gesture_recognizer.mm +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************/ -/* godot_view_gesture_recognizer.mm */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -#import "godot_view_gesture_recognizer.h" - -#import "godot_view.h" - -#include "core/config/project_settings.h" - -// Minimum distance for touches to move to fire -// a delay timer before scheduled time. -// Should be the low enough to not cause issues with dragging -// but big enough to allow click to work. -const CGFloat kGLGestureMovementDistance = 0.5; - -@interface GodotViewGestureRecognizer () - -@property(nonatomic, readwrite, assign) NSTimeInterval delayTimeInterval; - -@end - -@interface GodotViewGestureRecognizer () - -// Timer used to delay begin touch message. -// Should work as simple emulation of UIDelayedAction -@property(strong, nonatomic) NSTimer *delayTimer; - -// Delayed touch parameters -@property(strong, nonatomic) NSSet *delayedTouches; -@property(strong, nonatomic) UIEvent *delayedEvent; - -@end - -@implementation GodotViewGestureRecognizer - -- (GodotView *)godotView { - return (GodotView *)self.view; -} - -- (instancetype)init { - self = [super init]; - - self.cancelsTouchesInView = YES; - self.delaysTouchesBegan = YES; - self.delaysTouchesEnded = YES; - self.requiresExclusiveTouchType = NO; - - self.delayTimeInterval = GLOBAL_GET("input_devices/pointing/ios/touch_delay"); - - return self; -} - -- (void)dealloc { - if (self.delayTimer) { - [self.delayTimer invalidate]; - self.delayTimer = nil; - } - - if (self.delayedTouches) { - self.delayedTouches = nil; - } - - if (self.delayedEvent) { - self.delayedEvent = nil; - } -} - -- (void)delayTouches:(NSSet *)touches andEvent:(UIEvent *)event { - [self.delayTimer fire]; - - self.delayedTouches = touches; - self.delayedEvent = event; - - self.delayTimer = [NSTimer - scheduledTimerWithTimeInterval:self.delayTimeInterval - target:self - selector:@selector(fireDelayedTouches:) - userInfo:nil - repeats:NO]; -} - -- (void)fireDelayedTouches:(id)timer { - [self.delayTimer invalidate]; - self.delayTimer = nil; - - if (self.delayedTouches) { - [self.godotView godotTouchesBegan:self.delayedTouches withEvent:self.delayedEvent]; - } - - self.delayedTouches = nil; - self.delayedEvent = nil; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseBegan]; - [self delayTouches:cleared andEvent:event]; - - [super touchesBegan:touches withEvent:event]; -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseMoved]; - - if (self.delayTimer) { - // We should check if movement was significant enough to fire an event - // for dragging to work correctly. - for (UITouch *touch in cleared) { - CGPoint from = [touch locationInView:self.godotView]; - CGPoint to = [touch previousLocationInView:self.godotView]; - CGFloat xDistance = from.x - to.x; - CGFloat yDistance = from.y - to.y; - - CGFloat distance = sqrt(xDistance * xDistance + yDistance * yDistance); - - // Early exit, since one of touches has moved enough to fire a drag event. - if (distance > kGLGestureMovementDistance) { - [self.delayTimer fire]; - [self.godotView godotTouchesMoved:cleared withEvent:event]; - return; - } - } - - return; - } - - [self.godotView godotTouchesMoved:cleared withEvent:event]; - - [super touchesMoved:touches withEvent:event]; -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self.delayTimer fire]; - - NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseEnded]; - [self.godotView godotTouchesEnded:cleared withEvent:event]; - - [super touchesEnded:touches withEvent:event]; -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self.delayTimer fire]; - [self.godotView godotTouchesCancelled:touches withEvent:event]; - - [super touchesCancelled:touches withEvent:event]; -} - -- (NSSet *)copyClearedTouches:(NSSet *)touches phase:(UITouchPhase)phaseToSave { - NSMutableSet *cleared = [touches mutableCopy]; - - for (UITouch *touch in touches) { - if (touch.view != self.view || touch.phase != phaseToSave) { - [cleared removeObject:touch]; - } - } - - return cleared; -} - -@end diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 52a1213a49..1ee6a0b779 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -31,6 +31,7 @@ #include "navigation_agent_2d.h" #include "core/math/geometry_2d.h" +#include "scene/2d/navigation_link_2d.h" #include "scene/resources/world_2d.h" #include "servers/navigation_server_2d.h" @@ -623,6 +624,21 @@ void NavigationAgent2D::update_navigation() { } details[SNAME("owner")] = owner; + + if (waypoint_type == NavigationPathQueryResult2D::PATH_SEGMENT_TYPE_LINK) { + const NavigationLink2D *navlink = Object::cast_to<NavigationLink2D>(owner); + if (navlink) { + Vector2 link_global_start_position = navlink->get_global_start_position(); + Vector2 link_global_end_position = navlink->get_global_end_position(); + if (waypoint.distance_to(link_global_start_position) < waypoint.distance_to(link_global_end_position)) { + details[SNAME("link_entry_position")] = link_global_start_position; + details[SNAME("link_exit_position")] = link_global_end_position; + } else { + details[SNAME("link_entry_position")] = link_global_end_position; + details[SNAME("link_exit_position")] = link_global_start_position; + } + } + } } // Emit a signal for the waypoint diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 26dca40176..8adb7c6305 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -54,6 +54,12 @@ void NavigationLink2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink2D::set_end_position); ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink2D::get_end_position); + ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink2D::set_global_start_position); + ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink2D::get_global_start_position); + + ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink2D::set_global_end_position); + ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink2D::get_global_end_position); + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost); ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost); @@ -271,6 +277,38 @@ void NavigationLink2D::set_end_position(Vector2 p_position) { #endif // DEBUG_ENABLED } +void NavigationLink2D::set_global_start_position(Vector2 p_position) { + if (is_inside_tree()) { + set_start_position(to_local(p_position)); + } else { + set_start_position(p_position); + } +} + +Vector2 NavigationLink2D::get_global_start_position() const { + if (is_inside_tree()) { + return to_global(start_position); + } else { + return start_position; + } +} + +void NavigationLink2D::set_global_end_position(Vector2 p_position) { + if (is_inside_tree()) { + set_end_position(to_local(p_position)); + } else { + set_end_position(p_position); + } +} + +Vector2 NavigationLink2D::get_global_end_position() const { + if (is_inside_tree()) { + return to_global(end_position); + } else { + return end_position; + } +} + void NavigationLink2D::set_enter_cost(real_t p_enter_cost) { ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); if (Math::is_equal_approx(enter_cost, p_enter_cost)) { diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h index 5bf2a72358..8a24d611c9 100644 --- a/scene/2d/navigation_link_2d.h +++ b/scene/2d/navigation_link_2d.h @@ -78,6 +78,12 @@ public: void set_end_position(Vector2 p_position); Vector2 get_end_position() const { return end_position; } + void set_global_start_position(Vector2 p_position); + Vector2 get_global_start_position() const; + + void set_global_end_position(Vector2 p_position); + Vector2 get_global_end_position() const; + void set_enter_cost(real_t p_enter_cost); real_t get_enter_cost() const { return enter_cost; } diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 16f357194e..5b5ad62d64 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -30,6 +30,7 @@ #include "navigation_agent_3d.h" +#include "scene/3d/navigation_link_3d.h" #include "servers/navigation_server_3d.h" void NavigationAgent3D::_bind_methods() { @@ -649,6 +650,21 @@ void NavigationAgent3D::update_navigation() { } details[SNAME("owner")] = owner; + + if (waypoint_type == NavigationPathQueryResult3D::PATH_SEGMENT_TYPE_LINK) { + const NavigationLink3D *navlink = Object::cast_to<NavigationLink3D>(owner); + if (navlink) { + Vector3 link_global_start_position = navlink->get_global_start_position(); + Vector3 link_global_end_position = navlink->get_global_end_position(); + if (waypoint.distance_to(link_global_start_position) < waypoint.distance_to(link_global_end_position)) { + details[SNAME("link_entry_position")] = link_global_start_position; + details[SNAME("link_exit_position")] = link_global_end_position; + } else { + details[SNAME("link_entry_position")] = link_global_end_position; + details[SNAME("link_exit_position")] = link_global_start_position; + } + } + } } // Emit a signal for the waypoint diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp index f47fcfaf51..9c4b8e7905 100644 --- a/scene/3d/navigation_link_3d.cpp +++ b/scene/3d/navigation_link_3d.cpp @@ -163,6 +163,12 @@ void NavigationLink3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink3D::set_end_position); ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink3D::get_end_position); + ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink3D::set_global_start_position); + ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink3D::get_global_start_position); + + ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink3D::set_global_end_position); + ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink3D::get_global_end_position); + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost); ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost); @@ -386,6 +392,38 @@ void NavigationLink3D::set_end_position(Vector3 p_position) { update_configuration_warnings(); } +void NavigationLink3D::set_global_start_position(Vector3 p_position) { + if (is_inside_tree()) { + set_start_position(to_local(p_position)); + } else { + set_start_position(p_position); + } +} + +Vector3 NavigationLink3D::get_global_start_position() const { + if (is_inside_tree()) { + return to_global(start_position); + } else { + return start_position; + } +} + +void NavigationLink3D::set_global_end_position(Vector3 p_position) { + if (is_inside_tree()) { + set_end_position(to_local(p_position)); + } else { + set_end_position(p_position); + } +} + +Vector3 NavigationLink3D::get_global_end_position() const { + if (is_inside_tree()) { + return to_global(end_position); + } else { + return end_position; + } +} + void NavigationLink3D::set_enter_cost(real_t p_enter_cost) { ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); if (Math::is_equal_approx(enter_cost, p_enter_cost)) { diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h index 5c9ec36189..991f45c85d 100644 --- a/scene/3d/navigation_link_3d.h +++ b/scene/3d/navigation_link_3d.h @@ -83,6 +83,12 @@ public: void set_end_position(Vector3 p_position); Vector3 get_end_position() const { return end_position; } + void set_global_start_position(Vector3 p_position); + Vector3 get_global_start_position() const; + + void set_global_end_position(Vector3 p_position); + Vector3 get_global_end_position() const; + void set_enter_cost(real_t p_enter_cost); real_t get_enter_cost() const { return enter_cost; } diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index c0ef71ee4f..b861d7af01 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -86,9 +86,7 @@ int Label::get_line_height(int p_line) const { } } -void Label::_shape() { - bool font_was_dirty = font_dirty; - +bool Label::_shape() { Ref<StyleBox> style = theme_cache.normal_style; int width = (get_size().width - style->get_minimum_size().width); @@ -103,7 +101,7 @@ void Label::_shape() { } const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; - ERR_FAIL_COND(font.is_null()); + ERR_FAIL_COND_V(font.is_null(), true); String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { txt = txt.substr(0, visible_chars); @@ -123,6 +121,7 @@ void Label::_shape() { dirty = false; font_dirty = false; lines_dirty = true; + // Note for future maintainers: forgetting stable width here (e.g., setting it to -1) may fix still undiscovered bugs. } if (lines_dirty) { @@ -135,129 +134,138 @@ void Label::_shape() { Size2i prev_minsize = minsize; minsize = Size2(); + bool can_process_lines = false; if (xl_text.length() == 0) { + can_process_lines = true; lines_dirty = false; - return; - } - - // Don't compute minimum size until width is stable (two shape requests in a row with the same width.) - // This avoids situations in which the initial width is very narrow and the label would break text - // into many very short lines, causing a very tall label that can leave a deformed container. - bool width_stabilized = get_size().width == stable_width; - stable_width = get_size().width; + } else { + // With autowrap on or off with trimming enabled, we won't compute the minimum size until width is stable + // (two shape requests in a row with the same width.) This avoids situations in which the initial width is + // very narrow and the label would break text into many very short lines, causing a very tall label that can + // leave a deformed container. In the remaining case (namely, autowrap off and no trimming), the label is + // free to dictate its own width, something that will be taken advtantage of. + bool can_dictate_width = autowrap_mode == TextServer::AUTOWRAP_OFF && overrun_behavior == TextServer::OVERRUN_NO_TRIMMING; + bool is_width_stable = get_size().width == stable_width; + can_process_lines = can_dictate_width || is_width_stable; + stable_width = get_size().width; + + if (can_process_lines) { + if (lines_dirty) { + BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY; + switch (autowrap_mode) { + case TextServer::AUTOWRAP_WORD_SMART: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_WORD: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_ARBITRARY: + autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_OFF: + break; + } + autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; - // With autowrap off, there's still a point in shaping before width is stable: to contribute a min width. - if (lines_dirty && (width_stabilized || autowrap_mode == TextServer::AUTOWRAP_OFF)) { - BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY; - switch (autowrap_mode) { - case TextServer::AUTOWRAP_WORD_SMART: - autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_WORD: - autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_ARBITRARY: - autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_OFF: - break; - } - autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); + lines_rid.push_back(line); + } + } - PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); - for (int i = 0; i < line_breaks.size(); i = i + 2) { - RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); - lines_rid.push_back(line); - } - } + if (can_dictate_width) { + for (int i = 0; i < lines_rid.size(); i++) { + if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) { + minsize.width = TS->shaped_text_get_size(lines_rid[i]).x; + } + } - if (autowrap_mode == TextServer::AUTOWRAP_OFF) { - for (int i = 0; i < lines_rid.size(); i++) { - if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) { - minsize.width = TS->shaped_text_get_size(lines_rid[i]).x; + width = (minsize.width - style->get_minimum_size().width); } - } - // With autowrap off, by now we already know the width the label will take. - width = (minsize.width - style->get_minimum_size().width); - width_stabilized = true; - } - - if (lines_dirty && width_stabilized) { - BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM; - switch (overrun_behavior) { - case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); - overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); - break; - case TextServer::OVERRUN_TRIM_ELLIPSIS: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); - break; - case TextServer::OVERRUN_TRIM_WORD: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); - break; - case TextServer::OVERRUN_TRIM_CHAR: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - break; - case TextServer::OVERRUN_NO_TRIMMING: - break; - } + if (lines_dirty) { + BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM; + switch (overrun_behavior) { + case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); + overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); + break; + case TextServer::OVERRUN_TRIM_ELLIPSIS: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); + break; + case TextServer::OVERRUN_TRIM_WORD: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); + break; + case TextServer::OVERRUN_TRIM_CHAR: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + break; + case TextServer::OVERRUN_NO_TRIMMING: + break; + } - // Fill after min_size calculation. + // Fill after min_size calculation. - int visible_lines = lines_rid.size(); - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; - } - if (autowrap_mode != TextServer::AUTOWRAP_OFF) { - bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size(); - if (lines_hidden) { - overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS); - } - 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); - } else if (i == (visible_lines - 1)) { + int visible_lines = lines_rid.size(); + if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { + visible_lines = max_lines_visible; + } + if (autowrap_mode != TextServer::AUTOWRAP_OFF) { + bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size(); + if (lines_hidden) { + overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS); + } + 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); + } else if (i == (visible_lines - 1)) { + TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); + } + } + } else if (lines_hidden) { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } - } - } else if (lines_hidden) { - TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); - } - } else { - // Autowrap disabled. - for (int i = 0; i < lines_rid.size(); i++) { - if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - TS->shaped_text_fit_to_width(lines_rid[i], width); - overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE); - TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); - TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS); } else { - TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + // Autowrap disabled. + for (int i = 0; i < lines_rid.size(); i++) { + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { + TS->shaped_text_fit_to_width(lines_rid[i], width); + overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE); + TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS); + } else { + TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + } + } + } + + int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; + for (int64_t i = lines_skipped; i < last_line; i++) { + minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; } - } - } - int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; - for (int64_t i = lines_skipped; i < last_line; i++) { - minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; + lines_dirty = false; + } + } else { + callable_mp(this, &Label::_shape).call_deferred(); } + } - lines_dirty = false; + if (draw_pending) { + queue_redraw(); + draw_pending = false; } - if (minsize != prev_minsize || font_was_dirty) { + if (minsize != prev_minsize) { update_minimum_size(); } - if (!width_stabilized) { - callable_mp(this, &Label::_shape).call_deferred(); - } + return can_process_lines; } inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { @@ -367,10 +375,9 @@ void Label::_notification(int p_what) { } if (dirty || font_dirty || lines_dirty) { - _shape(); - if (lines_dirty) { + if (!_shape()) { // There will be another pass. - queue_redraw(); + draw_pending = true; break; } } @@ -396,7 +403,7 @@ void Label::_notification(int p_what) { style->draw(ci, Rect2(Point2(0, 0), get_size())); float total_h = 0.0; - int visible_lines = 0; + int lines_visible = 0; // Get number of lines to fit to the height. for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { @@ -404,14 +411,14 @@ void Label::_notification(int p_what) { if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { break; } - visible_lines++; + lines_visible++; } - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { + lines_visible = max_lines_visible; } - int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); + int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped); bool trim_chars = (visible_chars >= 0) && (visible_chars_behavior == TextServer::VC_CHARS_AFTER_SHAPING); bool trim_glyphs_ltr = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_LTR) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && !rtl_layout)); bool trim_glyphs_rtl = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_RTL) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && rtl_layout)); @@ -428,7 +435,7 @@ void Label::_notification(int p_what) { total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); int vbegin = 0, vsep = 0; - if (visible_lines > 0) { + if (lines_visible > 0) { switch (vertical_alignment) { case VERTICAL_ALIGNMENT_TOP: { // Nothing. @@ -445,8 +452,8 @@ void Label::_notification(int p_what) { } break; case VERTICAL_ALIGNMENT_FILL: { vbegin = 0; - if (visible_lines > 1) { - vsep = (size.y - (total_h - line_spacing)) / (visible_lines - 1); + if (lines_visible > 1) { + vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); } else { vsep = 0; } @@ -615,6 +622,8 @@ void Label::_notification(int p_what) { } ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing; } + + draw_pending = false; } break; case NOTIFICATION_THEME_CHANGED: { @@ -666,25 +675,25 @@ int Label::get_line_count() const { int Label::get_visible_line_count() const { Ref<StyleBox> style = theme_cache.normal_style; int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; - int visible_lines = 0; + int lines_visible = 0; float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { break; } - visible_lines++; + lines_visible++; } - if (visible_lines > lines_rid.size()) { - visible_lines = lines_rid.size(); + if (lines_visible > lines_rid.size()) { + lines_visible = lines_rid.size(); } - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { + lines_visible = max_lines_visible; } - return visible_lines; + return lines_visible; } void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) { @@ -969,7 +978,7 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_visible_ratio"), &Label::get_visible_ratio); ClassDB::bind_method(D_METHOD("set_lines_skipped", "lines_skipped"), &Label::set_lines_skipped); ClassDB::bind_method(D_METHOD("get_lines_skipped"), &Label::get_lines_skipped); - ClassDB::bind_method(D_METHOD("set_max_lines_visible", "visible_lines"), &Label::set_max_lines_visible); + ClassDB::bind_method(D_METHOD("set_max_lines_visible", "lines_visible"), &Label::set_max_lines_visible); ClassDB::bind_method(D_METHOD("get_max_lines_visible"), &Label::get_max_lines_visible); ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "parser"), &Label::set_structured_text_bidi_override); ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override"), &Label::get_structured_text_bidi_override); diff --git a/scene/gui/label.h b/scene/gui/label.h index 448cb245eb..36b85f7af8 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -50,7 +50,6 @@ private: bool uppercase = false; bool lines_dirty = true; - bool dirty = true; bool font_dirty = true; RID text_rid; @@ -66,6 +65,7 @@ private: float visible_ratio = 1.0; int lines_skipped = 0; int max_lines_visible = -1; + bool draw_pending = false; Ref<LabelSettings> settings; @@ -83,7 +83,7 @@ private: int font_shadow_outline_size; } theme_cache; - void _shape(); + bool _shape(); void _invalidate(); protected: diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index fee0a4a910..d4b2be355e 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -3308,7 +3308,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { PropertyInfo property_info; // Rendering. - p_list->push_back(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Rendering", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < occlusion_layers.size(); i++) { p_list->push_back(PropertyInfo(Variant::INT, vformat("occlusion_layer_%d/light_mask", i), PROPERTY_HINT_LAYERS_2D_RENDER)); @@ -3321,7 +3321,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { } // Physics. - p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Physics", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < physics_layers.size(); i++) { p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/collision_layer", i), PROPERTY_HINT_LAYERS_2D_PHYSICS)); @@ -3341,7 +3341,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { } // Terrains. - p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Terrains", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int terrain_set_index = 0; terrain_set_index < terrain_sets.size(); terrain_set_index++) { p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/mode", terrain_set_index), PROPERTY_HINT_ENUM, "Match Corners and Sides,Match Corners,Match Sides")); p_list->push_back(PropertyInfo(Variant::NIL, vformat("terrain_set_%d/terrains", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, vformat("terrain_set_%d/terrain_", terrain_set_index))); @@ -3352,7 +3352,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { } // Navigation. - p_list->push_back(PropertyInfo(Variant::NIL, "Navigation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < navigation_layers.size(); i++) { p_list->push_back(PropertyInfo(Variant::INT, vformat("navigation_layer_%d/layers", i), PROPERTY_HINT_LAYERS_2D_NAVIGATION)); } @@ -3362,7 +3362,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 1; i < Variant::VARIANT_MAX; i++) { argt += "," + Variant::get_type_name(Variant::Type(i)); } - p_list->push_back(PropertyInfo(Variant::NIL, "Custom data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Custom Data", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < custom_data_layers.size(); i++) { p_list->push_back(PropertyInfo(Variant::STRING, vformat("custom_data_layer_%d/name", i))); p_list->push_back(PropertyInfo(Variant::INT, vformat("custom_data_layer_%d/type", i), PROPERTY_HINT_ENUM, argt)); @@ -3376,10 +3376,10 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { // Tile Proxies. // Note: proxies need to be set after sources are set. - p_list->push_back(PropertyInfo(Variant::NIL, "Tile Proxies", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); - p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/source_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/coords_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/alternative_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Tile Proxies", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/source_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/coords_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/alternative_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); // Patterns. for (unsigned int pattern_index = 0; pattern_index < patterns.size(); pattern_index++) { @@ -4887,9 +4887,9 @@ bool TileSetScenesCollectionSource::_get(const StringName &p_name, Variant &r_re void TileSetScenesCollectionSource::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < scenes_ids.size(); i++) { - p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("scenes/%d/scene", scenes_ids[i]), PROPERTY_HINT_RESOURCE_TYPE, "TileSetScenesCollectionSource")); + p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("scene")), PROPERTY_HINT_RESOURCE_TYPE, "TileSetScenesCollectionSource")); - PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("scenes/%d/display_placeholder", scenes_ids[i])); + PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("display_placeholder"))); if (scenes[scenes_ids[i]].display_placeholder == false) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } @@ -5692,10 +5692,10 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { // Add the groups manually. if (tile_set) { // Occlusion layers. - p_list->push_back(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Rendering", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < occluders.size(); i++) { // occlusion_layer_%d/polygon - property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/polygon", i), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT); + property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT); if (!occluders[i].is_valid()) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } @@ -5703,29 +5703,29 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { } // Physics layers. - p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Physics", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < physics.size(); i++) { - p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/linear_velocity", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/angular_velocity", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/polygons_count", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); + p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/%s", i, PNAME("linear_velocity")), PROPERTY_HINT_NONE)); + p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/%s", i, PNAME("angular_velocity")), PROPERTY_HINT_NONE)); + p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/%s", i, PNAME("polygons_count")), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); for (int j = 0; j < physics[i].polygons.size(); j++) { // physics_layer_%d/points - property_info = PropertyInfo(Variant::ARRAY, vformat("physics_layer_%d/polygon_%d/points", i, j), PROPERTY_HINT_ARRAY_TYPE, "Vector2", PROPERTY_USAGE_DEFAULT); + property_info = PropertyInfo(Variant::ARRAY, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("points")), PROPERTY_HINT_ARRAY_TYPE, "Vector2", PROPERTY_USAGE_DEFAULT); if (physics[i].polygons[j].polygon.is_empty()) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } p_list->push_back(property_info); // physics_layer_%d/polygon_%d/one_way - property_info = PropertyInfo(Variant::BOOL, vformat("physics_layer_%d/polygon_%d/one_way", i, j)); + property_info = PropertyInfo(Variant::BOOL, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("one_way"))); if (physics[i].polygons[j].one_way == false) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } p_list->push_back(property_info); // physics_layer_%d/polygon_%d/one_way_margin - property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/polygon_%d/one_way_margin", i, j)); + property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("one_way_margin"))); if (physics[i].polygons[j].one_way_margin == 1.0) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } @@ -5735,7 +5735,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { // Terrain data if (terrain_set >= 0) { - p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Terrains", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (is_valid_terrain_peering_bit(bit)) { @@ -5749,9 +5749,9 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { } // Navigation layers. - p_list->push_back(PropertyInfo(Variant::NIL, "Navigation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < navigation.size(); i++) { - property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/polygon", i), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT); + property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT); if (!navigation[i].is_valid()) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } @@ -5759,7 +5759,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { } // Custom data layers. - p_list->push_back(PropertyInfo(Variant::NIL, "Custom data", PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Custom Data", "custom_data_"), PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP)); for (int i = 0; i < custom_data.size(); i++) { Variant default_val; Callable::CallError error; diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 668b1dffc3..273bb9ceda 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -152,14 +152,15 @@ void NavigationServer2D::_emit_map_changed(RID p_map) { emit_signal(SNAME("map_changed"), p_map); } -#ifdef DEBUG_ENABLED void NavigationServer2D::set_debug_enabled(bool p_enabled) { NavigationServer3D::get_singleton()->set_debug_enabled(p_enabled); } + bool NavigationServer2D::get_debug_enabled() const { return NavigationServer3D::get_singleton()->get_debug_enabled(); } +#ifdef DEBUG_ENABLED void NavigationServer2D::set_debug_navigation_edge_connection_color(const Color &p_color) { NavigationServer3D::get_singleton()->set_debug_navigation_edge_connection_color(p_color); } @@ -341,6 +342,9 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free); + ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationServer2D::set_debug_enabled); + ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationServer2D::get_debug_enabled); + ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); ADD_SIGNAL(MethodInfo("navigation_debug_changed")); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 153e60272c..ed2e39e53c 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -234,10 +234,10 @@ public: NavigationServer2D(); virtual ~NavigationServer2D(); -#ifdef DEBUG_ENABLED void set_debug_enabled(bool p_enabled); bool get_debug_enabled() const; +#ifdef DEBUG_ENABLED void set_debug_navigation_edge_connection_color(const Color &p_color); Color get_debug_navigation_edge_connection_color() const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index fbe97b9acb..e5cc426708 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -116,6 +116,9 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active); + ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationServer3D::set_debug_enabled); + ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationServer3D::get_debug_enabled); + ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); ADD_SIGNAL(MethodInfo("navigation_debug_changed")); @@ -184,6 +187,24 @@ NavigationServer3D::~NavigationServer3D() { singleton = nullptr; } +void NavigationServer3D::set_debug_enabled(bool p_enabled) { +#ifdef DEBUG_ENABLED + if (debug_enabled != p_enabled) { + debug_dirty = true; + } + + debug_enabled = p_enabled; + + if (debug_dirty) { + call_deferred("_emit_navigation_debug_changed_signal"); + } +#endif // DEBUG_ENABLED +} + +bool NavigationServer3D::get_debug_enabled() const { + return debug_enabled; +} + #ifdef DEBUG_ENABLED void NavigationServer3D::_emit_navigation_debug_changed_signal() { if (debug_dirty) { @@ -533,22 +554,6 @@ bool NavigationServer3D::get_debug_navigation_enable_link_connections_xray() con return debug_navigation_enable_link_connections_xray; } -void NavigationServer3D::set_debug_enabled(bool p_enabled) { - if (debug_enabled != p_enabled) { - debug_dirty = true; - } - - debug_enabled = p_enabled; - - if (debug_dirty) { - call_deferred("_emit_navigation_debug_changed_signal"); - } -} - -bool NavigationServer3D::get_debug_enabled() const { - return debug_enabled; -} - void NavigationServer3D::set_debug_navigation_enable_agent_paths(const bool p_value) { if (debug_navigation_enable_agent_paths != p_value) { debug_dirty = true; diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 79729c55be..05df5ca0fe 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -274,9 +274,13 @@ public: virtual int get_process_info(ProcessInfo p_info) const = 0; -#ifdef DEBUG_ENABLED + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; + private: bool debug_enabled = false; + +#ifdef DEBUG_ENABLED bool debug_dirty = true; void _emit_navigation_debug_changed_signal(); @@ -313,9 +317,6 @@ private: Ref<StandardMaterial3D> debug_navigation_agent_path_point_material; public: - void set_debug_enabled(bool p_enabled); - bool get_debug_enabled() const; - void set_debug_navigation_edge_connection_color(const Color &p_color); Color get_debug_navigation_edge_connection_color() const; diff --git a/servers/navigation_server_3d_dummy.h b/servers/navigation_server_3d_dummy.h index d2f8fe6048..fd9226e59e 100644 --- a/servers/navigation_server_3d_dummy.h +++ b/servers/navigation_server_3d_dummy.h @@ -112,6 +112,8 @@ public: void process(real_t delta_time) override {} NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const override { return NavigationUtilities::PathQueryResult(); } int get_process_info(ProcessInfo p_info) const override { return 0; } + void set_debug_enabled(bool p_enabled) {} + bool get_debug_enabled() const { return false; } }; #endif // NAVIGATION_SERVER_3D_DUMMY_H diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 05b1a8f87a..6e63f2ed9b 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2856,8 +2856,8 @@ RenderingServer::RenderingServer() { } void RenderingServer::init() { - GLOBAL_DEF_RST("rendering/textures/vram_compression/import_s3tc_bptc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_S3TC_BPTC); - GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2_astc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_ETC2_ASTC); + GLOBAL_DEF_RST_BASIC("rendering/textures/vram_compression/import_s3tc_bptc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_S3TC_BPTC); + GLOBAL_DEF_RST_BASIC("rendering/textures/vram_compression/import_etc2_astc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_ETC2_ASTC); GLOBAL_DEF("rendering/textures/lossless_compression/force_png", false); |