summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input/input_map.cpp8
-rw-r--r--doc/classes/CodeEdit.xml70
-rw-r--r--doc/classes/Expression.xml6
-rw-r--r--doc/classes/LineEdit.xml2
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/RenderingServer.xml2
-rw-r--r--doc/classes/TextEdit.xml86
-rw-r--r--doc/classes/Viewport.xml7
-rw-r--r--doc/classes/VisibilityEnabler3D.xml35
-rw-r--r--doc/classes/VisibilityNotifier3D.xml16
-rw-r--r--doc/translations/classes.pot6
-rw-r--r--editor/action_map_editor.cpp2
-rw-r--r--editor/animation_track_editor.cpp4
-rw-r--r--editor/animation_track_editor.h2
-rw-r--r--editor/code_editor.cpp11
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/connections_dialog.cpp4
-rw-r--r--editor/connections_dialog.h2
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp6
-rw-r--r--editor/editor_autoload_settings.h2
-rw-r--r--editor/editor_file_dialog.cpp8
-rw-r--r--editor/editor_file_dialog.h4
-rw-r--r--editor/editor_help.cpp9
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/editor_node.cpp32
-rw-r--r--editor/editor_properties.cpp6
-rw-r--r--editor/editor_properties.h2
-rw-r--r--editor/editor_settings.cpp48
-rw-r--r--editor/editor_settings.h1
-rw-r--r--editor/editor_spin_slider.cpp6
-rw-r--r--editor/editor_spin_slider.h2
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/find_in_files.cpp8
-rw-r--r--editor/find_in_files.h4
-rw-r--r--editor/groups_editor.cpp4
-rw-r--r--editor/import/resource_importer_texture.cpp1
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp2
-rw-r--r--editor/plugins/asset_library_editor_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp12
-rw-r--r--editor/plugins/node_3d_editor_plugin.h6
-rw-r--r--editor/plugins/script_text_editor.cpp4
-rw-r--r--editor/plugins/text_editor.cpp8
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h2
-rw-r--r--editor/project_export.cpp10
-rw-r--r--editor/project_manager.cpp32
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--editor/script_create_dialog.cpp12
-rw-r--r--editor/script_create_dialog.h2
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp22
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h1
-rw-r--r--scene/3d/audio_stream_player_3d.cpp5
-rw-r--r--scene/3d/camera_3d.cpp4
-rw-r--r--scene/3d/visibility_notifier_3d.cpp229
-rw-r--r--scene/3d/visibility_notifier_3d.h53
-rw-r--r--scene/gui/code_edit.cpp259
-rw-r--r--scene/gui/code_edit.h18
-rw-r--r--scene/gui/color_picker.cpp6
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/dialogs.cpp4
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp10
-rw-r--r--scene/gui/file_dialog.h4
-rw-r--r--scene/gui/line_edit.cpp8
-rw-r--r--scene/gui/rich_text_label.cpp132
-rw-r--r--scene/gui/rich_text_label.h3
-rw-r--r--scene/gui/spin_box.cpp8
-rw-r--r--scene/gui/spin_box.h2
-rw-r--r--scene/gui/text_edit.cpp216
-rw-r--r--scene/gui/text_edit.h19
-rw-r--r--scene/gui/tree.cpp6
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/main/scene_tree.cpp2
-rw-r--r--scene/main/viewport.cpp10
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/default_theme/ellipsis.pngbin0 -> 193 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/world_3d.cpp211
-rw-r--r--scene/resources/world_3d.h14
-rw-r--r--servers/rendering/rasterizer_dummy.h15
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp63
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h19
-rw-r--r--servers/rendering/renderer_scene.h1
-rw-r--r--servers/rendering/renderer_scene_cull.cpp45
-rw-r--r--servers/rendering/renderer_scene_cull.h19
-rw-r--r--servers/rendering/renderer_storage.h8
-rw-r--r--servers/rendering/rendering_server_default.cpp1
-rw-r--r--servers/rendering/rendering_server_default.h8
-rw-r--r--servers/rendering_server.h17
93 files changed, 950 insertions, 1034 deletions
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 5b96babe44..c43fd64561 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -353,8 +353,9 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = {
{ "ui_text_scroll_down", TTRC("Scroll Down") },
{ "ui_text_scroll_down.OSX", TTRC("Scroll Down") },
{ "ui_text_select_all", TTRC("Select All") },
- { "ui_text_select_word_under_caret", TTRC("Select Word Under Caret") },
+ { "ui_text_select_word_under_caret", TTRC("Select Word Under Caret") },
{ "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") },
+ { "ui_text_submit", TTRC("Text Submitted") },
{ "ui_graph_duplicate", TTRC("Duplicate Nodes") },
{ "ui_graph_delete", TTRC("Delete Nodes") },
{ "ui_filedialog_up_one_level", TTRC("Go Up One Level") },
@@ -668,6 +669,11 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
inputs.push_back(InputEventKey::create_reference(KEY_MENU));
default_builtin_cache.insert("ui_menu", inputs);
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
+ inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ default_builtin_cache.insert("ui_text_submit", inputs);
+
// ///// UI Graph Shortcuts /////
inputs = List<Ref<InputEvent>>();
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index 15a2e76acc..1250350971 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -86,6 +86,15 @@
Line only denotes if the region should continue until the end of the line or carry over on to the next line. If the end key is blank this is automatically set to [code]true[/code].
</description>
</method>
+ <method name="can_fold_line" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ Returns if the given line is foldable, that is, it has indented lines right below it or a comment / string block.
+ </description>
+ </method>
<method name="cancel_code_completion">
<return type="void">
</return>
@@ -134,6 +143,22 @@
Inserts the selected entry into the text. If [code]replace[/code] is true, any existing text is replaced rather then merged.
</description>
</method>
+ <method name="fold_all_lines">
+ <return type="void">
+ </return>
+ <description>
+ Folds all lines that are possible to be folded (see [method can_fold_line]).
+ </description>
+ </method>
+ <method name="fold_line">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ Folds the given line, if possible (see [method can_fold_line]).
+ </description>
+ </method>
<method name="get_bookmarked_lines" qualifiers="const">
<return type="Array">
</return>
@@ -221,6 +246,13 @@
<description>
</description>
</method>
+ <method name="get_folded_lines" qualifiers="const">
+ <return type="int[]">
+ </return>
+ <description>
+ Return all lines that are current folded.
+ </description>
+ </method>
<method name="get_text_for_code_completion" qualifiers="const">
<return type="String">
</return>
@@ -292,6 +324,15 @@
<description>
</description>
</method>
+ <method name="is_line_folded" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ Returns whether the line at the specified index is folded or not.
+ </description>
+ </method>
<method name="remove_comment_delimiter">
<return type="void">
</return>
@@ -376,6 +417,30 @@
<description>
</description>
</method>
+ <method name="toggle_foldable_line">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ Toggle the folding of the code block at the given line.
+ </description>
+ </method>
+ <method name="unfold_all_lines">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="unfold_line">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ Unfolds all lines that were previously folded.
+ </description>
+ </method>
<method name="update_code_completion_options">
<return type="void">
</return>
@@ -411,6 +476,9 @@
<member name="draw_line_numbers" type="bool" setter="set_draw_line_numbers" getter="is_draw_line_numbers_enabled" default="false">
</member>
<member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" override="true" enum="Control.LayoutDirection" default="2" />
+ <member name="line_folding" type="bool" setter="set_line_folding_enabled" getter="is_line_folding_enabled" default="true">
+ Sets whether line folding is allowed.
+ </member>
<member name="structured_text_bidi_override_options" type="Array" setter="set_structured_text_bidi_override_options" getter="get_structured_text_bidi_override_options" override="true" default="[ ]" />
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" override="true" enum="Control.TextDirection" default="1" />
<member name="zero_pad_line_numbers" type="bool" setter="set_line_numbers_zero_padded" getter="is_line_numbers_zero_padded" default="false">
@@ -500,6 +568,8 @@
</theme_item>
<theme_item name="folded" type="Texture2D">
</theme_item>
+ <theme_item name="folded_eol_icon" type="Texture2D">
+ </theme_item>
<theme_item name="font" type="Font">
</theme_item>
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml
index e41de4c4ed..0781d2ffa2 100644
--- a/doc/classes/Expression.xml
+++ b/doc/classes/Expression.xml
@@ -12,9 +12,9 @@
var expression = Expression.new()
func _ready():
- $LineEdit.connect("text_entered", self, "_on_text_entered")
+ $LineEdit.connect("text_submitted", self, "_on_text_submitted")
- func _on_text_entered(command):
+ func _on_text_submitted(command):
var error = expression.parse(command)
if error != OK:
print(expression.get_error_text())
@@ -28,7 +28,7 @@
public override void _Ready()
{
- GetNode("LineEdit").Connect("text_entered", this, nameof(OnTextEntered));
+ GetNode("LineEdit").Connect("text_submitted", this, nameof(OnTextEntered));
}
private void OnTextEntered(string command)
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 7adf19632e..e11ae7969a 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -248,7 +248,7 @@
Emitted when the text changes.
</description>
</signal>
- <signal name="text_entered">
+ <signal name="text_submitted">
<argument index="0" name="new_text" type="String">
</argument>
<description>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 757f0691bf..35656d170b 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -739,6 +739,8 @@
If no selection is currently active, selects the word currently under the caret in text fields. If a selection is currently active, deselects the current selection.
[b]Note:[/b] Currently, this is only implemented in [TextEdit], not [LineEdit].
</member>
+ <member name="input/ui_text_submit" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_text_toggle_insert_mode" type="Dictionary" setter="" getter="">
</member>
<member name="input/ui_undo" type="Dictionary" setter="" getter="">
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 9b9644093f..300108ff77 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -3702,7 +3702,7 @@
</constant>
<constant name="INSTANCE_OCCLUDER" value="11" enum="InstanceType">
</constant>
- <constant name="INSTANCE_MAX" value="12" enum="InstanceType">
+ <constant name="INSTANCE_MAX" value="13" enum="InstanceType">
Represents the size of the [enum InstanceType] enum.
</constant>
<constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 74811318dc..2d6a052fe3 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -18,15 +18,6 @@
<description>
</description>
</method>
- <method name="can_fold" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Returns if the given line is foldable, that is, it has indented lines right below it.
- </description>
- </method>
<method name="center_viewport_to_cursor">
<return type="void">
</return>
@@ -95,7 +86,7 @@
<description>
Moves the cursor at the specified [code]line[/code] index.
If [code]adjust_viewport[/code] is set to [code]true[/code], the viewport will center at the cursor position after the move occurs.
- If [code]can_be_hidden[/code] is set to [code]true[/code], the specified [code]line[/code] can be hidden using [method set_line_as_hidden].
+ If [code]can_be_hidden[/code] is set to [code]true[/code], the specified [code]line[/code] can be hidden.
</description>
</method>
<method name="cut">
@@ -112,22 +103,6 @@
Deselects the current selection.
</description>
</method>
- <method name="fold_all_lines">
- <return type="void">
- </return>
- <description>
- Folds all lines that are possible to be folded (see [method can_fold]).
- </description>
- </method>
- <method name="fold_line">
- <return type="void">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Folds the given line, if possible (see [method can_fold]).
- </description>
- </method>
<method name="get_caret_draw_pos" qualifiers="const">
<return type="Vector2">
</return>
@@ -329,15 +304,6 @@
Returns [code]true[/code] if the caret is visible on the screen.
</description>
</method>
- <method name="is_folded" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Returns whether the line at the specified index is folded or not.
- </description>
- </method>
<method name="is_gutter_clickable" qualifiers="const">
<return type="bool">
</return>
@@ -372,15 +338,6 @@
<description>
</description>
</method>
- <method name="is_line_hidden" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Returns whether the line at the specified index is hidden or not.
- </description>
- </method>
<method name="is_selection_active" qualifiers="const">
<return type="bool">
</return>
@@ -560,17 +517,6 @@
Sets the text for a specific line.
</description>
</method>
- <method name="set_line_as_hidden">
- <return type="void">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <argument index="1" name="enable" type="bool">
- </argument>
- <description>
- If [code]true[/code], hides the line of the specified index.
- </description>
- </method>
<method name="set_line_background_color">
<return type="void">
</return>
@@ -665,15 +611,6 @@
<description>
</description>
</method>
- <method name="toggle_fold_line">
- <return type="void">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Toggle the folding of the code block at the given line.
- </description>
- </method>
<method name="undo">
<return type="void">
</return>
@@ -681,22 +618,6 @@
Perform undo operation.
</description>
</method>
- <method name="unfold_line">
- <return type="void">
- </return>
- <argument index="0" name="line" type="int">
- </argument>
- <description>
- Unfolds the given line, if folded.
- </description>
- </method>
- <method name="unhide_all_lines">
- <return type="void">
- </return>
- <description>
- Unhide all lines that were previously set to hidden by [method set_line_as_hidden].
- </description>
- </method>
</methods>
<members>
<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled" default="false">
@@ -730,9 +651,6 @@
If [code]true[/code], the "tab" character will have a visible representation.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
- <member name="hiding_enabled" type="bool" setter="set_hiding_enabled" getter="is_hiding_enabled" default="false">
- If [code]true[/code], all lines that have been set to hidden by [method set_line_as_hidden], will not be visible.
- </member>
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled" default="false">
If [code]true[/code], all occurrences of the selected text will be highlighted.
</member>
@@ -972,8 +890,6 @@
</theme_item>
<theme_item name="caret_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
</theme_item>
- <theme_item name="code_folding_color" type="Color" default="Color( 0.8, 0.8, 0.8, 0.8 )">
- </theme_item>
<theme_item name="current_line_color" type="Color" default="Color( 0.25, 0.25, 0.26, 0.8 )">
Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled.
</theme_item>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 96d63b27ad..292be34a0d 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -179,13 +179,6 @@
<description>
</description>
</method>
- <method name="update_worlds">
- <return type="void">
- </return>
- <description>
- Forces update of the 2D and 3D worlds.
- </description>
- </method>
<method name="warp_mouse">
<return type="void">
</return>
diff --git a/doc/classes/VisibilityEnabler3D.xml b/doc/classes/VisibilityEnabler3D.xml
index d78ebb55f2..4614859a44 100644
--- a/doc/classes/VisibilityEnabler3D.xml
+++ b/doc/classes/VisibilityEnabler3D.xml
@@ -12,44 +12,19 @@
<tutorials>
</tutorials>
<methods>
- <method name="is_enabler_enabled" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="enabler" type="int" enum="VisibilityEnabler3D.Enabler">
- </argument>
- <description>
- Returns whether the enabler identified by given [enum Enabler] constant is active.
- </description>
- </method>
- <method name="set_enabler">
- <return type="void">
- </return>
- <argument index="0" name="enabler" type="int" enum="VisibilityEnabler3D.Enabler">
- </argument>
- <argument index="1" name="enabled" type="bool">
- </argument>
- <description>
- Sets active state of the enabler identified by given [enum Enabler] constant.
- </description>
- </method>
</methods>
<members>
- <member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled" default="true">
- If [code]true[/code], [RigidBody3D] nodes will be paused.
+ <member name="enable_mode" type="int" setter="set_enable_mode" getter="get_enable_mode" enum="VisibilityEnabler3D.EnableMode" default="0">
</member>
- <member name="pause_animations" type="bool" setter="set_enabler" getter="is_enabler_enabled" default="true">
- If [code]true[/code], [AnimationPlayer] nodes will be paused.
+ <member name="enable_node_path" type="NodePath" setter="set_enable_node_path" getter="get_enable_node_path" default="NodePath(&quot;..&quot;)">
</member>
</members>
<constants>
- <constant name="ENABLER_PAUSE_ANIMATIONS" value="0" enum="Enabler">
- This enabler will pause [AnimationPlayer] nodes.
+ <constant name="ENABLE_MODE_INHERIT" value="0" enum="EnableMode">
</constant>
- <constant name="ENABLER_FREEZE_BODIES" value="1" enum="Enabler">
- This enabler will freeze [RigidBody3D] nodes.
+ <constant name="ENABLE_MODE_ALWAYS" value="1" enum="EnableMode">
</constant>
- <constant name="ENABLER_MAX" value="2" enum="Enabler">
- Represents the size of the [enum Enabler] enum.
+ <constant name="ENABLE_MODE_WHEN_PAUSED" value="2" enum="EnableMode">
</constant>
</constants>
</class>
diff --git a/doc/classes/VisibilityNotifier3D.xml b/doc/classes/VisibilityNotifier3D.xml
index e5d3116612..bd6c03ea20 100644
--- a/doc/classes/VisibilityNotifier3D.xml
+++ b/doc/classes/VisibilityNotifier3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisibilityNotifier3D" inherits="Node3D" version="4.0">
+<class name="VisibilityNotifier3D" inherits="VisualInstance3D" version="4.0">
<brief_description>
Detects approximately when the node is visible on screen.
</brief_description>
@@ -26,20 +26,6 @@
</member>
</members>
<signals>
- <signal name="camera_entered">
- <argument index="0" name="camera" type="Camera3D">
- </argument>
- <description>
- Emitted when the VisibilityNotifier3D enters a [Camera3D]'s view.
- </description>
- </signal>
- <signal name="camera_exited">
- <argument index="0" name="camera" type="Camera3D">
- </argument>
- <description>
- Emitted when the VisibilityNotifier3D exits a [Camera3D]'s view.
- </description>
- </signal>
<signal name="screen_entered">
<description>
Emitted when the VisibilityNotifier3D enters the screen.
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index d12fa78b0e..f138276364 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -20685,9 +20685,9 @@ msgid ""
"onready var expression = Expression.new()\n"
"\n"
"func _ready():\n"
-" $LineEdit.connect(\"text_entered\", self, \"_on_text_entered\")\n"
+" $LineEdit.connect(\"text_submitted\", self, \"_on_text_submitted\")\n"
"\n"
-"func _on_text_entered(command):\n"
+"func _on_text_submitted(command):\n"
" var error = expression.parse(command, [])\n"
" if error != OK:\n"
" print(expression.get_error_text())\n"
@@ -33187,7 +33187,7 @@ msgid ""
"Examples:\n"
"[codeblock]\n"
"connect(\"pressed\", self, \"_on_Button_pressed\") # BaseButton signal\n"
-"connect(\"text_entered\", self, \"_on_LineEdit_text_entered\") # LineEdit "
+"connect(\"text_submitted\", self, \"_on_LineEdit_text_submitted\") # LineEdit "
"signal\n"
"connect(\"hit\", self, \"_on_Player_hit\", [ weapon_type, damage ]) # User-"
"defined signal\n"
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index cc07d589c5..b0b79ca069 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -1106,7 +1106,7 @@ ActionMapEditor::ActionMapEditor() {
add_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
add_edit->set_placeholder(TTR("Add New Action"));
add_edit->set_clear_button_enabled(true);
- add_edit->connect("text_entered", callable_mp(this, &ActionMapEditor::_add_action));
+ add_edit->connect("text_submitted", callable_mp(this, &ActionMapEditor::_add_action));
add_hbox->add_child(add_edit);
Button *add_button = memnew(Button);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index b26b5ce595..28453eb41d 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -2380,7 +2380,7 @@ void AnimationTrackEdit::_zoom_changed() {
play_position->update();
}
-void AnimationTrackEdit::_path_entered(const String &p_text) {
+void AnimationTrackEdit::_path_submitted(const String &p_text) {
undo_redo->create_action(TTR("Change Track Path"));
undo_redo->add_do_method(animation.ptr(), "track_set_path", track, p_text);
undo_redo->add_undo_method(animation.ptr(), "track_set_path", track, animation->track_get_path(track));
@@ -2755,7 +2755,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
path = memnew(LineEdit);
path_popup->add_child(path);
path->set_anchors_and_offsets_preset(PRESET_WIDE);
- path->connect("text_entered", callable_mp(this, &AnimationTrackEdit::_path_entered));
+ path->connect("text_submitted", callable_mp(this, &AnimationTrackEdit::_path_submitted));
}
path->set_text(animation->track_get_path(track));
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index d083235c68..6d977e5a3f 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -177,7 +177,7 @@ class AnimationTrackEdit : public Control {
void _menu_selected(int p_index);
- void _path_entered(const String &p_text);
+ void _path_submitted(const String &p_text);
void _play_position_draw();
bool _is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 7b96858ec7..807a45eb32 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -539,7 +539,7 @@ void FindReplaceBar::_search_text_changed(const String &p_text) {
search_current();
}
-void FindReplaceBar::_search_text_entered(const String &p_text) {
+void FindReplaceBar::_search_text_submitted(const String &p_text) {
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
search_prev();
} else {
@@ -547,7 +547,7 @@ void FindReplaceBar::_search_text_entered(const String &p_text) {
}
}
-void FindReplaceBar::_replace_text_entered(const String &p_text) {
+void FindReplaceBar::_replace_text_submitted(const String &p_text) {
if (selection_only->is_pressed() && text_editor->is_selection_active()) {
_replace_all();
_hide_bar();
@@ -643,7 +643,7 @@ FindReplaceBar::FindReplaceBar() {
vbc_lineedit->add_child(search_text);
search_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
search_text->connect("text_changed", callable_mp(this, &FindReplaceBar::_search_text_changed));
- search_text->connect("text_entered", callable_mp(this, &FindReplaceBar::_search_text_entered));
+ search_text->connect("text_submitted", callable_mp(this, &FindReplaceBar::_search_text_submitted));
matches_label = memnew(Label);
hbc_button_search->add_child(matches_label);
@@ -677,7 +677,7 @@ FindReplaceBar::FindReplaceBar() {
replace_text = memnew(LineEdit);
vbc_lineedit->add_child(replace_text);
replace_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- replace_text->connect("text_entered", callable_mp(this, &FindReplaceBar::_replace_text_entered));
+ replace_text->connect("text_submitted", callable_mp(this, &FindReplaceBar::_replace_text_submitted));
replace = memnew(Button);
hbc_button_replace->add_child(replace);
@@ -940,7 +940,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_draw_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers"));
text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/appearance/line_numbers_zero_padded"));
text_editor->set_draw_bookmarks_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/show_bookmark_gutter"));
- text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
+ text_editor->set_line_folding_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
text_editor->set_wrap_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/word_wrap"));
text_editor->set_show_line_length_guidelines(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guidelines"));
@@ -1502,6 +1502,7 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) {
void CodeTextEditor::goto_error() {
if (error->get_text() != "") {
+ text_editor->unfold_line(error_line);
text_editor->cursor_set_line(error_line);
text_editor->cursor_set_column(error_column);
text_editor->center_viewport_to_cursor();
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 9fc659b611..f368305e85 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -99,8 +99,8 @@ class FindReplaceBar : public HBoxContainer {
void _editor_text_changed();
void _search_options_changed(bool p_pressed);
void _search_text_changed(const String &p_text);
- void _search_text_entered(const String &p_text);
- void _replace_text_entered(const String &p_text);
+ void _search_text_submitted(const String &p_text);
+ void _replace_text_submitted(const String &p_text);
void _update_size();
protected:
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index a17b1aec10..de6407da73 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -146,7 +146,7 @@ void ConnectDialog::_item_activated() {
_ok_pressed(); // From AcceptDialog.
}
-void ConnectDialog::_text_entered(const String &p_text) {
+void ConnectDialog::_text_submitted(const String &p_text) {
_ok_pressed(); // From AcceptDialog.
}
@@ -471,7 +471,7 @@ ConnectDialog::ConnectDialog() {
dst_method = memnew(LineEdit);
dst_method->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- dst_method->connect("text_entered", callable_mp(this, &ConnectDialog::_text_entered));
+ dst_method->connect("text_submitted", callable_mp(this, &ConnectDialog::_text_submitted));
dstm_hb->add_child(dst_method);
advanced = memnew(CheckButton);
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 18feba0a61..b9911c1cc5 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -105,7 +105,7 @@ private:
void ok_pressed() override;
void _cancel_pressed();
void _item_activated();
- void _text_entered(const String &_text);
+ void _text_submitted(const String &_text);
void _tree_node_selected();
void _add_bind();
void _remove_bind();
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 13296e2f23..e08334c00e 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -782,7 +782,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
set_v_size_flags(SIZE_EXPAND_FILL);
track_name = memnew(LineEdit);
- track_name->connect("text_entered", callable_mp(this, &EditorAudioBus::_name_changed));
+ track_name->connect("text_submitted", callable_mp(this, &EditorAudioBus::_name_changed));
track_name->connect("focus_exited", callable_mp(this, &EditorAudioBus::_name_focus_exit));
vb->add_child(track_name);
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 1a09b1ac7b..304c2fe532 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -327,7 +327,7 @@ void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
add_autoload->set_disabled(false);
}
-void EditorAutoloadSettings::_autoload_text_entered(const String p_name) {
+void EditorAutoloadSettings::_autoload_text_submitted(const String p_name) {
if (autoload_add_path->get_text() != "" && _autoload_name_is_valid(p_name, nullptr)) {
_autoload_add();
}
@@ -859,7 +859,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
autoload_add_name = memnew(LineEdit);
autoload_add_name->set_h_size_flags(SIZE_EXPAND_FILL);
- autoload_add_name->connect("text_entered", callable_mp(this, &EditorAutoloadSettings::_autoload_text_entered));
+ autoload_add_name->connect("text_submitted", callable_mp(this, &EditorAutoloadSettings::_autoload_text_submitted));
autoload_add_name->connect("text_changed", callable_mp(this, &EditorAutoloadSettings::_autoload_text_changed));
hbc->add_child(autoload_add_name);
@@ -916,7 +916,7 @@ EditorAutoloadSettings::~EditorAutoloadSettings() {
void EditorAutoloadSettings::_set_autoload_add_path(const String &p_text) {
autoload_add_path->set_text(p_text);
- autoload_add_path->emit_signal("text_entered", p_text);
+ autoload_add_path->emit_signal("text_submitted", p_text);
}
void EditorAutoloadSettings::_browse_autoload_add_path() {
diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h
index 762457463c..b709728856 100644
--- a/editor/editor_autoload_settings.h
+++ b/editor/editor_autoload_settings.h
@@ -81,7 +81,7 @@ class EditorAutoloadSettings : public VBoxContainer {
void _autoload_button_pressed(Object *p_item, int p_column, int p_button);
void _autoload_activated();
void _autoload_path_text_changed(const String p_path);
- void _autoload_text_entered(const String p_name);
+ void _autoload_text_submitted(const String p_name);
void _autoload_text_changed(const String p_name);
void _autoload_open(const String &fpath);
void _autoload_file_callback(const String &p_path);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 991d76ce72..f3cee7576d 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -230,14 +230,14 @@ void EditorFileDialog::update_dir() {
}
}
-void EditorFileDialog::_dir_entered(String p_dir) {
+void EditorFileDialog::_dir_submitted(String p_dir) {
dir_access->change_dir(p_dir);
invalidate();
update_dir();
_push_history();
}
-void EditorFileDialog::_file_entered(const String &p_file) {
+void EditorFileDialog::_file_submitted(const String &p_file) {
_action_pressed();
}
@@ -1676,8 +1676,8 @@ EditorFileDialog::EditorFileDialog() {
item_list->connect("multi_selected", callable_mp(this, &EditorFileDialog::_multi_selected), varray(), CONNECT_DEFERRED);
item_list->connect("item_activated", callable_mp(this, &EditorFileDialog::_item_dc_selected), varray());
item_list->connect("nothing_selected", callable_mp(this, &EditorFileDialog::_items_clear_selection));
- dir->connect("text_entered", callable_mp(this, &EditorFileDialog::_dir_entered));
- file->connect("text_entered", callable_mp(this, &EditorFileDialog::_file_entered));
+ dir->connect("text_submitted", callable_mp(this, &EditorFileDialog::_dir_submitted));
+ file->connect("text_submitted", callable_mp(this, &EditorFileDialog::_file_submitted));
filter->connect("item_selected", callable_mp(this, &EditorFileDialog::_filter_selected));
confirm_save = memnew(ConfirmationDialog);
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index f7879838d4..d789956a3e 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -167,8 +167,8 @@ private:
void _item_menu_id_pressed(int p_option);
void _select_drive(int p_idx);
- void _dir_entered(String p_dir);
- void _file_entered(const String &p_file);
+ void _dir_submitted(String p_dir);
+ void _file_submitted(const String &p_file);
void _action_pressed();
void _save_confirm_pressed();
void _cancel_pressed();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 9361981db6..7365e8fd7d 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1761,7 +1761,7 @@ FindBar::FindBar() {
search_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
search_text->set_h_size_flags(SIZE_EXPAND_FILL);
search_text->connect("text_changed", callable_mp(this, &FindBar::_search_text_changed));
- search_text->connect("text_entered", callable_mp(this, &FindBar::_search_text_entered));
+ search_text->connect("text_submitted", callable_mp(this, &FindBar::_search_text_submitted));
matches_label = memnew(Label);
add_child(matches_label);
@@ -1849,9 +1849,6 @@ bool FindBar::_search(bool p_search_previous) {
bool keep = prev_search == stext;
bool ret = rich_text_label->search(stext, keep, p_search_previous);
- if (!ret) {
- ret = rich_text_label->search(stext, false, p_search_previous);
- }
prev_search = stext;
@@ -1878,7 +1875,7 @@ void FindBar::_update_results_count() {
int from_pos = 0;
while (true) {
- int pos = full_text.find(searched, from_pos);
+ int pos = full_text.findn(searched, from_pos);
if (pos == -1) {
break;
}
@@ -1935,7 +1932,7 @@ void FindBar::_search_text_changed(const String &p_text) {
search_next();
}
-void FindBar::_search_text_entered(const String &p_text) {
+void FindBar::_search_text_submitted(const String &p_text) {
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
search_prev();
} else {
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 65e20f060c..69bb72c52d 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -61,7 +61,7 @@ class FindBar : public HBoxContainer {
void _hide_bar();
void _search_text_changed(const String &p_text);
- void _search_text_entered(const String &p_text);
+ void _search_text_submitted(const String &p_text);
void _update_results_count();
void _update_matches_label();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b6df9f6088..b6264af9eb 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5689,36 +5689,10 @@ EditorNode::EditorNode() {
int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
switch (display_scale) {
- case 0: {
+ case 0:
// Try applying a suitable display scale automatically.
- // The code below is adapted in `editor/editor_settings.cpp` and `editor/project_manager.cpp`.
- // Make sure to update those when modifying the code below.
-#ifdef OSX_ENABLED
- editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
-#else
- const int screen = DisplayServer::get_singleton()->window_get_current_screen();
- // Use the smallest dimension to use a correct display scale on portait displays.
- const int smallest_dimension = MIN(DisplayServer::get_singleton()->screen_get_size(screen).x, DisplayServer::get_singleton()->screen_get_size(screen).y);
- float scale;
- if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && smallest_dimension >= 1400) {
- // hiDPI display.
- scale = 2.0;
- } else if (smallest_dimension >= 1700) {
- // Likely a hiDPI display, but we aren't certain due to the returned DPI.
- // Use an intermediate scale to handle this situation.
- scale = 1.5;
- } else if (smallest_dimension <= 800) {
- // Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
- // Icons won't look great, but this is better than having editor elements overflow from its window.
- scale = 0.75;
- } else {
- scale = 1.0;
- }
-
- editor_set_scale(scale);
-#endif
- } break;
-
+ editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
+ break;
case 1:
editor_set_scale(0.75);
break;
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index fd3cf662a9..3feeaec070 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -51,7 +51,7 @@ EditorPropertyNil::EditorPropertyNil() {
///////////////////// TEXT /////////////////////////
-void EditorPropertyText::_text_entered(const String &p_string) {
+void EditorPropertyText::_text_submitted(const String &p_string) {
if (updating) {
return;
}
@@ -100,7 +100,7 @@ EditorPropertyText::EditorPropertyText() {
add_child(text);
add_focusable(text);
text->connect("text_changed", callable_mp(this, &EditorPropertyText::_text_changed));
- text->connect("text_entered", callable_mp(this, &EditorPropertyText::_text_entered));
+ text->connect("text_submitted", callable_mp(this, &EditorPropertyText::_text_submitted));
string_name = false;
updating = false;
@@ -297,7 +297,7 @@ EditorPropertyPath::EditorPropertyPath() {
path = memnew(LineEdit);
path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
path_hb->add_child(path);
- path->connect("text_entered", callable_mp(this, &EditorPropertyPath::_path_selected));
+ path->connect("text_submitted", callable_mp(this, &EditorPropertyPath::_path_selected));
path->connect("focus_exited", callable_mp(this, &EditorPropertyPath::_path_focus_exited));
path->set_h_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 121848d936..dcde7dda3d 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -56,7 +56,7 @@ class EditorPropertyText : public EditorProperty {
bool updating;
bool string_name;
void _text_changed(const String &p_string);
- void _text_entered(const String &p_string);
+ void _text_submitted(const String &p_string);
protected:
static void _bind_methods();
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index d81c94bd35..df269606ad 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -373,30 +373,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Editor
_initial_set("interface/editor/display_scale", 0);
// Display what the Auto display scale setting effectively corresponds to.
- // The code below is adapted in `editor/editor_node.cpp` and `editor/project_manager.cpp`.
- // Make sure to update those when modifying the code below.
-#ifdef OSX_ENABLED
- float scale = DisplayServer::get_singleton()->screen_get_max_scale();
-#else
- const int screen = DisplayServer::get_singleton()->window_get_current_screen();
- // Use the smallest dimension to use a correct display scale on portait displays.
- const int smallest_dimension = MIN(DisplayServer::get_singleton()->screen_get_size(screen).x, DisplayServer::get_singleton()->screen_get_size(screen).y);
- float scale;
- if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && smallest_dimension >= 1400) {
- // hiDPI display.
- scale = 2.0;
- } else if (smallest_dimension <= 1700) {
- // Likely a hiDPI display, but we aren't certain due to the returned DPI.
- // Use an intermediate scale to handle this situation.
- scale = 1.5;
- } else if (smallest_dimension <= 800) {
- // Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
- // Icons won't look great, but this is better than having editor elements overflow from its window.
- scale = 0.75;
- } else {
- scale = 1.0;
- }
-#endif
+ float scale = get_auto_display_scale();
hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, vformat("Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom", Math::round(scale * 100)), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/custom_display_scale", 1.0f);
hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::FLOAT, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
@@ -1447,6 +1424,29 @@ String EditorSettings::get_editor_layouts_config() const {
return EditorPaths::get_singleton()->get_config_dir().plus_file("editor_layouts.cfg");
}
+float EditorSettings::get_auto_display_scale() const {
+#ifdef OSX_ENABLED
+ return DisplayServer::get_singleton()->screen_get_max_scale();
+#else
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
+ // Use the smallest dimension to use a correct display scale on portait displays.
+ const int smallest_dimension = MIN(DisplayServer::get_singleton()->screen_get_size(screen).x, DisplayServer::get_singleton()->screen_get_size(screen).y);
+ if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && smallest_dimension >= 1400) {
+ // hiDPI display.
+ return 2.0;
+ } else if (smallest_dimension >= 1700) {
+ // Likely a hiDPI display, but we aren't certain due to the returned DPI.
+ // Use an intermediate scale to handle this situation.
+ return 1.5;
+ } else if (smallest_dimension <= 800) {
+ // Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
+ // Icons won't look great, but this is better than having editor elements overflow from its window.
+ return 0.75;
+ }
+ return 1.0;
+#endif
+}
+
// Shortcuts
void EditorSettings::add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut) {
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index d6a9a9d1b9..3a28c18b27 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -174,6 +174,7 @@ public:
Vector<String> get_script_templates(const String &p_extension, const String &p_custom_path = String());
String get_editor_layouts_config() const;
+ float get_auto_display_scale() const;
void add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut);
bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 657dcfa760..4f0d75ecce 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -386,8 +386,8 @@ void EditorSpinSlider::_evaluate_input_text() {
set_value(v);
}
-//text_entered signal
-void EditorSpinSlider::_value_input_entered(const String &p_text) {
+//text_submitted signal
+void EditorSpinSlider::_value_input_submitted(const String &p_text) {
value_input_just_closed = true;
value_input_popup->hide();
}
@@ -510,7 +510,7 @@ EditorSpinSlider::EditorSpinSlider() {
value_input_popup->set_wrap_controls(true);
value_input->set_anchors_and_offsets_preset(PRESET_WIDE);
value_input_popup->connect("popup_hide", callable_mp(this, &EditorSpinSlider::_value_input_closed));
- value_input->connect("text_entered", callable_mp(this, &EditorSpinSlider::_value_input_entered));
+ value_input->connect("text_submitted", callable_mp(this, &EditorSpinSlider::_value_input_submitted));
value_input->connect("focus_exited", callable_mp(this, &EditorSpinSlider::_value_focus_exited));
value_input_just_closed = false;
hide_slider = false;
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index 248a13f7b6..50d04c9583 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -68,7 +68,7 @@ class EditorSpinSlider : public Range {
void _grabber_gui_input(const Ref<InputEvent> &p_event);
void _value_input_closed();
- void _value_input_entered(const String &);
+ void _value_input_submitted(const String &);
void _value_focus_exited();
bool hide_slider;
bool flat;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 46bb6a1632..fe1fa9f9d6 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -365,7 +365,7 @@ void FileSystemDock::_notification(int p_what) {
file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option));
tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option));
- current_path->connect("text_entered", callable_mp(this, &FileSystemDock::_navigate_to_path), make_binds(false));
+ current_path->connect("text_submitted", callable_mp(this, &FileSystemDock::_navigate_to_path), make_binds(false));
always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders"));
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 17d24a295c..c29b5d5906 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -311,7 +311,7 @@ FindInFilesDialog::FindInFilesDialog() {
_search_text_line_edit = memnew(LineEdit);
_search_text_line_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
_search_text_line_edit->connect("text_changed", callable_mp(this, &FindInFilesDialog::_on_search_text_modified));
- _search_text_line_edit->connect("text_entered", callable_mp(this, &FindInFilesDialog::_on_search_text_entered));
+ _search_text_line_edit->connect("text_submitted", callable_mp(this, &FindInFilesDialog::_on_search_text_submitted));
gc->add_child(_search_text_line_edit);
_replace_label = memnew(Label);
@@ -321,7 +321,7 @@ FindInFilesDialog::FindInFilesDialog() {
_replace_text_line_edit = memnew(LineEdit);
_replace_text_line_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- _replace_text_line_edit->connect("text_entered", callable_mp(this, &FindInFilesDialog::_on_replace_text_entered));
+ _replace_text_line_edit->connect("text_submitted", callable_mp(this, &FindInFilesDialog::_on_replace_text_submitted));
_replace_text_line_edit->hide();
gc->add_child(_replace_text_line_edit);
@@ -503,7 +503,7 @@ void FindInFilesDialog::_on_search_text_modified(String text) {
_replace_button->set_disabled(get_search_text().is_empty());
}
-void FindInFilesDialog::_on_search_text_entered(String text) {
+void FindInFilesDialog::_on_search_text_submitted(String text) {
// This allows to trigger a global search without leaving the keyboard
if (!_find_button->is_disabled()) {
if (_mode == SEARCH_MODE) {
@@ -518,7 +518,7 @@ void FindInFilesDialog::_on_search_text_entered(String text) {
}
}
-void FindInFilesDialog::_on_replace_text_entered(String text) {
+void FindInFilesDialog::_on_replace_text_submitted(String text) {
// This allows to trigger a global search without leaving the keyboard
if (!_replace_button->is_disabled()) {
if (_mode == REPLACE_MODE) {
diff --git a/editor/find_in_files.h b/editor/find_in_files.h
index b9d60a8d4f..488f14a922 100644
--- a/editor/find_in_files.h
+++ b/editor/find_in_files.h
@@ -128,8 +128,8 @@ private:
void _on_folder_button_pressed();
void _on_folder_selected(String path);
void _on_search_text_modified(String text);
- void _on_search_text_entered(String text);
- void _on_replace_text_entered(String text);
+ void _on_search_text_submitted(String text);
+ void _on_replace_text_submitted(String text);
FindInFilesMode _mode;
LineEdit *_search_text_line_edit;
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index d8e5a05c5d..1b11ec4451 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -446,7 +446,7 @@ GroupDialog::GroupDialog() {
add_group_text = memnew(LineEdit);
chbc->add_child(add_group_text);
add_group_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- add_group_text->connect("text_entered", callable_mp(this, &GroupDialog::_add_group_pressed));
+ add_group_text->connect("text_submitted", callable_mp(this, &GroupDialog::_add_group_pressed));
Button *add_group_button = memnew(Button);
add_group_button->set_text(TTR("Add"));
@@ -689,7 +689,7 @@ GroupsEditor::GroupsEditor() {
group_name = memnew(LineEdit);
group_name->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbc->add_child(group_name);
- group_name->connect("text_entered", callable_mp(this, &GroupsEditor::_add_group));
+ group_name->connect("text_submitted", callable_mp(this, &GroupsEditor::_add_group));
add = memnew(Button);
add->set_text(TTR("Add"));
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 809f47bad9..72df65a787 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -308,6 +308,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) {
FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
+ ERR_FAIL_NULL(f);
f->store_8('G');
f->store_8('S');
f->store_8('T');
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 78c30df04b..867c701733 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -139,7 +139,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
name->set_expand_to_text_length_enabled(true);
node->add_child(name);
node->set_slot(0, false, 0, Color(), true, 0, get_theme_color("font_color", "Label"));
- name->connect("text_entered", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed), varray(agnode), CONNECT_DEFERRED);
+ name->connect("text_submitted", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed), varray(agnode), CONNECT_DEFERRED);
name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out), varray(name, agnode), CONNECT_DEFERRED);
base = 1;
node->set_show_close_button(true);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index bd88d96a66..4a3f3212fa 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -1694,7 +1694,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
file->connect("file_selected", callable_mp(this, &AnimationPlayerEditor::_dialog_action));
frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false));
- scale->connect("text_entered", callable_mp(this, &AnimationPlayerEditor::_scale_changed));
+ scale->connect("text_submitted", callable_mp(this, &AnimationPlayerEditor::_scale_changed));
renaming = false;
last_active = false;
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index c915276d3a..fe5a0cab4d 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -1329,7 +1329,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
name_edit = memnew(LineEdit);
name_edit_popup->add_child(name_edit);
name_edit->set_anchors_and_offsets_preset(PRESET_WIDE);
- name_edit->connect("text_entered", callable_mp(this, &AnimationNodeStateMachineEditor::_name_edited));
+ name_edit->connect("text_submitted", callable_mp(this, &AnimationNodeStateMachineEditor::_name_edited));
name_edit->connect("focus_exited", callable_mp(this, &AnimationNodeStateMachineEditor::_name_edited_focus_out));
open_file = memnew(EditorFileDialog);
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index 11eae9e041..c6ca1ecd4f 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -282,7 +282,7 @@ class EditorAssetLibrary : public PanelContainer {
void _search(int p_page = 0);
void _rerun_search(int p_ignore);
void _search_text_changed(const String &p_text = "");
- void _search_text_entered(const String &p_text = "");
+ void _search_text_submitted(const String &p_text = "");
void _api_request(const String &p_request, RequestType p_request_type, const String &p_arguments = "");
void _http_request_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
void _http_download_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index fdb6e27367..60cc0a0a2a 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -7245,10 +7245,6 @@ void Node3DEditorPlugin::set_state(const Dictionary &p_state) {
spatial_editor->set_state(p_state);
}
-void Node3DEditor::snap_cursor_to_plane(const Plane &p_plane) {
- //cursor.pos=p_plane.project(cursor.pos);
-}
-
Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
if (is_snap_enabled()) {
p_target.x = Math::snap_scalar(0.0, get_translate_snap(), p_target.x);
@@ -7291,14 +7287,6 @@ float Node3DEditor::get_scale_snap() const {
return snap_value;
}
-void Node3DEditorPlugin::_bind_methods() {
- ClassDB::bind_method("snap_cursor_to_plane", &Node3DEditorPlugin::snap_cursor_to_plane);
-}
-
-void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) {
- spatial_editor->snap_cursor_to_plane(p_plane);
-}
-
struct _GizmoPluginPriorityComparator {
bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const {
if (p_a->get_priority() == p_b->get_priority()) {
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 161d6a38a9..20a0c501df 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -817,7 +817,6 @@ protected:
public:
static Node3DEditor *get_singleton() { return singleton; }
- void snap_cursor_to_plane(const Plane &p_plane);
Vector3 snap_point(Vector3 p_target, Vector3 p_start = Vector3(0, 0, 0)) const;
@@ -890,12 +889,7 @@ class Node3DEditorPlugin : public EditorPlugin {
Node3DEditor *spatial_editor;
EditorNode *editor;
-protected:
- static void _bind_methods();
-
public:
- void snap_cursor_to_plane(const Plane &p_plane);
-
Node3DEditor *get_spatial_editor() { return spatial_editor; }
virtual String get_name() const override { return "3D"; }
bool has_main_screen() const override { return true; }
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 1f6da30547..3ec20ae68e 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1061,7 +1061,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
- tx->toggle_fold_line(tx->cursor_get_line());
+ tx->toggle_foldable_line(tx->cursor_get_line());
tx->update();
} break;
case EDIT_FOLD_ALL_LINES: {
@@ -1549,7 +1549,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
bool has_color = (word_at_pos == "Color");
- bool foldable = tx->can_fold(row) || tx->is_folded(row);
+ bool foldable = tx->can_fold_line(row) || tx->is_line_folded(row);
bool open_docs = false;
bool goto_definition = false;
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index dc7f85a790..621f843e6f 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -332,7 +332,7 @@ void TextEditor::_edit_option(int p_op) {
code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
- tx->toggle_fold_line(tx->cursor_get_line());
+ tx->toggle_foldable_line(tx->cursor_get_line());
tx->update();
} break;
case EDIT_FOLD_ALL_LINES: {
@@ -432,8 +432,8 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
- bool can_fold = tx->can_fold(row);
- bool is_folded = tx->is_folded(row);
+ bool can_fold = tx->can_fold_line(row);
+ bool is_folded = tx->is_line_folded(row);
if (tx->is_right_click_moving_caret()) {
if (tx->is_selection_active()) {
@@ -463,7 +463,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_MENU) {
CodeEdit *tx = code_editor->get_text_editor();
int line = tx->cursor_get_line();
- _make_context_menu(tx->is_selection_active(), tx->can_fold(line), tx->is_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->_get_cursor_pixel_pos()));
+ _make_context_menu(tx->is_selection_active(), tx->can_fold_line(line), tx->is_line_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->_get_cursor_pixel_pos()));
context_menu->grab_focus();
}
}
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 237cd83b84..e393f960bd 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -432,7 +432,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
register_uniform_name(p_id, uniform_name);
uniform_name->set_text(uniform->get_uniform_name());
node->add_child(uniform_name);
- uniform_name->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id));
+ uniform_name->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id));
uniform_name->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_focus_out), varray(uniform_name, p_id));
if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") {
@@ -666,7 +666,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
name_box->set_text(name_left);
- name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
+ name_box->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false), CONNECT_DEFERRED);
Button *remove_btn = memnew(Button);
@@ -707,7 +707,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
name_box->set_text(name_right);
- name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
+ name_box->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true), CONNECT_DEFERRED);
OptionButton *type_box = memnew(OptionButton);
@@ -1855,7 +1855,7 @@ void VisualShaderEditor::_comment_title_text_changed(const String &p_new_text) {
comment_title_change_popup->set_size(Size2(-1, -1));
}
-void VisualShaderEditor::_comment_title_text_entered(const String &p_new_text) {
+void VisualShaderEditor::_comment_title_text_submitted(const String &p_new_text) {
comment_title_change_popup->hide();
}
@@ -3944,7 +3944,7 @@ VisualShaderEditor::VisualShaderEditor() {
comment_title_change_edit = memnew(LineEdit);
comment_title_change_edit->set_expand_to_text_length_enabled(true);
comment_title_change_edit->connect("text_changed", callable_mp(this, &VisualShaderEditor::_comment_title_text_changed));
- comment_title_change_edit->connect("text_entered", callable_mp(this, &VisualShaderEditor::_comment_title_text_entered));
+ comment_title_change_edit->connect("text_submitted", callable_mp(this, &VisualShaderEditor::_comment_title_text_submitted));
comment_title_change_popup->add_child(comment_title_change_edit);
comment_title_change_edit->set_size(Size2(-1, -1));
comment_title_change_popup->set_size(Size2(-1, -1));
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index fa98c6b780..4c7489a694 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -358,7 +358,7 @@ class VisualShaderEditor : public VBoxContainer {
void _comment_title_popup_hide();
void _comment_title_popup_focus_out();
void _comment_title_text_changed(const String &p_new_text);
- void _comment_title_text_entered(const String &p_new_text);
+ void _comment_title_text_submitted(const String &p_new_text);
void _comment_desc_popup_show(const Point2 &p_position, int p_node_id);
void _comment_desc_popup_hide();
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 7ca2d4d324..ec65694772 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -871,10 +871,10 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) {
if (invalid_path) {
export_project->get_ok_button()->set_disabled(true);
- export_project->get_line_edit()->disconnect("text_entered", Callable(export_project, "_file_entered"));
+ export_project->get_line_edit()->disconnect("text_submitted", Callable(export_project, "_file_submitted"));
} else {
export_project->get_ok_button()->set_disabled(false);
- export_project->get_line_edit()->connect("text_entered", Callable(export_project, "_file_entered"));
+ export_project->get_line_edit()->connect("text_submitted", Callable(export_project, "_file_submitted"));
}
}
@@ -905,10 +905,10 @@ void ProjectExportDialog::_export_project() {
// Ensure that signal is connected if previous attempt left it disconnected
// with _validate_export_path.
// FIXME: This is a hack, we should instead change EditorFileDialog to allow
- // disabling validation by the "text_entered" signal.
- if (!export_project->get_line_edit()->is_connected("text_entered", Callable(export_project, "_file_entered"))) {
+ // disabling validation by the "text_submitted" signal.
+ if (!export_project->get_line_edit()->is_connected("text_submitted", Callable(export_project, "_file_submitted"))) {
export_project->get_ok_button()->set_disabled(false);
- export_project->get_line_edit()->connect("text_entered", Callable(export_project, "_file_entered"));
+ export_project->get_line_edit()->connect("text_submitted", Callable(export_project, "_file_submitted"));
}
export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 5490fbbbc7..1267c7dd19 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -2400,36 +2400,10 @@ ProjectManager::ProjectManager() {
int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
switch (display_scale) {
- case 0: {
+ case 0:
// Try applying a suitable display scale automatically.
- // The code below is adapted in `editor/editor_settings.cpp` and `editor/editor_node.cpp`.
- // Make sure to update those when modifying the code below.
-#ifdef OSX_ENABLED
- editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
-#else
- const int screen = DisplayServer::get_singleton()->window_get_current_screen();
- // Use the smallest dimension to use a correct display scale on portait displays.
- const int smallest_dimension = MIN(DisplayServer::get_singleton()->screen_get_size(screen).x, DisplayServer::get_singleton()->screen_get_size(screen).y);
- float scale;
- if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && smallest_dimension >= 1400) {
- // hiDPI display.
- scale = 2.0;
- } else if (smallest_dimension >= 1700) {
- // Likely a hiDPI display, but we aren't certain due to the returned DPI.
- // Use an intermediate scale to handle this situation.
- scale = 1.5;
- } else if (smallest_dimension <= 800) {
- // Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
- // Icons won't look great, but this is better than having editor elements overflow from its window.
- scale = 0.75;
- } else {
- scale = 1.0;
- }
-
- editor_set_scale(scale);
-#endif
- } break;
-
+ editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
+ break;
case 1:
editor_set_scale(0.75);
break;
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index c44f8d9a4b..ba3c9aafb4 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -1781,7 +1781,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
value_hboxes[hbox_idx]->add_child(value_editor[i]);
value_editor[i]->set_h_size_flags(Control::SIZE_EXPAND_FILL);
value_editor[i]->hide();
- value_editor[i]->connect("text_entered", callable_mp(this, &CustomPropertyEditor::_modified));
+ value_editor[i]->connect("text_submitted", callable_mp(this, &CustomPropertyEditor::_modified));
value_editor[i]->connect("focus_entered", callable_mp(this, &CustomPropertyEditor::_focus_enter));
value_editor[i]->connect("focus_exited", callable_mp(this, &CustomPropertyEditor::_focus_exit));
}
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 650decfd49..01743bccab 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -602,7 +602,7 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
_update_dialog();
}
-void ScriptCreateDialog::_path_entered(const String &p_path) {
+void ScriptCreateDialog::_path_submitted(const String &p_path) {
ok_pressed();
}
@@ -731,13 +731,13 @@ void ScriptCreateDialog::_update_dialog() {
get_ok_button()->set_disabled(!script_ok);
- Callable entered_call = callable_mp(this, &ScriptCreateDialog::_path_entered);
+ Callable entered_call = callable_mp(this, &ScriptCreateDialog::_path_submitted);
if (script_ok) {
- if (!file_path->is_connected("text_entered", entered_call)) {
- file_path->connect("text_entered", entered_call);
+ if (!file_path->is_connected("text_submitted", entered_call)) {
+ file_path->connect("text_submitted", entered_call);
}
- } else if (file_path->is_connected("text_entered", entered_call)) {
- file_path->disconnect("text_entered", entered_call);
+ } else if (file_path->is_connected("text_submitted", entered_call)) {
+ file_path->disconnect("text_submitted", entered_call);
}
}
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index d6417b9d33..a020be0478 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -105,7 +105,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
void _path_hbox_sorted();
bool _can_be_built_in();
void _path_changed(const String &p_path = String());
- void _path_entered(const String &p_path = String());
+ void _path_submitted(const String &p_path = String());
void _lang_changed(int l = 0);
void _built_in_pressed();
bool _validate_parent(const String &p_string);
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index a47ed6652d..7e17ac2f05 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -62,12 +62,6 @@ void GridMapEditor::_menu_option(int p_option) {
floor->set_value(floor->get_value() + 1);
} break;
- case MENU_OPTION_LOCK_VIEW: {
- int index = options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW);
- lock_view = !options->get_popup()->is_item_checked(index);
-
- options->get_popup()->set_item_checked(index, lock_view);
- } break;
case MENU_OPTION_CLIP_DISABLED:
case MENU_OPTION_CLIP_ABOVE:
case MENU_OPTION_CLIP_BELOW: {
@@ -1080,20 +1074,6 @@ void GridMapEditor::_notification(int p_what) {
if (cgmt.operator->() != last_mesh_library) {
update_palette();
}
-
- if (lock_view) {
- EditorNode *editor = Object::cast_to<EditorNode>(get_tree()->get_root()->get_child(0));
-
- Plane p;
- p.normal[edit_axis] = 1.0;
- p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis];
- p = node->get_transform().xform(p); // plane to snap
-
- Node3DEditorPlugin *sep = Object::cast_to<Node3DEditorPlugin>(editor->get_editor_plugin_screen());
- if (sep) {
- sep->snap_cursor_to_plane(p);
- }
- }
} break;
case NOTIFICATION_THEME_CHANGED: {
@@ -1187,8 +1167,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
spatial_editor_hb->hide();
options->set_text(TTR("Grid Map"));
- options->get_popup()->add_check_item(TTR("Snap View"), MENU_OPTION_LOCK_VIEW);
- options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q);
options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E);
options->get_popup()->add_separator();
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 0e29c88d26..4bc849e071 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -94,7 +94,6 @@ class GridMapEditor : public VBoxContainer {
MeshLibrary *last_mesh_library;
ClipMode clip_mode = CLIP_DISABLED;
- bool lock_view = false;
Transform3D grid_xform;
Transform3D edit_grid_xform;
Vector3::Axis edit_axis;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index cad4330c17..9640043031 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -404,10 +404,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
break;
}
- List<Camera3D *> cameras;
- world_3d->get_camera_list(&cameras);
-
- for (List<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
+ for (const Set<Camera3D *>::Element *E = world_3d->get_cameras().front(); E; E = E->next()) {
Camera3D *camera = E->get();
Viewport *vp = camera->get_viewport();
if (!vp->is_audio_listener()) {
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 6b8851b4f8..62bbebe6e7 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -93,10 +93,6 @@ void Camera3D::_update_camera() {
}
get_viewport()->_camera_transform_changed_notify();
-
- if (get_world_3d().is_valid()) {
- get_world_3d()->_update_camera(this);
- }
}
void Camera3D::_notification(int p_what) {
diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp
index b230cb2fd7..39b17d195b 100644
--- a/scene/3d/visibility_notifier_3d.cpp
+++ b/scene/3d/visibility_notifier_3d.cpp
@@ -36,27 +36,23 @@
#include "scene/animation/animation_player.h"
#include "scene/scene_string_names.h"
-void VisibilityNotifier3D::_enter_camera(Camera3D *p_camera) {
- ERR_FAIL_COND(cameras.has(p_camera));
- cameras.insert(p_camera);
- if (cameras.size() == 1) {
- emit_signal(SceneStringNames::get_singleton()->screen_entered);
- _screen_enter();
+void VisibilityNotifier3D::_visibility_enter() {
+ if (!is_inside_tree() || Engine::get_singleton()->is_editor_hint()) {
+ return;
}
- emit_signal(SceneStringNames::get_singleton()->camera_entered, p_camera);
+ on_screen = true;
+ emit_signal(SceneStringNames::get_singleton()->screen_entered);
+ _screen_enter();
}
-
-void VisibilityNotifier3D::_exit_camera(Camera3D *p_camera) {
- ERR_FAIL_COND(!cameras.has(p_camera));
- cameras.erase(p_camera);
-
- emit_signal(SceneStringNames::get_singleton()->camera_exited, p_camera);
- if (cameras.size() == 0) {
- emit_signal(SceneStringNames::get_singleton()->screen_exited);
-
- _screen_exit();
+void VisibilityNotifier3D::_visibility_exit() {
+ if (!is_inside_tree() || Engine::get_singleton()->is_editor_hint()) {
+ return;
}
+
+ on_screen = false;
+ emit_signal(SceneStringNames::get_singleton()->screen_exited);
+ _screen_exit();
}
void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
@@ -65,9 +61,7 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
}
aabb = p_aabb;
- if (is_inside_world()) {
- get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
- }
+ RS::get_singleton()->visibility_notifier_set_aabb(get_base(), aabb);
update_gizmo();
}
@@ -76,178 +70,129 @@ AABB VisibilityNotifier3D::get_aabb() const {
return aabb;
}
-void VisibilityNotifier3D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_WORLD: {
- world = get_world_3d();
- ERR_FAIL_COND(!world.is_valid());
- world->_register_notifier(this, get_global_transform().xform(aabb));
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- world->_update_notifier(this, get_global_transform().xform(aabb));
- } break;
- case NOTIFICATION_EXIT_WORLD: {
- ERR_FAIL_COND(!world.is_valid());
- world->_remove_notifier(this);
- } break;
- }
+bool VisibilityNotifier3D::is_on_screen() const {
+ return on_screen;
}
-bool VisibilityNotifier3D::is_on_screen() const {
- return cameras.size() != 0;
+void VisibilityNotifier3D::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_EXIT_TREE) {
+ on_screen = false;
+ }
}
void VisibilityNotifier3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_aabb", "rect"), &VisibilityNotifier3D::set_aabb);
- ClassDB::bind_method(D_METHOD("get_aabb"), &VisibilityNotifier3D::get_aabb);
ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier3D::is_on_screen);
ADD_PROPERTY(PropertyInfo(Variant::AABB, "aabb"), "set_aabb", "get_aabb");
- ADD_SIGNAL(MethodInfo("camera_entered", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D")));
- ADD_SIGNAL(MethodInfo("camera_exited", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D")));
ADD_SIGNAL(MethodInfo("screen_entered"));
ADD_SIGNAL(MethodInfo("screen_exited"));
}
+Vector<Face3> VisibilityNotifier3D::get_faces(uint32_t p_usage_flags) const {
+ return Vector<Face3>();
+}
+
VisibilityNotifier3D::VisibilityNotifier3D() {
- set_notify_transform(true);
+ RID notifier = RS::get_singleton()->visibility_notifier_create();
+ RS::get_singleton()->visibility_notifier_set_aabb(notifier, aabb);
+ RS::get_singleton()->visibility_notifier_set_callbacks(notifier, callable_mp(this, &VisibilityNotifier3D::_visibility_enter), callable_mp(this, &VisibilityNotifier3D::_visibility_exit));
+ set_base(notifier);
}
//////////////////////////////////////
void VisibilityEnabler3D::_screen_enter() {
- for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
- _change_node_state(E->key(), true);
- }
-
- visible = true;
+ _update_enable_mode(true);
}
void VisibilityEnabler3D::_screen_exit() {
- for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
- _change_node_state(E->key(), false);
- }
-
- visible = false;
+ _update_enable_mode(false);
}
-void VisibilityEnabler3D::_find_nodes(Node *p_node) {
- bool add = false;
- Variant meta;
-
- {
- RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node);
- if (rb && ((rb->get_mode() == RigidBody3D::MODE_DYNAMIC || rb->get_mode() == RigidBody3D::MODE_DYNAMIC_LOCKED))) {
- add = true;
- meta = rb->get_mode();
- }
+void VisibilityEnabler3D::set_enable_mode(EnableMode p_mode) {
+ enable_mode = p_mode;
+ if (is_inside_tree()) {
+ _update_enable_mode(is_on_screen());
}
+}
+VisibilityEnabler3D::EnableMode VisibilityEnabler3D::get_enable_mode() {
+ return enable_mode;
+}
- {
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
- if (ap) {
- add = true;
- }
+void VisibilityEnabler3D::set_enable_node_path(NodePath p_path) {
+ if (enable_node_path == p_path) {
+ return;
}
-
- if (add) {
- p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler3D::_node_removed), varray(p_node), CONNECT_ONESHOT);
- nodes[p_node] = meta;
- _change_node_state(p_node, false);
+ enable_node_path = p_path;
+ if (is_inside_tree()) {
+ node_id = ObjectID();
+ Node *node = get_node(enable_node_path);
+ if (node) {
+ node_id = node->get_instance_id();
+ _update_enable_mode(is_on_screen());
+ }
}
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *c = p_node->get_child(i);
- if (c->get_filename() != String()) {
- continue; //skip, instance
+}
+NodePath VisibilityEnabler3D::get_enable_node_path() {
+ return enable_node_path;
+}
+
+void VisibilityEnabler3D::_update_enable_mode(bool p_enable) {
+ Node *node = static_cast<Node *>(ObjectDB::get_instance(node_id));
+ if (node) {
+ if (p_enable) {
+ switch (enable_mode) {
+ case ENABLE_MODE_INHERIT: {
+ node->set_process_mode(PROCESS_MODE_INHERIT);
+ } break;
+ case ENABLE_MODE_ALWAYS: {
+ node->set_process_mode(PROCESS_MODE_ALWAYS);
+ } break;
+ case ENABLE_MODE_WHEN_PAUSED: {
+ node->set_process_mode(PROCESS_MODE_WHEN_PAUSED);
+ } break;
+ }
+ } else {
+ node->set_process_mode(PROCESS_MODE_DISABLED);
}
-
- _find_nodes(c);
}
}
-
void VisibilityEnabler3D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
- Node *from = this;
- //find where current scene starts
- while (from->get_parent() && from->get_filename() == String()) {
- from = from->get_parent();
+ node_id = ObjectID();
+ Node *node = get_node(enable_node_path);
+ if (node) {
+ node_id = node->get_instance_id();
+ node->set_process_mode(PROCESS_MODE_DISABLED);
}
-
- _find_nodes(from);
}
if (p_what == NOTIFICATION_EXIT_TREE) {
- if (Engine::get_singleton()->is_editor_hint()) {
- return;
- }
-
- for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
- if (!visible) {
- _change_node_state(E->key(), true);
- }
- E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler3D::_node_removed));
- }
-
- nodes.clear();
- }
-}
-
-void VisibilityEnabler3D::_change_node_state(Node *p_node, bool p_enabled) {
- ERR_FAIL_COND(!nodes.has(p_node));
-
- if (enabler[ENABLER_FREEZE_BODIES]) {
- RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node);
- if (rb) {
- rb->set_sleeping(!p_enabled);
- }
- }
-
- if (enabler[ENABLER_PAUSE_ANIMATIONS]) {
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
-
- if (ap) {
- ap->set_active(p_enabled);
- }
+ node_id = ObjectID();
}
}
-void VisibilityEnabler3D::_node_removed(Node *p_node) {
- if (!visible) {
- _change_node_state(p_node, true);
- }
- nodes.erase(p_node);
-}
-
void VisibilityEnabler3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler3D::set_enabler);
- ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler3D::is_enabler_enabled);
+ ClassDB::bind_method(D_METHOD("set_enable_mode", "mode"), &VisibilityEnabler3D::set_enable_mode);
+ ClassDB::bind_method(D_METHOD("get_enable_mode"), &VisibilityEnabler3D::get_enable_mode);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "pause_animations"), "set_enabler", "is_enabler_enabled", ENABLER_PAUSE_ANIMATIONS);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "freeze_bodies"), "set_enabler", "is_enabler_enabled", ENABLER_FREEZE_BODIES);
+ ClassDB::bind_method(D_METHOD("set_enable_node_path", "path"), &VisibilityEnabler3D::set_enable_node_path);
+ ClassDB::bind_method(D_METHOD("get_enable_node_path"), &VisibilityEnabler3D::get_enable_node_path);
- BIND_ENUM_CONSTANT(ENABLER_PAUSE_ANIMATIONS);
- BIND_ENUM_CONSTANT(ENABLER_FREEZE_BODIES);
- BIND_ENUM_CONSTANT(ENABLER_MAX);
-}
+ ADD_GROUP("Enabling", "enable_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "enable_mode", PROPERTY_HINT_ENUM, "Inherit,Always,WhenPaused"), "set_enable_mode", "get_enable_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "enable_node_path"), "set_enable_node_path", "get_enable_node_path");
-void VisibilityEnabler3D::set_enabler(Enabler p_enabler, bool p_enable) {
- ERR_FAIL_INDEX(p_enabler, ENABLER_MAX);
- enabler[p_enabler] = p_enable;
-}
-
-bool VisibilityEnabler3D::is_enabler_enabled(Enabler p_enabler) const {
- ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false);
- return enabler[p_enabler];
+ BIND_ENUM_CONSTANT(ENABLE_MODE_INHERIT);
+ BIND_ENUM_CONSTANT(ENABLE_MODE_ALWAYS);
+ BIND_ENUM_CONSTANT(ENABLE_MODE_WHEN_PAUSED);
}
VisibilityEnabler3D::VisibilityEnabler3D() {
- for (int i = 0; i < ENABLER_MAX; i++) {
- enabler[i] = true;
- }
}
diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h
index 9f7705067f..878c97e35e 100644
--- a/scene/3d/visibility_notifier_3d.h
+++ b/scene/3d/visibility_notifier_3d.h
@@ -31,34 +31,34 @@
#ifndef VISIBILITY_NOTIFIER_H
#define VISIBILITY_NOTIFIER_H
-#include "scene/3d/node_3d.h"
+#include "scene/3d/visual_instance_3d.h"
class World3D;
class Camera3D;
-class VisibilityNotifier3D : public Node3D {
- GDCLASS(VisibilityNotifier3D, Node3D);
-
- Ref<World3D> world;
- Set<Camera3D *> cameras;
+class VisibilityNotifier3D : public VisualInstance3D {
+ GDCLASS(VisibilityNotifier3D, VisualInstance3D);
AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
+private:
+ bool on_screen = false;
+ void _visibility_enter();
+ void _visibility_exit();
+
protected:
virtual void _screen_enter() {}
virtual void _screen_exit() {}
void _notification(int p_what);
static void _bind_methods();
- friend struct SpatialIndexer;
-
- void _enter_camera(Camera3D *p_camera);
- void _exit_camera(Camera3D *p_camera);
public:
void set_aabb(const AABB &p_aabb);
- AABB get_aabb() const;
+ virtual AABB get_aabb() const override;
bool is_on_screen() const;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
+
VisibilityNotifier3D();
};
@@ -66,36 +66,35 @@ class VisibilityEnabler3D : public VisibilityNotifier3D {
GDCLASS(VisibilityEnabler3D, VisibilityNotifier3D);
public:
- enum Enabler {
- ENABLER_PAUSE_ANIMATIONS,
- ENABLER_FREEZE_BODIES,
- ENABLER_MAX
+ enum EnableMode {
+ ENABLE_MODE_INHERIT,
+ ENABLE_MODE_ALWAYS,
+ ENABLE_MODE_WHEN_PAUSED,
};
protected:
+ ObjectID node_id;
virtual void _screen_enter() override;
virtual void _screen_exit() override;
- bool visible = false;
-
- void _find_nodes(Node *p_node);
-
- Map<Node *, Variant> nodes;
- void _node_removed(Node *p_node);
- bool enabler[ENABLER_MAX];
-
- void _change_node_state(Node *p_node, bool p_enabled);
+ EnableMode enable_mode = ENABLE_MODE_INHERIT;
+ NodePath enable_node_path = NodePath("..");
void _notification(int p_what);
static void _bind_methods();
+ void _update_enable_mode(bool p_enable);
+
public:
- void set_enabler(Enabler p_enabler, bool p_enable);
- bool is_enabler_enabled(Enabler p_enabler) const;
+ void set_enable_mode(EnableMode p_mode);
+ EnableMode get_enable_mode();
+
+ void set_enable_node_path(NodePath p_path);
+ NodePath get_enable_node_path();
VisibilityEnabler3D();
};
-VARIANT_ENUM_CAST(VisibilityEnabler3D::Enabler);
+VARIANT_ENUM_CAST(VisibilityEnabler3D::EnableMode);
#endif // VISIBILITY_NOTIFIER_H
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index bf6a877384..5b720945b8 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -218,6 +218,11 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseButton> mb = p_gui_input;
if (mb.is_valid()) {
+ /* Ignore mouse clicks in IME input mode. */
+ if (has_ime_text()) {
+ return;
+ }
+
if (code_completion_active && code_completion_rect.has_point(mb->get_position())) {
if (!mb->is_pressed()) {
return;
@@ -248,6 +253,30 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
cancel_code_completion();
set_code_hint("");
+
+ if (mb->is_pressed()) {
+ Vector2i mpos = mb->get_position();
+ if (is_layout_rtl()) {
+ mpos.x = get_size().x - mpos.x;
+ }
+
+ int line, col;
+ _get_mouse_pos(Point2i(mpos.x, mpos.y), line, col);
+
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
+ if (is_line_folded(line)) {
+ int wrap_index = get_line_wrap_index_at_col(line, col);
+ if (wrap_index == times_line_wraps(line)) {
+ int eol_icon_width = cache.folded_eol_icon->get_width();
+ int left_margin = get_total_gutter_width() + eol_icon_width + get_line_width(line, wrap_index) - get_h_scroll();
+ if (mpos.x > left_margin && mpos.x <= left_margin + eol_icon_width + 3) {
+ unfold_line(line);
+ return;
+ }
+ }
+ }
+ }
+ }
}
Ref<InputEventKey> k = p_gui_input;
@@ -356,6 +385,16 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
set_code_hint("");
}
+ /* Override input to unfold lines where needed. */
+ if (!is_readonly()) {
+ if (k->is_action("ui_text_newline_above", true) || k->is_action("ui_text_newline_blank", true) || k->is_action("ui_text_newline", true)) {
+ unfold_line(cursor_get_line());
+ }
+ if (cursor_get_line() > 0 && k->is_action("ui_text_backspace", true)) {
+ unfold_line(cursor_get_line() - 1);
+ }
+ }
+
/* Remove shift otherwise actions will not match. */
k = k->duplicate();
k->set_shift_pressed(false);
@@ -380,6 +419,21 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
if ((code_completion_active && code_completion_rect.has_point(p_pos)) || (is_readonly() && (!is_selecting_enabled() || get_line_count() == 0))) {
return CURSOR_ARROW;
}
+
+ int line, col;
+ _get_mouse_pos(p_pos, line, col);
+
+ if (is_line_folded(line)) {
+ int wrap_index = get_line_wrap_index_at_col(line, col);
+ if (wrap_index == times_line_wraps(line)) {
+ int eol_icon_width = cache.folded_eol_icon->get_width();
+ int left_margin = get_total_gutter_width() + eol_icon_width + get_line_width(line, wrap_index) - get_h_scroll();
+ if (p_pos.x > left_margin && p_pos.x <= left_margin + eol_icon_width + 3) {
+ return CURSOR_POINTING_HAND;
+ }
+ }
+ }
+
return TextEdit::get_cursor_shape(p_pos);
}
@@ -581,7 +635,7 @@ bool CodeEdit::is_drawing_fold_gutter() const {
}
void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_region) {
- if (!can_fold(p_line) && !is_folded(p_line)) {
+ if (!can_fold_line(p_line) && !is_line_folded(p_line)) {
set_line_gutter_clickable(p_line, fold_gutter, false);
return;
}
@@ -593,13 +647,193 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi
p_region.position += Point2(horizontal_padding, vertical_padding);
p_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
- if (can_fold(p_line)) {
+ if (can_fold_line(p_line)) {
can_fold_icon->draw_rect(get_canvas_item(), p_region, false, folding_color);
return;
}
folded_icon->draw_rect(get_canvas_item(), p_region, false, folding_color);
}
+/* Line Folding */
+void CodeEdit::set_line_folding_enabled(bool p_enabled) {
+ line_folding_enabled = p_enabled;
+ set_hiding_enabled(p_enabled);
+}
+
+bool CodeEdit::is_line_folding_enabled() const {
+ return line_folding_enabled;
+}
+
+bool CodeEdit::can_fold_line(int p_line) const {
+ ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
+ if (!line_folding_enabled) {
+ return false;
+ }
+
+ if (p_line + 1 >= get_line_count() || get_line(p_line).strip_edges().size() == 0) {
+ return false;
+ }
+
+ if (is_line_hidden(p_line) || is_line_folded(p_line)) {
+ return false;
+ }
+
+ /* Check for full multiline line or block strings / comments. */
+ int in_comment = is_in_comment(p_line);
+ int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
+ if (in_string != -1 || in_comment != -1) {
+ if (get_delimiter_start_position(p_line, get_line(p_line).size() - 1).y != p_line) {
+ return false;
+ }
+
+ int delimter_end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
+ /* No end line, therefore we have a multiline region over the rest of the file. */
+ if (delimter_end_line == -1) {
+ return true;
+ }
+ /* End line is the same therefore we have a block. */
+ if (delimter_end_line == p_line) {
+ /* Check we are the start of the block. */
+ if (p_line - 1 >= 0) {
+ if ((in_string != -1 && is_in_string(p_line - 1) != -1) || (in_comment != -1 && is_in_comment(p_line - 1) != -1)) {
+ return false;
+ }
+ }
+ /* Check it continues for at least one line. */
+ return ((in_string != -1 && is_in_string(p_line + 1) != -1) || (in_comment != -1 && is_in_comment(p_line + 1) != -1));
+ }
+ return ((in_string != -1 && is_in_string(delimter_end_line) != -1) || (in_comment != -1 && is_in_comment(delimter_end_line) != -1));
+ }
+
+ /* Otherwise check indent levels. */
+ int start_indent = get_indent_level(p_line);
+ for (int i = p_line + 1; i < get_line_count(); i++) {
+ if (is_in_string(i) != -1 || is_in_comment(i) != -1 || get_line(i).strip_edges().size() == 0) {
+ continue;
+ }
+ return (get_indent_level(i) > start_indent);
+ }
+ return false;
+}
+
+void CodeEdit::fold_line(int p_line) {
+ ERR_FAIL_INDEX(p_line, get_line_count());
+ if (!is_line_folding_enabled() || !can_fold_line(p_line)) {
+ return;
+ }
+
+ /* Find the last line to be hidden. */
+ int end_line = get_line_count();
+
+ int in_comment = is_in_comment(p_line);
+ int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
+ if (in_string != -1 || in_comment != -1) {
+ end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
+ /* End line is the same therefore we have a block. */
+ if (end_line == p_line) {
+ for (int i = p_line + 1; i < get_line_count(); i++) {
+ if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
+ end_line = i - 1;
+ break;
+ }
+ }
+ }
+ } else {
+ int start_indent = get_indent_level(p_line);
+ for (int i = p_line + 1; i < get_line_count(); i++) {
+ if (get_line(p_line).strip_edges().size() == 0 || is_in_string(i) != -1 || is_in_comment(i) != -1) {
+ end_line = i;
+ continue;
+ }
+
+ if (get_indent_level(i) <= start_indent && get_line(i).strip_edges().size() != 0) {
+ end_line = i - 1;
+ break;
+ }
+ }
+ }
+
+ for (int i = p_line + 1; i <= end_line; i++) {
+ set_line_as_hidden(i, true);
+ }
+
+ /* Fix selection. */
+ if (is_selection_active()) {
+ if (is_line_hidden(get_selection_from_line()) && is_line_hidden(get_selection_to_line())) {
+ deselect();
+ } else if (is_line_hidden(get_selection_from_line())) {
+ select(p_line, 9999, get_selection_to_line(), get_selection_to_column());
+ } else if (is_line_hidden(get_selection_to_line())) {
+ select(get_selection_from_line(), get_selection_from_column(), p_line, 9999);
+ }
+ }
+
+ /* Reset caret. */
+ if (is_line_hidden(cursor_get_line())) {
+ cursor_set_line(p_line, false, false);
+ cursor_set_column(get_line(p_line).length(), false);
+ }
+ update();
+}
+
+void CodeEdit::unfold_line(int p_line) {
+ ERR_FAIL_INDEX(p_line, get_line_count());
+ if (!is_line_folded(p_line) && !is_line_hidden(p_line)) {
+ return;
+ }
+
+ int fold_start = p_line;
+ for (; fold_start > 0; fold_start--) {
+ if (is_line_folded(fold_start)) {
+ break;
+ }
+ }
+ fold_start = is_line_folded(fold_start) ? fold_start : p_line;
+
+ for (int i = fold_start + 1; i < get_line_count(); i++) {
+ if (!is_line_hidden(i)) {
+ break;
+ }
+ set_line_as_hidden(i, false);
+ }
+ update();
+}
+
+void CodeEdit::fold_all_lines() {
+ for (int i = 0; i < get_line_count(); i++) {
+ fold_line(i);
+ }
+ update();
+}
+
+void CodeEdit::unfold_all_lines() {
+ unhide_all_lines();
+}
+
+void CodeEdit::toggle_foldable_line(int p_line) {
+ ERR_FAIL_INDEX(p_line, get_line_count());
+ if (is_line_folded(p_line)) {
+ unfold_line(p_line);
+ return;
+ }
+ fold_line(p_line);
+}
+
+bool CodeEdit::is_line_folded(int p_line) const {
+ ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
+ return p_line + 1 < get_line_count() && !is_line_hidden(p_line) && is_line_hidden(p_line + 1);
+}
+
+TypedArray<int> CodeEdit::get_folded_lines() const {
+ TypedArray<int> folded_lines;
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_folded(i)) {
+ folded_lines.push_back(i);
+ }
+ }
+ return folded_lines;
+}
+
/* Delimiters */
// Strings
void CodeEdit::add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only) {
@@ -1094,6 +1328,21 @@ void CodeEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_fold_gutter", "enable"), &CodeEdit::set_draw_fold_gutter);
ClassDB::bind_method(D_METHOD("is_drawing_fold_gutter"), &CodeEdit::is_drawing_fold_gutter);
+ /* Line folding */
+ ClassDB::bind_method(D_METHOD("set_line_folding_enabled", "enabled"), &CodeEdit::set_line_folding_enabled);
+ ClassDB::bind_method(D_METHOD("is_line_folding_enabled"), &CodeEdit::is_line_folding_enabled);
+
+ ClassDB::bind_method(D_METHOD("can_fold_line", "line"), &CodeEdit::can_fold_line);
+
+ ClassDB::bind_method(D_METHOD("fold_line", "line"), &CodeEdit::fold_line);
+ ClassDB::bind_method(D_METHOD("unfold_line", "line"), &CodeEdit::unfold_line);
+ ClassDB::bind_method(D_METHOD("fold_all_lines"), &CodeEdit::fold_all_lines);
+ ClassDB::bind_method(D_METHOD("unfold_all_lines"), &CodeEdit::unfold_all_lines);
+ ClassDB::bind_method(D_METHOD("toggle_foldable_line", "line"), &CodeEdit::toggle_foldable_line);
+
+ ClassDB::bind_method(D_METHOD("is_line_folded", "line"), &CodeEdit::is_line_folded);
+ ClassDB::bind_method(D_METHOD("get_folded_lines"), &CodeEdit::get_folded_lines);
+
/* Delimiters */
// Strings
ClassDB::bind_method(D_METHOD("add_string_delimiter", "start_key", "end_key", "line_only"), &CodeEdit::add_string_delimiter, DEFVAL(false));
@@ -1175,6 +1424,8 @@ void CodeEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "line_folding"), "set_line_folding_enabled", "is_line_folding_enabled");
+
ADD_GROUP("Delimiters", "delimiter_");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "delimiter_strings"), "set_string_delimiters", "get_string_delimiters");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "delimiter_comments"), "set_comment_delimiters", "get_comment_delimiters");
@@ -1205,9 +1456,9 @@ void CodeEdit::_gutter_clicked(int p_line, int p_gutter) {
}
if (p_gutter == fold_gutter) {
- if (is_folded(p_line)) {
+ if (is_line_folded(p_line)) {
unfold_line(p_line);
- } else if (can_fold(p_line)) {
+ } else if (can_fold_line(p_line)) {
fold_line(p_line);
}
return;
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 6305eacf83..52b3f52a03 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -98,6 +98,9 @@ private:
void _gutter_clicked(int p_line, int p_gutter);
void _update_gutter_indexes();
+ /* Line Folding */
+ bool line_folding_enabled = true;
+
/* Delimiters */
enum DelimiterType {
TYPE_STRING,
@@ -241,6 +244,21 @@ public:
void set_draw_fold_gutter(bool p_draw);
bool is_drawing_fold_gutter() const;
+ /* Line Folding */
+ void set_line_folding_enabled(bool p_enabled);
+ bool is_line_folding_enabled() const;
+
+ bool can_fold_line(int p_line) const;
+
+ void fold_line(int p_line);
+ void unfold_line(int p_line);
+ void fold_all_lines();
+ void unfold_all_lines();
+ void toggle_foldable_line(int p_line);
+
+ bool is_line_folded(int p_line) const;
+ TypedArray<int> get_folded_lines() const;
+
/* Delimiters */
void add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only = false);
void remove_string_delimiter(const String &p_start_key);
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index c0b4563615..f394b9e3a5 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -289,7 +289,7 @@ void ColorPicker::_value_changed(double) {
emit_signal("color_changed", color);
}
-void ColorPicker::_html_entered(const String &p_html) {
+void ColorPicker::_html_submitted(const String &p_html) {
if (updating || text_is_constructor || !c_text->is_visible()) {
return;
}
@@ -1041,7 +1041,7 @@ void ColorPicker::_html_focus_exit() {
if (c_text->get_menu()->is_visible()) {
return;
}
- _html_entered(c_text->get_text());
+ _html_submitted(c_text->get_text());
_focus_exit();
}
@@ -1204,7 +1204,7 @@ ColorPicker::ColorPicker() :
hhb->add_child(c_text);
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
- c_text->connect("text_entered", callable_mp(this, &ColorPicker::_html_entered));
+ c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted));
c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 14113467d0..3bd2ff9375 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -104,7 +104,7 @@ private:
float v = 0.0;
Color last_hsv;
- void _html_entered(const String &p_html);
+ void _html_submitted(const String &p_html);
void _value_changed(double);
void _update_controls();
void _update_color(bool p_update_sliders = true);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 7cae091c57..f63ae7569f 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -97,7 +97,7 @@ void AcceptDialog::_notification(int p_what) {
}
}
-void AcceptDialog::_text_entered(const String &p_text) {
+void AcceptDialog::_text_submitted(const String &p_text) {
_ok_pressed();
}
@@ -159,7 +159,7 @@ void AcceptDialog::register_text_enter(Control *p_line_edit) {
ERR_FAIL_NULL(p_line_edit);
LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit);
if (line_edit) {
- line_edit->connect("text_entered", callable_mp(this, &AcceptDialog::_text_entered));
+ line_edit->connect("text_submitted", callable_mp(this, &AcceptDialog::_text_submitted));
}
}
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 69035001c0..d389806fff 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -69,7 +69,7 @@ protected:
virtual void custom_action(const String &) {}
// Not private since used by derived classes signal.
- void _text_entered(const String &p_text);
+ void _text_submitted(const String &p_text);
void _ok_pressed();
void _cancel_pressed();
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 806039d7ac..f8cee6daec 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -116,7 +116,7 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
invalidate();
} break;
case KEY_BACKSPACE: {
- _dir_entered("..");
+ _dir_submitted("..");
} break;
default: {
handled = false;
@@ -156,7 +156,7 @@ void FileDialog::update_dir() {
deselect_all();
}
-void FileDialog::_dir_entered(String p_dir) {
+void FileDialog::_dir_submitted(String p_dir) {
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
@@ -164,7 +164,7 @@ void FileDialog::_dir_entered(String p_dir) {
_push_history();
}
-void FileDialog::_file_entered(const String &p_file) {
+void FileDialog::_file_submitted(const String &p_file) {
_action_pressed();
}
@@ -1020,8 +1020,8 @@ FileDialog::FileDialog() {
tree->connect("cell_selected", callable_mp(this, &FileDialog::_tree_selected), varray(), CONNECT_DEFERRED);
tree->connect("item_activated", callable_mp(this, &FileDialog::_tree_item_activated), varray());
tree->connect("nothing_selected", callable_mp(this, &FileDialog::deselect_all));
- dir->connect("text_entered", callable_mp(this, &FileDialog::_dir_entered));
- file->connect("text_entered", callable_mp(this, &FileDialog::_file_entered));
+ dir->connect("text_submitted", callable_mp(this, &FileDialog::_dir_submitted));
+ file->connect("text_submitted", callable_mp(this, &FileDialog::_file_submitted));
filter->connect("item_selected", callable_mp(this, &FileDialog::_filter_selected));
confirm_save = memnew(ConfirmationDialog);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 55774b488c..7fbafc4bb4 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -118,8 +118,8 @@ private:
void _select_drive(int p_idx);
void _tree_item_activated();
- void _dir_entered(String p_dir);
- void _file_entered(const String &p_file);
+ void _dir_submitted(String p_dir);
+ void _file_submitted(const String &p_file);
void _action_pressed();
void _save_confirm_pressed();
void _cancel_pressed();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index c2ed9c1a3c..089893e63b 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -357,9 +357,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
}
- // Default is ENTER, KP_ENTER. Cannot use ui_accept as default includes SPACE
- if (k->is_action("ui_text_newline", true)) {
- emit_signal("text_entered", text);
+ // Default is ENTER and KP_ENTER. Cannot use ui_accept as default includes SPACE
+ if (k->is_action("ui_text_submit", false)) {
+ emit_signal("text_submitted", text);
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
}
@@ -2159,7 +2159,7 @@ void LineEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_change_rejected"));
- ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
+ ADD_SIGNAL(MethodInfo("text_submitted", PropertyInfo(Variant::STRING, "new_text")));
BIND_ENUM_CONSTANT(ALIGN_LEFT);
BIND_ENUM_CONSTANT(ALIGN_CENTER);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index a2c3b4ed8a..987d05bf71 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -3452,7 +3452,30 @@ void RichTextLabel::set_selection_enabled(bool p_enabled) {
}
}
-bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to) {
+bool RichTextLabel::_search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search) {
+ List<Item *>::Element *E = p_from;
+ while (E != nullptr) {
+ ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
+ ItemFrame *frame = static_cast<ItemFrame *>(E->get());
+ if (p_reverse_search) {
+ for (int i = frame->lines.size() - 1; i >= 0; i--) {
+ if (_search_line(frame, i, p_string, -1, p_reverse_search)) {
+ return true;
+ }
+ }
+ } else {
+ for (int i = 0; i < frame->lines.size(); i++) {
+ if (_search_line(frame, i, p_string, 0, p_reverse_search)) {
+ return true;
+ }
+ }
+ }
+ E = p_reverse_search ? E->prev() : E->next();
+ }
+ return false;
+}
+
+bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search) {
ERR_FAIL_COND_V(p_frame == nullptr, false);
ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), false);
@@ -3474,24 +3497,23 @@ bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p
} break;
case ITEM_TABLE: {
ItemTable *table = static_cast<ItemTable *>(it);
- int idx = 0;
- for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) {
- ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
- ItemFrame *frame = static_cast<ItemFrame *>(E->get());
-
- for (int i = 0; i < frame->lines.size(); i++) {
- if (_search_line(frame, i, p_string, p_from, p_to)) {
- return true;
- }
- }
- idx++;
+ List<Item *>::Element *E = p_reverse_search ? table->subitems.back() : table->subitems.front();
+ if (_search_table(table, E, p_string, p_reverse_search)) {
+ return true;
}
} break;
default:
break;
}
}
- int sp = text.findn(p_string, 0);
+
+ int sp = -1;
+ if (p_reverse_search) {
+ sp = text.rfindn(p_string, p_char_idx);
+ } else {
+ sp = text.findn(p_string, p_char_idx);
+ }
+
if (sp != -1) {
selection.from_frame = p_frame;
selection.from_line = p_line;
@@ -3499,8 +3521,8 @@ bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p
selection.from_char = sp;
selection.to_frame = p_frame;
selection.to_line = p_line;
- selection.to_item = _get_item_at_pos(l.from, it_to, sp + p_string.length() - 1);
- selection.to_char = sp + p_string.length() - 1;
+ selection.to_item = _get_item_at_pos(l.from, it_to, sp + p_string.length());
+ selection.to_char = sp + p_string.length();
selection.active = true;
return true;
}
@@ -3511,23 +3533,81 @@ bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p
bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p_search_previous) {
ERR_FAIL_COND_V(!selection.enabled, false);
+ if (p_string.size() == 0) {
+ selection.active = false;
+ return false;
+ }
+
+ int char_idx = p_search_previous ? -1 : 0;
+ int current_line = 0;
+ int ending_line = main->lines.size() - 1;
if (p_from_selection && selection.active) {
- for (int i = 0; i < main->lines.size(); i++) {
- if (_search_line(main, i, p_string, selection.from_item, selection.to_item)) {
- update();
- return true;
- }
+ // First check to see if other results exist in current line
+ char_idx = p_search_previous ? selection.from_char - 1 : selection.to_char;
+ if (!(p_search_previous && char_idx < 0) &&
+ _search_line(selection.from_frame, selection.from_line, p_string, char_idx, p_search_previous)) {
+ scroll_to_line(selection.from_frame->line + selection.from_line);
+ update();
+ return true;
}
- } else {
- for (int i = 0; i < main->lines.size(); i++) {
- if (_search_line(main, i, p_string, nullptr, nullptr)) {
- update();
- return true;
+ char_idx = p_search_previous ? -1 : 0;
+
+ // Next, check to see if the current search result is in a table
+ if (selection.from_frame->parent != nullptr && selection.from_frame->parent->type == ITEM_TABLE) {
+ // Find last search result in table
+ ItemTable *parent_table = static_cast<ItemTable *>(selection.from_frame->parent);
+ List<Item *>::Element *parent_element = p_search_previous ? parent_table->subitems.back() : parent_table->subitems.front();
+
+ while (parent_element->get() != selection.from_frame) {
+ parent_element = p_search_previous ? parent_element->prev() : parent_element->next();
+ ERR_FAIL_COND_V(parent_element == nullptr, false);
+ }
+
+ // Search remainder of table
+ if (!(p_search_previous && parent_element == parent_table->subitems.front()) &&
+ parent_element != parent_table->subitems.back()) {
+ parent_element = p_search_previous ? parent_element->prev() : parent_element->next(); // Don't want to search current item
+ ERR_FAIL_COND_V(parent_element == nullptr, false);
+
+ // Search for next element
+ if (_search_table(parent_table, parent_element, p_string, p_search_previous)) {
+ scroll_to_line(selection.from_frame->line + selection.from_line);
+ update();
+ return true;
+ }
}
}
+
+ ending_line = selection.from_frame->line + selection.from_line;
+ current_line = p_search_previous ? ending_line - 1 : ending_line + 1;
+ } else if (p_search_previous) {
+ current_line = ending_line;
+ ending_line = 0;
}
- return false;
+ // Search remainder of the file
+ while (current_line != ending_line) {
+ // Wrap around
+ if (current_line < 0) {
+ current_line = main->lines.size() - 1;
+ } else if (current_line >= main->lines.size()) {
+ current_line = 0;
+ }
+
+ if (_search_line(main, current_line, p_string, char_idx, p_search_previous)) {
+ scroll_to_line(current_line);
+ update();
+ return true;
+ }
+ p_search_previous ? current_line-- : current_line++;
+ }
+
+ if (p_from_selection && selection.active) {
+ // Check contents of selection
+ return _search_line(main, current_line, p_string, char_idx, p_search_previous);
+ } else {
+ return false;
+ }
}
String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) const {
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index e3e457d1f2..9cf94b0cd7 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -392,7 +392,8 @@ private:
void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr);
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
- bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to);
+ bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
+ bool _search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search);
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 9dc2afdb2d..4ac73ae6b5 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -50,7 +50,7 @@ void SpinBox::_value_changed(double) {
line_edit->set_text(value);
}
-void SpinBox::_text_entered(const String &p_string) {
+void SpinBox::_text_submitted(const String &p_string) {
Ref<Expression> expr;
expr.instance();
@@ -172,7 +172,7 @@ void SpinBox::_line_edit_focus_exit() {
return;
}
- _text_entered(line_edit->get_text());
+ _text_submitted(line_edit->get_text());
}
inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) {
@@ -251,7 +251,7 @@ bool SpinBox::is_editable() const {
}
void SpinBox::apply() {
- _text_entered(line_edit->get_text());
+ _text_submitted(line_edit->get_text());
}
void SpinBox::_bind_methods() {
@@ -283,7 +283,7 @@ SpinBox::SpinBox() {
line_edit->set_align(LineEdit::ALIGN_LEFT);
//connect("value_changed",this,"_value_changed");
- line_edit->connect("text_entered", callable_mp(this, &SpinBox::_text_entered), Vector<Variant>(), CONNECT_DEFERRED);
+ line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), Vector<Variant>(), CONNECT_DEFERRED);
line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED);
line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input));
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index e116adb64c..fb10379296 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -45,7 +45,7 @@ class SpinBox : public Range {
void _range_click_timeout();
void _release_mouse();
- void _text_entered(const String &p_string);
+ void _text_submitted(const String &p_string);
virtual void _value_changed(double) override;
String prefix;
String suffix;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 07ccad70b1..6f78d586f1 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -137,8 +137,11 @@ void TextEdit::Text::set_draw_control_chars(bool p_draw_control_chars) {
draw_control_chars = p_draw_control_chars;
}
-int TextEdit::Text::get_line_width(int p_line) const {
+int TextEdit::Text::get_line_width(int p_line, int p_wrap_index) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
+ if (p_wrap_index != -1) {
+ return text[p_line].data_buf->get_line_width(p_wrap_index);
+ }
return text[p_line].data_buf->get_size().x;
}
@@ -1354,7 +1357,8 @@ void TextEdit::_notification(int p_what) {
}
}
- if (line_wrap_index == line_wrap_amount && is_folded(line)) {
+ // is_line_folded
+ if (line_wrap_index == line_wrap_amount && line < text.size() - 1 && is_line_hidden(line + 1)) {
int xofs = char_ofs + char_margin + ofs_x + (cache.folded_eol_icon->get_width() / 2);
if (xofs >= xmargin_beg && xofs < xmargin_end) {
int yofs = (text_height - cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
@@ -1943,10 +1947,6 @@ void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
}
}
- if (is_folded(cursor.line)) {
- unfold_line(cursor.line);
- }
-
bool brace_indent = false;
// No need to indent if we are going upwards.
@@ -2361,10 +2361,6 @@ void TextEdit::_backspace(bool p_word, bool p_all_to_left) {
cursor_set_line(line, false);
cursor_set_column(column);
} else {
- // One character.
- if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) {
- unfold_line(cursor.line - 1);
- }
backspace_at_cursor();
}
}
@@ -2692,15 +2688,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
left_margin += gutters[i].width;
}
- // Unfold on folded icon click.
- if (is_folded(row)) {
- left_margin += gutter_padding + text.get_line_width(row) - cursor.x_ofs;
- if (mpos.x > left_margin && mpos.x <= left_margin + cache.folded_eol_icon->get_width() + 3) {
- unfold_line(row);
- return;
- }
- }
-
// minimap
if (draw_minimap) {
_update_minimap_click();
@@ -3703,10 +3690,6 @@ void TextEdit::center_viewport_to_cursor() {
scrolling = false;
minimap_clicked = false;
- if (is_line_hidden(cursor.line)) {
- unfold_line(cursor.line);
- }
-
set_line_as_center_visible(cursor.line, get_cursor_wrap_index());
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.minimap_width;
if (v_scroll->is_visible_in_tree()) {
@@ -4124,15 +4107,6 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
if (draw_minimap && p_pos.x > xmargin_end - minimap_width && p_pos.x <= xmargin_end) {
return CURSOR_ARROW;
}
-
- // EOL fold icon.
- if (is_folded(row)) {
- gutter += gutter_padding + text.get_line_width(row) - cursor.x_ofs;
- if (p_pos.x > gutter - 3 && p_pos.x <= gutter + cache.folded_eol_icon->get_width() + 3) {
- return CURSOR_POINTING_HAND;
- }
- }
-
return get_default_cursor_shape();
}
@@ -4318,6 +4292,10 @@ String TextEdit::get_line(int line) const {
return text[line];
};
+bool TextEdit::has_ime_text() const {
+ return !ime_text.is_empty();
+}
+
void TextEdit::_clear() {
clear_undo_history();
text.clear();
@@ -4404,7 +4382,7 @@ void TextEdit::_update_caches() {
cache.selection_color = get_theme_color("selection_color");
cache.current_line_color = get_theme_color("current_line_color");
cache.line_length_guideline_color = get_theme_color("line_length_guideline_color");
- cache.code_folding_color = get_theme_color("code_folding_color");
+ cache.code_folding_color = get_theme_color("code_folding_color", "CodeEdit");
cache.brace_mismatch_color = get_theme_color("brace_mismatch_color");
cache.word_highlighted_color = get_theme_color("word_highlighted_color");
cache.search_result_color = get_theme_color("search_result_color");
@@ -4417,7 +4395,7 @@ void TextEdit::_update_caches() {
#endif
cache.tab_icon = get_theme_icon("tab");
cache.space_icon = get_theme_icon("space");
- cache.folded_eol_icon = get_theme_icon("GuiEllipsis", "EditorIcons");
+ cache.folded_eol_icon = get_theme_icon("folded_eol_icon", "CodeEdit");
TextServer::Direction dir;
if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
@@ -4526,6 +4504,10 @@ int TextEdit::get_gutter_width(int p_gutter) const {
return gutters[p_gutter].width;
}
+int TextEdit::get_total_gutter_width() const {
+ return gutters_width + gutter_padding;
+}
+
void TextEdit::set_gutter_draw(int p_gutter, bool p_draw) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
gutters.write[p_gutter].draw = p_draw;
@@ -5107,14 +5089,6 @@ bool TextEdit::is_line_hidden(int p_line) const {
return text.is_hidden(p_line);
}
-void TextEdit::fold_all_lines() {
- for (int i = 0; i < text.size(); i++) {
- fold_line(i);
- }
- _update_scrollbars();
- update();
-}
-
void TextEdit::unhide_all_lines() {
for (int i = 0; i < text.size(); i++) {
text.set_hidden(i, false);
@@ -5262,151 +5236,14 @@ bool TextEdit::is_line_comment(int p_line) const {
return false;
}
-bool TextEdit::can_fold(int p_line) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), false);
- if (!is_hiding_enabled()) {
- return false;
- }
- if (p_line + 1 >= text.size()) {
- return false;
- }
- if (text[p_line].strip_edges().size() == 0) {
- return false;
- }
- if (is_folded(p_line)) {
- return false;
- }
- if (is_line_hidden(p_line)) {
- return false;
- }
- if (is_line_comment(p_line)) {
- return false;
- }
-
- int start_indent = get_indent_level(p_line);
-
- for (int i = p_line + 1; i < text.size(); i++) {
- if (text[i].strip_edges().size() == 0) {
- continue;
- }
- int next_indent = get_indent_level(i);
- if (is_line_comment(i)) {
- continue;
- } else if (next_indent > start_indent) {
- return true;
- } else {
- return false;
- }
- }
-
- return false;
-}
-
-bool TextEdit::is_folded(int p_line) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), false);
- if (p_line + 1 >= text.size()) {
- return false;
- }
- return !is_line_hidden(p_line) && is_line_hidden(p_line + 1);
-}
-
-Vector<int> TextEdit::get_folded_lines() const {
- Vector<int> folded_lines;
-
- for (int i = 0; i < text.size(); i++) {
- if (is_folded(i)) {
- folded_lines.push_back(i);
- }
- }
- return folded_lines;
-}
-
-void TextEdit::fold_line(int p_line) {
- ERR_FAIL_INDEX(p_line, text.size());
- if (!is_hiding_enabled()) {
- return;
- }
- if (!can_fold(p_line)) {
- return;
- }
-
- // Hide lines below this one.
- int start_indent = get_indent_level(p_line);
- int last_line = start_indent;
- for (int i = p_line + 1; i < text.size(); i++) {
- if (text[i].strip_edges().size() != 0) {
- if (is_line_comment(i)) {
- continue;
- } else if (get_indent_level(i) > start_indent) {
- last_line = i;
- } else {
- break;
- }
- }
- }
- for (int i = p_line + 1; i <= last_line; i++) {
- set_line_as_hidden(i, true);
- }
-
- // Fix selection.
- if (is_selection_active()) {
- if (is_line_hidden(selection.from_line) && is_line_hidden(selection.to_line)) {
- deselect();
- } else if (is_line_hidden(selection.from_line)) {
- select(p_line, 9999, selection.to_line, selection.to_column);
- } else if (is_line_hidden(selection.to_line)) {
- select(selection.from_line, selection.from_column, p_line, 9999);
- }
- }
-
- // Reset cursor.
- if (is_line_hidden(cursor.line)) {
- cursor_set_line(p_line, false, false);
- cursor_set_column(get_line(p_line).length(), false);
- }
- _update_scrollbars();
- update();
-}
-
-void TextEdit::unfold_line(int p_line) {
- ERR_FAIL_INDEX(p_line, text.size());
-
- if (!is_folded(p_line) && !is_line_hidden(p_line)) {
- return;
- }
- int fold_start;
- for (fold_start = p_line; fold_start > 0; fold_start--) {
- if (is_folded(fold_start)) {
- break;
- }
- }
- fold_start = is_folded(fold_start) ? fold_start : p_line;
-
- for (int i = fold_start + 1; i < text.size(); i++) {
- if (is_line_hidden(i)) {
- set_line_as_hidden(i, false);
- } else {
- break;
- }
- }
- _update_scrollbars();
- update();
-}
-
-void TextEdit::toggle_fold_line(int p_line) {
- ERR_FAIL_INDEX(p_line, text.size());
-
- if (!is_folded(p_line)) {
- fold_line(p_line);
- } else {
- unfold_line(p_line);
- }
-}
-
int TextEdit::get_line_count() const {
return text.size();
}
+int TextEdit::get_line_width(int p_line, int p_wrap_offset) const {
+ return text.get_line_width(p_line, p_wrap_offset);
+}
+
void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
ERR_FAIL_COND(p_op.type == TextOperation::TYPE_NONE);
@@ -6270,18 +6107,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_spaces"), &TextEdit::set_draw_spaces);
ClassDB::bind_method(D_METHOD("is_drawing_spaces"), &TextEdit::is_drawing_spaces);
- ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled);
- ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled);
- ClassDB::bind_method(D_METHOD("set_line_as_hidden", "line", "enable"), &TextEdit::set_line_as_hidden);
- ClassDB::bind_method(D_METHOD("is_line_hidden", "line"), &TextEdit::is_line_hidden);
- ClassDB::bind_method(D_METHOD("fold_all_lines"), &TextEdit::fold_all_lines);
- ClassDB::bind_method(D_METHOD("unhide_all_lines"), &TextEdit::unhide_all_lines);
- ClassDB::bind_method(D_METHOD("fold_line", "line"), &TextEdit::fold_line);
- ClassDB::bind_method(D_METHOD("unfold_line", "line"), &TextEdit::unfold_line);
- ClassDB::bind_method(D_METHOD("toggle_fold_line", "line"), &TextEdit::toggle_fold_line);
- ClassDB::bind_method(D_METHOD("can_fold", "line"), &TextEdit::can_fold);
- ClassDB::bind_method(D_METHOD("is_folded", "line"), &TextEdit::is_folded);
-
ClassDB::bind_method(D_METHOD("set_highlight_all_occurrences", "enable"), &TextEdit::set_highlight_all_occurrences);
ClassDB::bind_method(D_METHOD("is_highlight_all_occurrences_enabled"), &TextEdit::is_highlight_all_occurrences_enabled);
@@ -6365,7 +6190,6 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_vertical"), "set_v_scroll", "get_v_scroll");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index f963e664d1..c04d758abb 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -124,7 +124,7 @@ private:
void set_draw_control_chars(bool p_draw_control_chars);
int get_line_height(int p_line, int p_wrap_index) const;
- int get_line_width(int p_line) const;
+ int get_line_width(int p_line, int p_wrap_index = -1) const;
int get_max_width(bool p_exclude_hidden = false) const;
void set_width(float p_width);
@@ -349,11 +349,8 @@ private:
void update_cursor_wrap_offset();
void _update_wrap_at(bool p_force = false);
- bool line_wraps(int line) const;
- int times_line_wraps(int line) const;
Vector<String> get_wrap_rows_text(int p_line) const;
int get_cursor_wrap_index() const;
- int get_line_wrap_index_at_col(int p_line, int p_column) const;
int get_char_count();
double get_scroll_pos_for_line(int p_line, int p_wrap_index = 0) const;
@@ -514,6 +511,7 @@ public:
void set_gutter_width(int p_gutter, int p_width);
int get_gutter_width(int p_gutter) const;
+ int get_total_gutter_width() const;
void set_gutter_draw(int p_gutter, bool p_draw);
bool is_gutter_drawn(int p_gutter) const;
@@ -622,24 +620,19 @@ public:
void insert_text_at_cursor(const String &p_text);
void insert_at(const String &p_text, int at);
int get_line_count() const;
+ int get_line_width(int p_line, int p_wrap_offset = -1) const;
+ int get_line_wrap_index_at_col(int p_line, int p_column) const;
void set_line_as_hidden(int p_line, bool p_hidden);
bool is_line_hidden(int p_line) const;
- void fold_all_lines();
void unhide_all_lines();
int num_lines_from(int p_line_from, int visible_amount) const;
int num_lines_from_rows(int p_line_from, int p_wrap_index_from, int visible_amount, int &wrap_index) const;
int get_last_unhidden_line() const;
- bool can_fold(int p_line) const;
- bool is_folded(int p_line) const;
- Vector<int> get_folded_lines() const;
- void fold_line(int p_line);
- void unfold_line(int p_line);
- void toggle_fold_line(int p_line);
-
String get_text();
String get_line(int line) const;
+ bool has_ime_text() const;
void set_line(int line, String new_text);
int get_row_height() const;
void backspace_at_cursor();
@@ -701,6 +694,8 @@ public:
void set_wrap_enabled(bool p_wrap_enabled);
bool is_wrap_enabled() const;
+ bool line_wraps(int line) const;
+ int times_line_wraps(int line) const;
void clear();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index f66cc13af5..26d881955b 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2451,10 +2451,10 @@ void Tree::_text_editor_modal_close() {
return;
}
- _text_editor_enter(text_editor->get_text());
+ _text_editor_submit(text_editor->get_text());
}
-void Tree::_text_editor_enter(String p_text) {
+void Tree::_text_editor_submit(String p_text) {
popup_editor->hide();
if (!popup_edited_item) {
@@ -4554,7 +4554,7 @@ Tree::Tree() {
h_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
v_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
- text_editor->connect("text_entered", callable_mp(this, &Tree::_text_editor_enter));
+ text_editor->connect("text_submitted", callable_mp(this, &Tree::_text_editor_submit));
popup_editor->connect("popup_hide", callable_mp(this, &Tree::_text_editor_modal_close));
popup_menu->connect("id_pressed", callable_mp(this, &Tree::popup_select));
value_editor->connect("value_changed", callable_mp(this, &Tree::value_editor_changed));
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 5176d01497..0571a605a5 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -449,7 +449,7 @@ private:
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = nullptr, bool *r_in_range = nullptr, bool p_force_deselect = false);
int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
- void _text_editor_enter(String p_text);
+ void _text_editor_submit(String p_text);
void _text_editor_modal_close();
void value_editor_changed(double p_value);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index e4ba93feec..f588e000f9 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -413,7 +413,6 @@ bool SceneTree::physics_process(float p_time) {
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
flush_transform_notifications();
- call_group_flags(GROUP_CALL_REALTIME, "_viewports", "update_worlds");
root_lock--;
_flush_delete_queue();
@@ -445,7 +444,6 @@ bool SceneTree::process(float p_time) {
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
flush_transform_notifications(); //transforms after world update, to avoid unnecessary enter/exit notifications
- call_group_flags(GROUP_CALL_REALTIME, "_viewports", "update_worlds");
root_lock--;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 425fbf0d6a..59ec0e6345 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -183,14 +183,6 @@ public:
/////////////////////////////////////
-void Viewport::update_worlds() {
- if (!is_inside_tree()) {
- return;
- }
-
- find_world_3d()->_update(get_tree()->get_frame());
-}
-
void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
Transform3D object_transform = p_object->get_global_transform();
Transform3D camera_transform = p_camera->get_global_transform();
@@ -3513,8 +3505,6 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("input", "event", "in_local_coords"), &Viewport::input, DEFVAL(false));
ClassDB::bind_method(D_METHOD("unhandled_input", "event", "in_local_coords"), &Viewport::unhandled_input, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
-
ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 2d7f5101c2..d905e44a82 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -397,8 +397,6 @@ private:
void _gui_input_event(Ref<InputEvent> p_event);
- void update_worlds();
-
_FORCE_INLINE_ Transform2D _get_input_pre_xform() const;
Ref<InputEvent> _make_input_local(const Ref<InputEvent> &ev);
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index b91a5c0b7f..a4228d48b4 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -445,7 +445,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_readonly_color", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1));
theme->set_color("selection_color", "TextEdit", control_selection_color);
- theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "TextEdit", control_font_color);
theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0));
@@ -469,6 +468,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("executing_line", "CodeEdit", make_icon(arrow_right_png));
theme->set_icon("can_fold", "CodeEdit", make_icon(arrow_down_png));
theme->set_icon("folded", "CodeEdit", make_icon(arrow_right_png));
+ theme->set_icon("folded_eol_icon", "CodeEdit", make_icon(ellipsis_png));
theme->set_font("font", "CodeEdit", Ref<Font>());
theme->set_font_size("font_size", "CodeEdit", -1);
@@ -487,8 +487,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3));
theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
- theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
+ theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("caret_color", "CodeEdit", control_font_color);
theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0));
theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2));
diff --git a/scene/resources/default_theme/ellipsis.png b/scene/resources/default_theme/ellipsis.png
new file mode 100644
index 0000000000..c949e2c95b
--- /dev/null
+++ b/scene/resources/default_theme/ellipsis.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 190f2a03d9..7d747e3c9e 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -74,6 +74,10 @@ static const unsigned char dropdown_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x60, 0xf8, 0xc0, 0xcc, 0x0, 0x2, 0x60, 0x16, 0x98, 0x78, 0x67, 0x8, 0x81, 0x6f, 0x4d, 0xde, 0x9a, 0x0, 0x5, 0xde, 0x3a, 0x3d, 0xfc, 0x8f, 0x80, 0xaf, 0xba, 0x18, 0xde, 0x29, 0x2, 0x19, 0xbf, 0x61, 0x2, 0x6f, 0x62, 0x18, 0x3e, 0xb0, 0xbd, 0x97, 0x4, 0x32, 0xff, 0x80, 0xb9, 0xb1, 0x20, 0x93, 0xc0, 0x42, 0x8, 0x2e, 0x54, 0xe8, 0x9d, 0xdc, 0x9b, 0x54, 0x10, 0xb, 0x21, 0xc4, 0x4, 0x63, 0x1, 0x0, 0x86, 0x1f, 0x3b, 0x1e, 0x92, 0x22, 0x3f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char ellipsis_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc9, 0x11, 0xce, 0xcc, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x78, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x95, 0xd1, 0x31, 0xa, 0xc2, 0x50, 0x10, 0x4, 0xd0, 0xb7, 0x1f, 0xf, 0x60, 0x67, 0xa, 0xf, 0x12, 0x6f, 0x60, 0xe9, 0x51, 0x5, 0x3d, 0x44, 0xee, 0x61, 0xa1, 0xa5, 0xf6, 0x81, 0xb5, 0xc8, 0x47, 0x82, 0x84, 0x4f, 0xb2, 0xdd, 0xb0, 0x33, 0xb3, 0xb3, 0x4c, 0x40, 0x66, 0xee, 0x71, 0xc2, 0x1, 0x3b, 0xcb, 0x33, 0xe2, 0x85, 0x21, 0x22, 0xde, 0x51, 0x45, 0x97, 0x86, 0x60, 0xc9, 0xe0, 0x5a, 0xea, 0xa5, 0xb5, 0x22, 0x95, 0xdb, 0x97, 0x1a, 0xf, 0x6e, 0xb8, 0xcf, 0x8, 0x2d, 0xdc, 0x95, 0xd9, 0x22, 0xfe, 0x9c, 0x9b, 0x38, 0x32, 0xf3, 0x8c, 0xe3, 0x86, 0xa8, 0xf0, 0x28, 0x18, 0x4c, 0xf, 0xaf, 0x9d, 0x11, 0x43, 0xf0, 0xab, 0xa3, 0x47, 0xa7, 0x5d, 0xc7, 0xd3, 0x54, 0xc7, 0xe7, 0xb, 0xb9, 0xce, 0x1f, 0xc6, 0x2d, 0x99, 0x55, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char error_icon_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x1, 0x14, 0xc2, 0xc0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index e811cbf57a..a85bd8fdba 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -37,206 +37,15 @@
#include "scene/scene_string_names.h"
#include "servers/navigation_server_3d.h"
-struct SpatialIndexer {
- Octree<VisibilityNotifier3D> octree;
-
- struct NotifierData {
- AABB aabb;
- OctreeElementID id;
- };
-
- Map<VisibilityNotifier3D *, NotifierData> notifiers;
- struct CameraData {
- Map<VisibilityNotifier3D *, uint64_t> notifiers;
- };
-
- Map<Camera3D *, CameraData> cameras;
-
- enum {
- VISIBILITY_CULL_MAX = 32768
- };
-
- Vector<VisibilityNotifier3D *> cull;
-
- bool changed;
- uint64_t pass;
- uint64_t last_frame;
-
- void _notifier_add(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
- ERR_FAIL_COND(notifiers.has(p_notifier));
- notifiers[p_notifier].aabb = p_rect;
- notifiers[p_notifier].id = octree.create(p_notifier, p_rect);
- changed = true;
- }
-
- void _notifier_update(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
- Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
- ERR_FAIL_COND(!E);
- if (E->get().aabb == p_rect) {
- return;
- }
-
- E->get().aabb = p_rect;
- octree.move(E->get().id, E->get().aabb);
- changed = true;
- }
-
- void _notifier_remove(VisibilityNotifier3D *p_notifier) {
- Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
- ERR_FAIL_COND(!E);
-
- octree.erase(E->get().id);
- notifiers.erase(p_notifier);
-
- List<Camera3D *> removed;
- for (Map<Camera3D *, CameraData>::Element *F = cameras.front(); F; F = F->next()) {
- Map<VisibilityNotifier3D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
-
- if (G) {
- F->get().notifiers.erase(G);
- removed.push_back(F->key());
- }
- }
-
- while (!removed.is_empty()) {
- p_notifier->_exit_camera(removed.front()->get());
- removed.pop_front();
- }
-
- changed = true;
- }
-
- void _add_camera(Camera3D *p_camera) {
- ERR_FAIL_COND(cameras.has(p_camera));
- CameraData vd;
- cameras[p_camera] = vd;
- changed = true;
- }
-
- void _update_camera(Camera3D *p_camera) {
- Map<Camera3D *, CameraData>::Element *E = cameras.find(p_camera);
- ERR_FAIL_COND(!E);
- changed = true;
- }
-
- void _remove_camera(Camera3D *p_camera) {
- ERR_FAIL_COND(!cameras.has(p_camera));
- List<VisibilityNotifier3D *> removed;
- for (Map<VisibilityNotifier3D *, uint64_t>::Element *E = cameras[p_camera].notifiers.front(); E; E = E->next()) {
- removed.push_back(E->key());
- }
-
- while (!removed.is_empty()) {
- removed.front()->get()->_exit_camera(p_camera);
- removed.pop_front();
- }
-
- cameras.erase(p_camera);
- }
-
- void _update(uint64_t p_frame) {
- if (p_frame == last_frame) {
- return;
- }
- last_frame = p_frame;
-
- if (!changed) {
- return;
- }
-
- for (Map<Camera3D *, CameraData>::Element *E = cameras.front(); E; E = E->next()) {
- pass++;
-
- Camera3D *c = E->key();
-
- Vector<Plane> planes = c->get_frustum();
-
- int culled = octree.cull_convex(planes, cull.ptrw(), cull.size());
-
- VisibilityNotifier3D **ptr = cull.ptrw();
-
- List<VisibilityNotifier3D *> added;
- List<VisibilityNotifier3D *> removed;
-
- for (int i = 0; i < culled; i++) {
- //notifiers in frustum
-
- Map<VisibilityNotifier3D *, uint64_t>::Element *H = E->get().notifiers.find(ptr[i]);
- if (!H) {
- E->get().notifiers.insert(ptr[i], pass);
- added.push_back(ptr[i]);
- } else {
- H->get() = pass;
- }
- }
-
- for (Map<VisibilityNotifier3D *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
- if (F->get() != pass) {
- removed.push_back(F->key());
- }
- }
-
- while (!added.is_empty()) {
- added.front()->get()->_enter_camera(E->key());
- added.pop_front();
- }
-
- while (!removed.is_empty()) {
- E->get().notifiers.erase(removed.front()->get());
- removed.front()->get()->_exit_camera(E->key());
- removed.pop_front();
- }
- }
- changed = false;
- }
-
- SpatialIndexer() {
- pass = 0;
- last_frame = 0;
- changed = false;
- cull.resize(VISIBILITY_CULL_MAX);
- }
-};
-
void World3D::_register_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
- indexer->_add_camera(p_camera);
-#endif
-}
-
-void World3D::_update_camera(Camera3D *p_camera) {
-#ifndef _3D_DISABLED
- indexer->_update_camera(p_camera);
+ cameras.insert(p_camera);
#endif
}
void World3D::_remove_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
- indexer->_remove_camera(p_camera);
-#endif
-}
-
-void World3D::_register_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-#ifndef _3D_DISABLED
- indexer->_notifier_add(p_notifier, p_rect);
-#endif
-}
-
-void World3D::_update_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-#ifndef _3D_DISABLED
- indexer->_notifier_update(p_notifier, p_rect);
-#endif
-}
-
-void World3D::_remove_notifier(VisibilityNotifier3D *p_notifier) {
-#ifndef _3D_DISABLED
- indexer->_notifier_remove(p_notifier);
-#endif
-}
-
-void World3D::_update(uint64_t p_frame) {
-#ifndef _3D_DISABLED
- indexer->_update(p_frame);
+ cameras.erase(p_camera);
#endif
}
@@ -307,12 +116,6 @@ PhysicsDirectSpaceState3D *World3D::get_direct_space_state() {
return PhysicsServer3D::get_singleton()->space_get_direct_state(space);
}
-void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
- for (Map<Camera3D *, SpatialIndexer::CameraData>::Element *E = indexer->cameras.front(); E; E = E->next()) {
- r_cameras->push_back(E->key());
- }
-}
-
void World3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map);
@@ -349,20 +152,10 @@ World3D::World3D() {
NavigationServer3D::get_singleton()->map_set_active(navigation_map, true);
NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.3));
NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 0.3));
-
-#ifdef _3D_DISABLED
- indexer = nullptr;
-#else
- indexer = memnew(SpatialIndexer);
-#endif
}
World3D::~World3D() {
PhysicsServer3D::get_singleton()->free(space);
RenderingServer::get_singleton()->free(scenario);
NavigationServer3D::get_singleton()->free(navigation_map);
-
-#ifndef _3D_DISABLED
- memdelete(indexer);
-#endif
}
diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h
index 4e2717a2bb..da5ed486b0 100644
--- a/scene/resources/world_3d.h
+++ b/scene/resources/world_3d.h
@@ -48,27 +48,21 @@ private:
RID space;
RID navigation_map;
RID scenario;
- SpatialIndexer *indexer;
+
Ref<Environment> environment;
Ref<Environment> fallback_environment;
Ref<CameraEffects> camera_effects;
+ Set<Camera3D *> cameras;
+
protected:
static void _bind_methods();
friend class Camera3D;
- friend class VisibilityNotifier3D;
void _register_camera(Camera3D *p_camera);
- void _update_camera(Camera3D *p_camera);
void _remove_camera(Camera3D *p_camera);
- void _register_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect);
- void _update_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect);
- void _remove_notifier(VisibilityNotifier3D *p_notifier);
- friend class Viewport;
- void _update(uint64_t p_frame);
-
public:
RID get_space() const;
RID get_navigation_map() const;
@@ -83,7 +77,7 @@ public:
void set_camera_effects(const Ref<CameraEffects> &p_camera_effects);
Ref<CameraEffects> get_camera_effects() const;
- void get_camera_list(List<Camera3D *> *r_cameras);
+ _FORCE_INLINE_ const Set<Camera3D *> &get_cameras() const { return cameras; }
PhysicsDirectSpaceState3D *get_direct_space_state();
diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h
index b44088e822..d4c25b6253 100644
--- a/servers/rendering/rasterizer_dummy.h
+++ b/servers/rendering/rasterizer_dummy.h
@@ -621,9 +621,18 @@ public:
bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; }
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); }
- RID particles_collision_instance_create(RID p_collision) override { return RID(); };
- void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override{};
- void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override{};
+ RID particles_collision_instance_create(RID p_collision) override { return RID(); }
+ void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override {}
+ void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override {}
+
+ /* VISIBILITY NOTIFIER */
+ virtual RID visibility_notifier_allocate() override { return RID(); }
+ virtual void visibility_notifier_initialize(RID p_notifier) override {}
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override {}
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override {}
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
/* GLOBAL VARIABLES */
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 64be54115f..246b5f0e4c 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -5535,6 +5535,59 @@ void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_
pci->active = p_active;
}
+/* VISIBILITY NOTIFIER */
+
+RID RendererStorageRD::visibility_notifier_allocate() {
+ return visibility_notifier_owner.allocate_rid();
+}
+void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) {
+ visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
+}
+void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->aabb = p_aabb;
+ vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
+}
+void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->enter_callback = p_enter_callbable;
+ vn->exit_callback = p_exit_callable;
+}
+
+AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const {
+ const VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND_V(!vn, AABB());
+ return vn->aabb;
+}
+void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+
+ if (p_enter) {
+ if (!vn->enter_callback.is_null()) {
+ if (p_deferred) {
+ vn->enter_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->enter_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ } else {
+ if (!vn->exit_callback.is_null()) {
+ if (p_deferred) {
+ vn->exit_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->exit_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ }
+}
+
/* SKELETON API */
RID RendererStorageRD::skeleton_allocate() {
@@ -7590,6 +7643,9 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
} else if (particles_collision_owner.owns(p_base)) {
ParticlesCollision *pc = particles_collision_owner.getornull(p_base);
p_instance->update_dependency(&pc->dependency);
+ } else if (visibility_notifier_owner.owns(p_base)) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_base);
+ p_instance->update_dependency(&vn->dependency);
}
}
@@ -7628,6 +7684,9 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (particles_collision_owner.owns(p_rid)) {
return RS::INSTANCE_PARTICLES_COLLISION;
}
+ if (visibility_notifier_owner.owns(p_rid)) {
+ return RS::INSTANCE_VISIBLITY_NOTIFIER;
+ }
return RS::INSTANCE_NONE;
}
@@ -8704,6 +8763,10 @@ bool RendererStorageRD::free(RID p_rid) {
}
particles_collision->dependency.deleted_notify(p_rid);
particles_collision_owner.free(p_rid);
+ } else if (visibility_notifier_owner.owns(p_rid)) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_rid);
+ vn->dependency.deleted_notify(p_rid);
+ visibility_notifier_owner.free(p_rid);
} else if (particles_collision_instance_owner.owns(p_rid)) {
particles_collision_instance_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 28a1044705..ab470cb3a6 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -947,6 +947,17 @@ private:
mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
+ /* visibility_notifier */
+
+ struct VisibilityNotifier {
+ AABB aabb;
+ Callable enter_callback;
+ Callable exit_callback;
+ Dependency dependency;
+ };
+
+ mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
+
/* Skeleton */
struct Skeleton {
@@ -2253,6 +2264,14 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
+ virtual RID visibility_notifier_allocate();
+ virtual void visibility_notifier_initialize(RID p_notifier);
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb);
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable);
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred);
+
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision);
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform);
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index 3b25498ed8..d71425f465 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -207,6 +207,7 @@ public:
virtual void update() = 0;
virtual void render_probes() = 0;
+ virtual void update_visibility_notifiers() = 0;
virtual bool free(RID p_rid) = 0;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 2c66b22089..60c7dbf3b7 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -506,6 +506,9 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
RSG::storage->free(collision->instance);
} break;
+ case RS::INSTANCE_VISIBLITY_NOTIFIER: {
+ //none
+ } break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
scene_render->free(reflection_probe->instance);
@@ -615,6 +618,11 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
RSG::storage->particles_collision_instance_set_active(collision->instance, instance->visible);
instance->base_data = collision;
} break;
+ case RS::INSTANCE_VISIBLITY_NOTIFIER: {
+ InstanceVisibilityNotifierData *vnd = memnew(InstanceVisibilityNotifierData);
+ vnd->base = p_base;
+ instance->base_data = vnd;
+ } break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
reflection_probe->owner = instance;
@@ -1549,6 +1557,9 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
case RS::INSTANCE_VOXEL_GI: {
idata.instance_data_rid = static_cast<InstanceVoxelGIData *>(p_instance->base_data)->probe_instance.get_id();
} break;
+ case RS::INSTANCE_VISIBLITY_NOTIFIER: {
+ idata.visibility_notifier = static_cast<InstanceVisibilityNotifierData *>(p_instance->base_data);
+ } break;
default: {
}
}
@@ -1758,6 +1769,9 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
new_aabb = RSG::storage->particles_collision_get_aabb(p_instance->base);
} break;
+ case RenderingServer::INSTANCE_VISIBLITY_NOTIFIER: {
+ new_aabb = RSG::storage->visibility_notifier_get_aabb(p_instance->base);
+ } break;
case RenderingServer::INSTANCE_LIGHT: {
new_aabb = RSG::storage->light_get_aabb(p_instance->base);
@@ -2613,6 +2627,15 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
} else if (base_type == RS::INSTANCE_LIGHTMAP) {
cull_result.lightmaps.push_back(RID::from_uint64(idata.instance_data_rid));
+ } else if (base_type == RS::INSTANCE_VISIBLITY_NOTIFIER) {
+ InstanceVisibilityNotifierData *vnd = idata.visibility_notifier;
+ if (!vnd->list_element.in_list()) {
+ visible_notifier_list_lock.lock();
+ visible_notifier_list.add(&vnd->list_element);
+ visible_notifier_list_lock.unlock();
+ vnd->just_visible = true;
+ }
+ vnd->visible_in_frame = RSG::rasterizer->get_frame_number();
} else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) {
bool keep = true;
@@ -3849,6 +3872,28 @@ TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RI
return scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size);
}
+void RendererSceneCull::update_visibility_notifiers() {
+ SelfList<InstanceVisibilityNotifierData> *E = visible_notifier_list.first();
+ while (E) {
+ SelfList<InstanceVisibilityNotifierData> *N = E->next();
+
+ InstanceVisibilityNotifierData *visibility_notifier = E->self();
+ if (visibility_notifier->just_visible) {
+ visibility_notifier->just_visible = false;
+
+ RSG::storage->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
+ } else {
+ if (visibility_notifier->visible_in_frame != RSG::rasterizer->get_frame_number()) {
+ visible_notifier_list.remove(E);
+
+ RSG::storage->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
+ }
+ }
+
+ E = N;
+ }
+}
+
/*******************************/
/* Passthrough to Scene Render */
/*******************************/
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index bdfbea95a2..d9466d8b04 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -118,6 +118,8 @@ public:
virtual void occluder_initialize(RID p_occluder);
virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices);
+ /* VISIBILITY NOTIFIER API */
+
RendererSceneOcclusionCull *dummy_occlusion_culling;
/* SCENARIO API */
@@ -243,6 +245,8 @@ public:
}
};
+ struct InstanceVisibilityNotifierData;
+
struct InstanceData {
// Store instance pointer as well as common instance processing information,
// to make processing more cache friendly.
@@ -271,6 +275,7 @@ public:
union {
uint64_t instance_data_rid;
RendererSceneRender::GeometryInstance *instance_geometry;
+ InstanceVisibilityNotifierData *visibility_notifier;
};
Instance *instance = nullptr;
int32_t parent_array_index = -1;
@@ -611,6 +616,18 @@ public:
RID instance;
};
+ struct InstanceVisibilityNotifierData : public InstanceBaseData {
+ bool just_visible = false;
+ uint64_t visible_in_frame = 0;
+ RID base;
+ SelfList<InstanceVisibilityNotifierData> list_element;
+ InstanceVisibilityNotifierData() :
+ list_element(this) {}
+ };
+
+ SpinLock visible_notifier_list_lock;
+ SelfList<InstanceVisibilityNotifierData>::List visible_notifier_list;
+
struct InstanceLightData : public InstanceBaseData {
RID instance;
uint64_t last_version;
@@ -1123,6 +1140,8 @@ public:
void set_scene_render(RendererSceneRender *p_scene_render);
+ virtual void update_visibility_notifiers();
+
RendererSceneCull();
virtual ~RendererSceneCull();
};
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
index e6b9ac15ff..f22c582f48 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/renderer_storage.h
@@ -557,6 +557,14 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0;
+ virtual RID visibility_notifier_allocate() = 0;
+ virtual void visibility_notifier_initialize(RID p_notifier) = 0;
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) = 0;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) = 0;
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const = 0;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) = 0;
+
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision) = 0;
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) = 0;
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 95aa05f6b3..629d212b69 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -118,6 +118,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
RSG::rasterizer->end_frame(p_swap_buffers);
RSG::canvas->update_visibility_notifiers();
+ RSG::scene->update_visibility_notifiers();
while (frame_drawn_callbacks.front()) {
Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object);
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 73373c97bb..9404374287 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -529,6 +529,12 @@ public:
FUNC1(particles_collision_height_field_update, RID)
FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution)
+ /* VISIBILITY_NOTIFIER */
+
+ FUNCRIDSPLIT(visibility_notifier)
+ FUNC2(visibility_notifier_set_aabb, RID, const AABB &)
+ FUNC3(visibility_notifier_set_callbacks, RID, const Callable &, const Callable &)
+
#undef server_name
#undef ServerName
//from now on, calls forwarded to this singleton
@@ -549,7 +555,7 @@ public:
/* OCCLUDER */
FUNCRIDSPLIT(occluder)
- FUNC3(occluder_set_mesh, RID, const PackedVector3Array &, const PackedInt32Array &);
+ FUNC3(occluder_set_mesh, RID, const PackedVector3Array &, const PackedInt32Array &)
#undef server_name
#undef ServerName
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 0cb765ef56..ac6b0a4d1a 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -722,6 +722,17 @@ public:
virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
+ /* VISIBILITY NOTIFIER API */
+
+ virtual RID visibility_notifier_create() = 0;
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) = 0;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) = 0;
+
+ /* OCCLUDER API */
+
+ virtual RID occluder_create() = 0;
+ virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) = 0;
+
/* CAMERA API */
virtual RID camera_create() = 0;
@@ -734,11 +745,6 @@ public:
virtual void camera_set_camera_effects(RID p_camera, RID p_camera_effects) = 0;
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
- /* OCCLUDER API */
-
- virtual RID occluder_create() = 0;
- virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) = 0;
-
/* VIEWPORT TARGET API */
enum CanvasItemTextureFilter {
@@ -1148,6 +1154,7 @@ public:
INSTANCE_VOXEL_GI,
INSTANCE_LIGHTMAP,
INSTANCE_OCCLUDER,
+ INSTANCE_VISIBLITY_NOTIFIER,
INSTANCE_MAX,
INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES)