diff options
48 files changed, 284 insertions, 150 deletions
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 8ee09ba8f8..b46719c758 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -43,7 +43,7 @@ You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dict["White"][/code] will return [code]50[/code]. You can also write [code]points_dict.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable). [codeblocks] [gdscript] - export(string, "White", "Yellow", "Orange") var my_color + export(String, "White", "Yellow", "Orange") var my_color var points_dict = {"White": 50, "Yellow": 75, "Orange": 100} func _ready(): # We can't use dot syntax here as `my_color` is a variable. diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index cbd83e8d7d..b84e221d1c 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -118,7 +118,7 @@ <argument index="2" name="from_b" type="Vector2" /> <argument index="3" name="dir_b" type="Vector2" /> <description> - Checks if the two lines ([code]from_a[/code], [code]dir_a[/code]) and ([code]from_b[/code], [code]dir_b[/code]) intersect. If yes, return the point of intersection as [Vector2]. If no intersection takes place, returns an empty [Variant]. + Checks if the two lines ([code]from_a[/code], [code]dir_a[/code]) and ([code]from_b[/code], [code]dir_b[/code]) intersect. If yes, return the point of intersection as [Vector2]. If no intersection takes place, returns [code]null[/code]. [b]Note:[/b] The lines are specified using direction vectors, not end points. </description> </method> @@ -195,7 +195,7 @@ <argument index="2" name="from_b" type="Vector2" /> <argument index="3" name="to_b" type="Vector2" /> <description> - Checks if the two segments ([code]from_a[/code], [code]to_a[/code]) and ([code]from_b[/code], [code]to_b[/code]) intersect. If yes, return the point of intersection as [Vector2]. If no intersection takes place, returns an empty [Variant]. + Checks if the two segments ([code]from_a[/code], [code]to_a[/code]) and ([code]from_b[/code], [code]to_b[/code]) intersect. If yes, return the point of intersection as [Vector2]. If no intersection takes place, returns [code]null[/code]. </description> </method> <method name="triangulate_delaunay"> diff --git a/doc/classes/Geometry3D.xml b/doc/classes/Geometry3D.xml index 0bf6f880c2..c05d7df53f 100644 --- a/doc/classes/Geometry3D.xml +++ b/doc/classes/Geometry3D.xml @@ -81,7 +81,7 @@ <argument index="3" name="b" type="Vector3" /> <argument index="4" name="c" type="Vector3" /> <description> - Tests if the 3D ray starting at [code]from[/code] with the direction of [code]dir[/code] intersects the triangle specified by [code]a[/code], [code]b[/code] and [code]c[/code]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, an empty [Variant] is returned. + Tests if the 3D ray starting at [code]from[/code] with the direction of [code]dir[/code] intersects the triangle specified by [code]a[/code], [code]b[/code] and [code]c[/code]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, returns [code]null[/code]. </description> </method> <method name="segment_intersects_convex"> @@ -121,7 +121,7 @@ <argument index="3" name="b" type="Vector3" /> <argument index="4" name="c" type="Vector3" /> <description> - Tests if the segment ([code]from[/code], [code]to[/code]) intersects the triangle [code]a[/code], [code]b[/code], [code]c[/code]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, an empty [Variant] is returned. + Tests if the segment ([code]from[/code], [code]to[/code]) intersects the triangle [code]a[/code], [code]b[/code], [code]c[/code]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, returns [code]null[/code]. </description> </method> </methods> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index 02352ca808..965dbe7449 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -202,6 +202,9 @@ <member name="connection_lines_antialiased" type="bool" setter="set_connection_lines_antialiased" getter="is_connection_lines_antialiased" default="true"> If [code]true[/code], the lines between nodes will use antialiasing. </member> + <member name="connection_lines_curvature" type="float" setter="set_connection_lines_curvature" getter="get_connection_lines_curvature" default="0.5"> + The curvature of the lines between the nodes. 0 results in straight lines. + </member> <member name="connection_lines_thickness" type="float" setter="set_connection_lines_thickness" getter="get_connection_lines_thickness" default="2.0"> The thickness of the lines between the nodes. </member> @@ -372,15 +375,11 @@ <theme_item name="selection_stroke" data_type="color" type="Color" default="Color(1, 1, 1, 0.8)"> The outline color of the selection rectangle. </theme_item> - <theme_item name="bezier_len_neg" data_type="constant" type="int" default="160"> - </theme_item> - <theme_item name="bezier_len_pos" data_type="constant" type="int" default="80"> - </theme_item> - <theme_item name="port_grab_distance_horizontal" data_type="constant" type="int" default="24"> - The horizontal range within which a port can be grabbed (on both sides). + <theme_item name="port_hotzone_inner_extent" data_type="constant" type="int" default="22"> + The horizontal range within which a port can be grabbed (inner side). </theme_item> - <theme_item name="port_grab_distance_vertical" data_type="constant" type="int" default="26"> - The vertical range within which a port can be grabbed (on both sides). + <theme_item name="port_hotzone_outer_extent" data_type="constant" type="int" default="26"> + The horizontal range within which a port can be grabbed (outer side). </theme_item> <theme_item name="layout" data_type="icon" type="Texture2D"> </theme_item> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 5f0dca0402..f261da8413 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -43,6 +43,13 @@ Returns the number of enabled input slots (connections) to the GraphNode. </description> </method> + <method name="get_connection_input_height"> + <return type="int" /> + <argument index="0" name="idx" type="int" /> + <description> + Returns the height of the input connection [code]idx[/code]. + </description> + </method> <method name="get_connection_input_position"> <return type="Vector2" /> <argument index="0" name="idx" type="int" /> @@ -70,6 +77,13 @@ Returns the number of enabled output slots (connections) of the GraphNode. </description> </method> + <method name="get_connection_output_height"> + <return type="int" /> + <argument index="0" name="idx" type="int" /> + <description> + Returns the height of the output connection [code]idx[/code]. + </description> + </method> <method name="get_connection_output_position"> <return type="Vector2" /> <argument index="0" name="idx" type="int" /> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index c9795856d5..e9000d4356 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -625,7 +625,7 @@ <return type="void" /> <argument index="0" name="method" type="StringName" /> <description> - Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns an empty [Variant]. + Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns [code]null[/code]. [b]Note:[/b] You can only safely use RPCs on clients after you received the [code]connected_to_server[/code] signal from the [MultiplayerAPI]. You also need to keep track of the connection state, either by the [MultiplayerAPI] signals like [code]server_disconnected[/code] or by checking [code]get_multiplayer().peer.get_connection_status() == CONNECTION_CONNECTED[/code]. </description> </method> @@ -645,7 +645,7 @@ <argument index="0" name="peer_id" type="int" /> <argument index="1" name="method" type="StringName" /> <description> - Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method MultiplayerPeer.set_target_peer]). Returns an empty [Variant]. + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method MultiplayerPeer.set_target_peer]). Returns [code]null[/code]. </description> </method> <method name="set_display_folded"> diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 6ed723b891..74fea03fee 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -1126,7 +1126,7 @@ ConnectionsDock::ConnectionsDock() { search_box = memnew(LineEdit); search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search_box->set_placeholder(TTR("Filter signals")); + search_box->set_placeholder(TTR("Filter Signals")); search_box->set_clear_button_enabled(true); search_box->connect("text_changed", callable_mp(this, &ConnectionsDock::_filter_changed)); vbc->add_child(search_box); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 60486b5286..8cb984af1b 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1765,7 +1765,7 @@ ScriptEditorDebugger::ScriptEditorDebugger() { search = memnew(LineEdit); search->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search->set_placeholder(TTR("Filter stack variables")); + search->set_placeholder(TTR("Filter Stack Variables")); search->set_clear_button_enabled(true); tools_hb->add_child(search); diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp index e3cbd8ad50..c1cd7f9c7b 100644 --- a/editor/editor_command_palette.cpp +++ b/editor/editor_command_palette.cpp @@ -299,7 +299,7 @@ EditorCommandPalette::EditorCommandPalette() { add_child(vbc); command_search_box = memnew(LineEdit); - command_search_box->set_placeholder(TTR("Filter commands")); + command_search_box->set_placeholder(TTR("Filter Commands")); command_search_box->connect("gui_input", callable_mp(this, &EditorCommandPalette::_sbox_input)); command_search_box->connect("text_changed", callable_mp(this, &EditorCommandPalette::_update_command_search)); command_search_box->set_v_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index dba0864fcb..19ffb6f0f5 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -73,6 +73,13 @@ void EditorHelp::_search(bool p_search_previous) { } } +void EditorHelp::_class_desc_finished() { + if (scroll_to >= 0) { + class_desc->scroll_to_paragraph(scroll_to); + } + scroll_to = -1; +} + void EditorHelp::_class_list_select(const String &p_select) { _goto_desc(p_select); } @@ -126,7 +133,11 @@ void EditorHelp::_class_desc_select(const String &p_select) { // Case order is important here to correctly handle edge cases like Variant.Type in @GlobalScope. if (table->has(link)) { // Found in the current page. - class_desc->scroll_to_paragraph((*table)[link]); + if (class_desc->is_ready()) { + class_desc->scroll_to_paragraph((*table)[link]); + } else { + scroll_to = (*table)[link]; + } } else { // Look for link in @GlobalScope. // Note that a link like @GlobalScope.enum_name will not be found in this section, only enum_name will be. @@ -1469,7 +1480,11 @@ void EditorHelp::_help_callback(const String &p_topic) { } } - class_desc->call_deferred(SNAME("scroll_to_paragraph"), line); + if (class_desc->is_ready()) { + class_desc->call_deferred(SNAME("scroll_to_paragraph"), line); + } else { + scroll_to = line; + } } static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { @@ -1824,7 +1839,11 @@ Vector<Pair<String, int>> EditorHelp::get_sections() { void EditorHelp::scroll_to_section(int p_section_index) { _wait_for_thread(); int line = section_line[p_section_index].second; - class_desc->scroll_to_paragraph(line); + if (class_desc->is_ready()) { + class_desc->scroll_to_paragraph(line); + } else { + scroll_to = line; + } } void EditorHelp::popup_search() { @@ -1877,6 +1896,7 @@ EditorHelp::EditorHelp() { class_desc->set_v_size_flags(SIZE_EXPAND_FILL); class_desc->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); + class_desc->connect("finished", callable_mp(this, &EditorHelp::_class_desc_finished)); class_desc->connect("meta_clicked", callable_mp(this, &EditorHelp::_class_desc_select)); class_desc->connect("gui_input", callable_mp(this, &EditorHelp::_class_desc_input)); class_desc->connect("resized", callable_mp(this, &EditorHelp::_class_desc_resized), varray(false)); diff --git a/editor/editor_help.h b/editor/editor_help.h index b5410f6880..766a09f485 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -140,6 +140,8 @@ class EditorHelp : public VBoxContainer { Ref<Font> doc_title_font; Ref<Font> doc_code_font; + int scroll_to = -1; + void _update_theme(); void _help_callback(const String &p_topic); @@ -152,6 +154,7 @@ class EditorHelp : public VBoxContainer { void _add_bulletpoint(); + void _class_desc_finished(); void _class_list_select(const String &p_select); void _class_desc_select(const String &p_select); void _class_desc_input(const Ref<InputEvent> &p_input); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 8d45f90ed6..dbe44aee1b 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -353,7 +353,7 @@ EditorLog::EditorLog() { // Search box search_box = memnew(LineEdit); search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search_box->set_placeholder(TTR("Filter messages")); + search_box->set_placeholder(TTR("Filter Messages")); search_box->set_clear_button_enabled(true); search_box->set_visible(true); search_box->connect("text_changed", callable_mp(this, &EditorLog::_search_changed)); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 801a1a4641..b7073665a8 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -250,6 +250,11 @@ void SectionedInspector::update_category_list() { continue; } + // Filter out unnecessary ProjectSettings sections, as they already have their dedicated tabs. + if (pi.name.begins_with("autoload") || pi.name.begins_with("editor_plugins") || pi.name.begins_with("shader_globals")) { + continue; + } + if (!filter.is_empty() && !_property_path_matches(pi.name, filter, name_style)) { continue; } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 31ce31a437..504e09aa36 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -681,6 +681,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // Visual editors EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/minimap_opacity", 0.85, "0.0,1.0,0.01") + EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/visual_editors/lines_curvature", 0.5, "0.0,1.0,0.01") EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/visual_editors/visualshader/port_preview_size", 160, "100,400,0.01") /* Run */ diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 712a5b150f..bec9f2dc51 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -697,7 +697,7 @@ EditorSettingsDialog::EditorSettingsDialog() { tab_general->add_child(hbc); search_box = memnew(LineEdit); - search_box->set_placeholder(TTR("Search")); + search_box->set_placeholder(TTR("Filter Settings")); search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); hbc->add_child(search_box); @@ -739,7 +739,7 @@ EditorSettingsDialog::EditorSettingsDialog() { tab_shortcuts->set_name(TTR("Shortcuts")); shortcut_search_box = memnew(LineEdit); - shortcut_search_box->set_placeholder(TTR("Search")); + shortcut_search_box->set_placeholder(TTR("Filter Shortcuts")); shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); tab_shortcuts->add_child(shortcut_search_box); shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts)); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 550a73ed72..352cd453a7 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -1446,8 +1446,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("snap", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), SNAME("EditorIcons"))); theme->set_icon("minimap", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), SNAME("EditorIcons"))); theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), SNAME("EditorIcons"))); - theme->set_constant("bezier_len_pos", "GraphEdit", 80 * EDSCALE); - theme->set_constant("bezier_len_neg", "GraphEdit", 160 * EDSCALE); // GraphEditMinimap Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp index c8099c9a0b..e4beea5e5f 100644 --- a/editor/editor_zoom_widget.cpp +++ b/editor/editor_zoom_widget.cpp @@ -178,7 +178,7 @@ EditorZoomWidget::EditorZoomWidget() { zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0)); zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_reset)); - zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KeyModifierMask::CMD | Key::KEY_0)); + zoom_reset->set_shortcut(ED_GET_SHORTCUT("canvas_item_editor/zoom_100_percent")); zoom_reset->set_shortcut_context(this); zoom_reset->set_focus_mode(FOCUS_NONE); zoom_reset->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index aaff892c2a..3dd0044ab9 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -3082,7 +3082,7 @@ FileSystemDock::FileSystemDock() { tree_search_box = memnew(LineEdit); tree_search_box->set_h_size_flags(SIZE_EXPAND_FILL); - tree_search_box->set_placeholder(TTR("Search files")); + tree_search_box->set_placeholder(TTR("Filter Files")); tree_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(tree_search_box)); toolbar2_hbc->add_child(tree_search_box); @@ -3127,7 +3127,7 @@ FileSystemDock::FileSystemDock() { file_list_search_box = memnew(LineEdit); file_list_search_box->set_h_size_flags(SIZE_EXPAND_FILL); - file_list_search_box->set_placeholder(TTR("Search files")); + file_list_search_box->set_placeholder(TTR("Filter Files")); file_list_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(file_list_search_box)); path_hb->add_child(file_list_search_box); diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index bbf9b11be3..f3129db65e 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -499,7 +499,7 @@ GroupDialog::GroupDialog() { add_filter = memnew(LineEdit); add_filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); - add_filter->set_placeholder(TTR("Filter nodes")); + add_filter->set_placeholder(TTR("Filter Nodes")); add_filter_hbc->add_child(add_filter); add_filter->connect("text_changed", callable_mp(this, &GroupDialog::_add_filter_changed)); @@ -549,7 +549,7 @@ GroupDialog::GroupDialog() { remove_filter = memnew(LineEdit); remove_filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); - remove_filter->set_placeholder(TTR("Filter nodes")); + remove_filter->set_placeholder(TTR("Filter Nodes")); remove_filter_hbc->add_child(remove_filter); remove_filter->connect("text_changed", callable_mp(this, &GroupDialog::_remove_filter_changed)); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 934d3a82b4..ad92911810 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -657,7 +657,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) { search = memnew(LineEdit); search->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search->set_placeholder(TTR("Filter properties")); + search->set_placeholder(TTR("Filter Properties")); search->set_clear_button_enabled(true); property_tools_hb->add_child(search); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 8c8505283c..5e703cf814 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -264,6 +264,8 @@ void AnimationNodeBlendTreeEditor::_update_graph() { float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); } void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) { @@ -969,6 +971,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->connect("connection_from_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_from_empty)); float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); VSeparator *vs = memnew(VSeparator); graph->get_zoom_hbox()->add_child(vs); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index d7061a420a..249b3a6d6a 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -1402,9 +1402,9 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { filter = memnew(LineEdit); if (templates_only) { - filter->set_placeholder(TTR("Search templates, projects, and demos")); + filter->set_placeholder(TTR("Search Templates, Projects, and Demos")); } else { - filter->set_placeholder(TTR("Search assets (excluding templates, projects, and demos)")); + filter->set_placeholder(TTR("Search Assets (Excluding Templates, Projects, and Demos)")); } filter->set_clear_button_enabled(true); search_hb->add_child(filter); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index a7e3d17fdc..d28629b41a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5295,14 +5295,12 @@ CanvasItemEditor::CanvasItemEditor() { // To ensure that scripts can parse the list of shortcuts correctly, we have to define // those shortcuts one by one. - // Resetting zoom to 100% is a duplicate shortcut of `canvas_item_editor/reset_zoom`, - // but it ensures both 1 and Ctrl + 0 can be used to reset zoom. ED_SHORTCUT("canvas_item_editor/zoom_3.125_percent", TTR("Zoom to 3.125%"), KeyModifierMask::SHIFT | Key::KEY_5); ED_SHORTCUT("canvas_item_editor/zoom_6.25_percent", TTR("Zoom to 6.25%"), KeyModifierMask::SHIFT | Key::KEY_4); ED_SHORTCUT("canvas_item_editor/zoom_12.5_percent", TTR("Zoom to 12.5%"), KeyModifierMask::SHIFT | Key::KEY_3); ED_SHORTCUT("canvas_item_editor/zoom_25_percent", TTR("Zoom to 25%"), KeyModifierMask::SHIFT | Key::KEY_2); ED_SHORTCUT("canvas_item_editor/zoom_50_percent", TTR("Zoom to 50%"), KeyModifierMask::SHIFT | Key::KEY_1); - ED_SHORTCUT("canvas_item_editor/zoom_100_percent", TTR("Zoom to 100%"), Key::KEY_1); + ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_100_percent", TTR("Zoom to 100%"), { (int32_t)Key::KEY_1, (int32_t)(KeyModifierMask::CMD | Key::KEY_0) }); ED_SHORTCUT("canvas_item_editor/zoom_200_percent", TTR("Zoom to 200%"), Key::KEY_2); ED_SHORTCUT("canvas_item_editor/zoom_400_percent", TTR("Zoom to 400%"), Key::KEY_3); ED_SHORTCUT("canvas_item_editor/zoom_800_percent", TTR("Zoom to 800%"), Key::KEY_4); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 99b810be44..b9d99fcc93 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3674,7 +3674,7 @@ ScriptEditor::ScriptEditor() { list_split->add_child(scripts_vbox); filter_scripts = memnew(LineEdit); - filter_scripts->set_placeholder(TTR("Filter scripts")); + filter_scripts->set_placeholder(TTR("Filter Scripts")); filter_scripts->set_clear_button_enabled(true); filter_scripts->connect("text_changed", callable_mp(this, &ScriptEditor::_filter_scripts_text_changed)); scripts_vbox->add_child(filter_scripts); @@ -3717,7 +3717,7 @@ ScriptEditor::ScriptEditor() { buttons_hbox->add_child(members_overview_alphabeta_sort_button); filter_methods = memnew(LineEdit); - filter_methods->set_placeholder(TTR("Filter methods")); + filter_methods->set_placeholder(TTR("Filter Methods")); filter_methods->set_clear_button_enabled(true); filter_methods->connect("text_changed", callable_mp(this, &ScriptEditor::_filter_methods_text_changed)); overview_vbox->add_child(filter_methods); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index a4bccf30e3..b0cc0bff63 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1524,6 +1524,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data te->set_caret_line(row); te->set_caret_column(col); te->insert_text_at_caret(res->get_path()); + te->grab_focus(); } if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) { @@ -1546,6 +1547,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data te->set_caret_line(row); te->set_caret_column(col); te->insert_text_at_caret(text_to_drop); + te->grab_focus(); } if (d.has("type") && String(d["type"]) == "nodes") { @@ -1619,6 +1621,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data te->set_caret_line(row); te->set_caret_column(col); te->insert_text_at_caret(text_to_drop); + te->grab_focus(); } if (d.has("type") && String(d["type"]) == "obj_property") { @@ -1627,6 +1630,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data te->set_caret_line(row); te->set_caret_column(col); te->insert_text_at_caret(text_to_drop); + te->grab_focus(); } } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 751751aaaa..400611c0e6 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -834,6 +834,8 @@ void ThemeItemImportTree::_notification(int p_what) { select_icons_warning_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + import_items_filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + // Bottom panel buttons. import_collapse_types_button->set_icon(get_theme_icon(SNAME("CollapseTree"), SNAME("EditorIcons"))); import_expand_types_button->set_icon(get_theme_icon(SNAME("ExpandTree"), SNAME("EditorIcons"))); @@ -881,15 +883,10 @@ void ThemeItemImportTree::_bind_methods() { } ThemeItemImportTree::ThemeItemImportTree() { - HBoxContainer *import_items_filter_hb = memnew(HBoxContainer); - add_child(import_items_filter_hb); - Label *import_items_filter_label = memnew(Label); - import_items_filter_label->set_text(TTR("Filter:")); - import_items_filter_hb->add_child(import_items_filter_label); import_items_filter = memnew(LineEdit); + import_items_filter->set_placeholder(TTR("Filter Items")); import_items_filter->set_clear_button_enabled(true); - import_items_filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); - import_items_filter_hb->add_child(import_items_filter); + add_child(import_items_filter); import_items_filter->connect("text_changed", callable_mp(this, &ThemeItemImportTree::_filter_text_changed)); HBoxContainer *import_main_hb = memnew(HBoxContainer); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 6e13a31a1f..642973648e 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1745,6 +1745,8 @@ void VisualShaderEditor::_update_graph() { float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); } VisualShader::Type VisualShaderEditor::get_current_shader_type() const { @@ -4675,6 +4677,8 @@ VisualShaderEditor::VisualShaderEditor() { graph->set_drag_forwarding(this); float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index a56b6ec9d4..7fcabb1e80 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -2594,7 +2594,7 @@ ProjectManager::ProjectManager() { search_tree_vb->add_child(hb); search_box = memnew(LineEdit); - search_box->set_placeholder(TTR("Filter projects")); + search_box->set_placeholder(TTR("Filter Projects")); search_box->set_tooltip(TTR("This field filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character.")); search_box->connect("text_changed", callable_mp(this, &ProjectManager::_on_search_term_changed)); search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 14a0427e18..58f69436a5 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -586,7 +586,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { general_editor->add_child(header); property_box = memnew(LineEdit); - property_box->set_placeholder(TTR("Select a setting or type its name")); + property_box->set_placeholder(TTR("Select a Setting or Type its Name")); property_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); property_box->connect("text_changed", callable_mp(this, &ProjectSettingsEditor::_property_box_changed)); header->add_child(property_box); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index c1cc144ff5..1ddefeba77 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -3381,7 +3381,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec vbc->add_child(filter_hbc); filter = memnew(LineEdit); filter->set_h_size_flags(SIZE_EXPAND_FILL); - filter->set_placeholder(TTR("Filter nodes")); + filter->set_placeholder(TTR("Filter Nodes")); filter_hbc->add_child(filter); filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index eaec3bab02..b5b70b827b 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -170,9 +170,9 @@ void SceneTreeEditor::_toggle_visible(Node *p_node) { } } -bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected) { +void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (!p_node) { - return false; + return; } // only owned nodes are editable, since nodes can create their own (manually owned) child nodes, @@ -185,7 +185,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll part_of_subscene = true; //allow } else { - return false; + return; } } else { part_of_subscene = p_node != get_scene_node() && get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node)) >= 0; @@ -431,29 +431,21 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll } } - bool scroll = false; - if (editor_selection) { if (editor_selection->is_selected(p_node)) { item->select(0); - scroll = p_scroll_to_selected; } } if (selected == p_node) { if (!editor_selection) { item->select(0); - scroll = p_scroll_to_selected; } item->set_as_cursor(0); } - bool keep = (filter.is_subsequence_ofn(String(p_node->get_name()))); - for (int i = 0; i < p_node->get_child_count(); i++) { - bool child_keep = _add_nodes(p_node->get_child(i), item, p_scroll_to_selected); - - keep = keep || child_keep; + _add_nodes(p_node->get_child(i), item); } if (valid_types.size()) { @@ -466,27 +458,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll } if (!valid) { - //item->set_selectable(0,marked_selectable); item->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); item->set_selectable(0, false); } } - - if (!keep) { - if (editor_selection) { - Node *n = get_node(item->get_metadata(0)); - if (n) { - editor_selection->remove_node(n); - } - } - memdelete(item); - return false; - } else { - if (scroll) { - tree->scroll_to_item(item); - } - return true; - } } void SceneTreeEditor::_node_visibility_changed(Node *p_node) { @@ -592,13 +567,48 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { updating_tree = true; tree->clear(); if (get_scene_node()) { - _add_nodes(get_scene_node(), nullptr, p_scroll_to_selected); + _add_nodes(get_scene_node(), nullptr); last_hash = hash_djb2_one_64(0); _compute_hash(get_scene_node(), last_hash); } updating_tree = false; - tree_dirty = false; + + if (!filter.is_empty()) { + _update_filter(nullptr, p_scroll_to_selected); + } +} + +bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_selected) { + if (!p_parent) { + p_parent = tree->get_root(); + } + + bool keep = false; + for (TreeItem *child = p_parent->get_first_child(); child; child = child->get_next()) { + keep = _update_filter(child, p_scroll_to_selected) || keep; + } + + if (!keep) { + keep = filter.is_subsequence_ofn(p_parent->get_text(0)); + } + + p_parent->set_visible(keep); + if (editor_selection) { + Node *n = get_node(p_parent->get_metadata(0)); + if (keep) { + if (p_scroll_to_selected && n && editor_selection->is_selected(n)) { + tree->scroll_to_item(p_parent); + } + } else { + if (n && p_parent->is_selected(0)) { + editor_selection->remove_node(n); + p_parent->deselect(0); + } + } + } + + return keep; } void SceneTreeEditor::_compute_hash(Node *p_node, uint64_t &hash) { @@ -898,7 +908,7 @@ void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_child void SceneTreeEditor::set_filter(const String &p_filter) { filter = p_filter; - _update_tree(true); + _update_filter(nullptr, true); } String SceneTreeEditor::get_filter() const { @@ -1211,7 +1221,7 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) { } void SceneTreeEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_update_tree", "scroll_to_selected"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by some connect_compat. + ClassDB::bind_method(D_METHOD("_update_tree"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by some connect_compat. ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node); ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree); @@ -1360,7 +1370,7 @@ SceneTreeDialog::SceneTreeDialog() { filter = memnew(LineEdit); filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); - filter->set_placeholder(TTR("Filter nodes")); + filter->set_placeholder(TTR("Filter Nodes")); filter->set_clear_button_enabled(true); filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed)); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 60387cea3e..5d4230059c 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -73,9 +73,10 @@ class SceneTreeEditor : public Control { void _compute_hash(Node *p_node, uint64_t &hash); - bool _add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected = false); + void _add_nodes(Node *p_node, TreeItem *p_parent); void _test_update_tree(); void _update_tree(bool p_scroll_to_selected = false); + bool _update_filter(TreeItem *p_parent = nullptr, bool p_scroll_to_selected = false); void _tree_changed(); void _tree_process_mode_changed(); void _node_removed(Node *p_node); diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 4902adb827..cfff5c61de 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -1221,7 +1221,7 @@ GridMapEditor::GridMapEditor() { search_box = memnew(LineEdit); search_box->set_h_size_flags(SIZE_EXPAND_FILL); - search_box->set_placeholder(TTR("Filter meshes")); + search_box->set_placeholder(TTR("Filter Meshes")); hb->add_child(search_box); search_box->connect("text_changed", callable_mp(this, &GridMapEditor::_text_changed)); search_box->connect("gui_input", callable_mp(this, &GridMapEditor::_sbox_input)); diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 5cbaded6c1..1bc7cd7cdc 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -172,14 +172,16 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans if (Object::cast_to<MultiMeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { MultiMeshInstance3D *multimesh_instance = Object::cast_to<MultiMeshInstance3D>(p_node); Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh(); - Ref<Mesh> mesh = multimesh->get_mesh(); - if (mesh.is_valid()) { - int n = multimesh->get_visible_instance_count(); - if (n == -1) { - n = multimesh->get_instance_count(); - } - for (int i = 0; i < n; i++) { - _add_mesh(mesh, p_navmesh_transform * multimesh_instance->get_global_transform() * multimesh->get_instance_transform(i), p_vertices, p_indices); + if (multimesh.is_valid()) { + Ref<Mesh> mesh = multimesh->get_mesh(); + if (mesh.is_valid()) { + int n = multimesh->get_visible_instance_count(); + if (n == -1) { + n = multimesh->get_instance_count(); + } + for (int i = 0; i < n; i++) { + _add_mesh(mesh, p_navmesh_transform * multimesh_instance->get_global_transform() * multimesh->get_instance_transform(i), p_vertices, p_indices); + } } } } diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 7454c8076f..684faf7c8e 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -980,6 +980,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) { float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); + // Use default_func instead of default_func for now I think that should be good stop gap solution to ensure not breaking anything. graph->call_deferred(SNAME("set_scroll_ofs"), script->get_scroll() * EDSCALE); updating_graph = false; @@ -4593,6 +4596,8 @@ VisualScriptEditor::VisualScriptEditor() { graph->set_drag_forwarding(this); float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); + float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + graph->set_connection_lines_curvature(graph_lines_curvature); graph->hide(); graph->connect("scroll_offset_changed", callable_mp(this, &VisualScriptEditor::_graph_ofs_changed)); diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index 33dd737416..1971dc1240 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -66,6 +66,7 @@ void VisibleOnScreenNotifier2D::set_rect(const Rect2 &p_rect) { if (is_inside_tree()) { RS::get_singleton()->canvas_item_set_visibility_notifier(get_canvas_item(), true, rect, callable_mp(this, &VisibleOnScreenNotifier2D::_visibility_enter), callable_mp(this, &VisibleOnScreenNotifier2D::_visibility_exit)); } + update(); } Rect2 VisibleOnScreenNotifier2D::get_rect() const { diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index fdff6a88a9..446d9e800a 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -426,8 +426,8 @@ void GraphEdit::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - port_grab_distance_horizontal = get_theme_constant(SNAME("port_grab_distance_horizontal")); - port_grab_distance_vertical = get_theme_constant(SNAME("port_grab_distance_vertical")); + port_hotzone_inner_extent = get_theme_constant("port_hotzone_inner_extent"); + port_hotzone_outer_extent = get_theme_constant("port_hotzone_outer_extent"); zoom_minus->set_icon(get_theme_icon(SNAME("minus"))); zoom_reset->set_icon(get_theme_icon(SNAME("reset"))); @@ -544,8 +544,7 @@ void GraphEdit::_set_position_of_comment_enclosed_nodes(GraphNode *p_node, HashM } bool GraphEdit::_filter_input(const Point2 &p_point) { - Ref<Texture2D> port = get_theme_icon(SNAME("port"), SNAME("GraphNode")); - Vector2i port_size = Vector2i(port->get_width(), port->get_height()); + Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); @@ -553,14 +552,18 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { continue; } - for (int j = 0; j < gn->get_connection_output_count(); j++) { - if (is_in_output_hotzone(gn, j, p_point / zoom, port_size)) { + for (int j = 0; j < gn->get_connection_input_count(); j++) { + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_input_height(j)); + if (is_in_input_hotzone(gn, j, p_point / zoom, port_size)) { return true; } } - for (int j = 0; j < gn->get_connection_input_count(); j++) { - if (is_in_input_hotzone(gn, j, p_point / zoom, port_size)) { + for (int j = 0; j < gn->get_connection_output_count(); j++) { + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_output_height(j)); + if (is_in_output_hotzone(gn, j, p_point / zoom, port_size)) { return true; } } @@ -572,8 +575,7 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseButton> mb = p_ev; if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { - Ref<Texture2D> port = get_theme_icon(SNAME("port"), SNAME("GraphNode")); - Vector2i port_size = Vector2i(port->get_width(), port->get_height()); + Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); connecting_valid = false; click_pos = mb->get_position() / zoom; @@ -585,6 +587,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_output_height(j)); + if (is_in_output_hotzone(gn, j, click_pos, port_size)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect @@ -629,6 +634,10 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); + + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_input_height(j)); + if (is_in_input_hotzone(gn, j, click_pos, port_size)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect @@ -682,11 +691,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_valid = just_disconnected || click_pos.distance_to(connecting_to / zoom) > 20.0; if (connecting_valid) { - Ref<Texture2D> port = get_theme_icon(SNAME("port"), SNAME("GraphNode")); - Vector2i port_size = Vector2i(port->get_width(), port->get_height()); - Vector2 mpos = mm->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { + Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) { continue; @@ -695,6 +702,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (!connecting_out) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_output_height(j)); + int type = gn->get_connection_output_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_output_hotzone(gn, j, mpos, port_size)) { connecting_target = true; @@ -707,6 +717,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } else { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); + Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); + port_size.height = MAX(port_size.height, gn->get_connection_input_height(j)); + int type = gn->get_connection_input_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_input_hotzone(gn, j, mpos, port_size)) { connecting_target = true; @@ -754,19 +767,24 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } -bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos) { - if (p_control->is_set_as_top_level() || !p_control->is_visible()) { +bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &mpos, const Vector2 &p_offset) { + if (p_control->is_set_as_top_level() || !p_control->is_visible() || !p_control->is_inside_tree()) { return false; } - if (!p_control->has_point(pos) || p_control->get_mouse_filter() == MOUSE_FILTER_IGNORE) { - //test children + Rect2 control_rect = p_control->get_rect(); + control_rect.size *= zoom; + control_rect.position *= zoom; + control_rect.position += p_offset; + + if (!control_rect.has_point(mpos) || p_control->get_mouse_filter() == MOUSE_FILTER_IGNORE) { + // Test children. for (int i = 0; i < p_control->get_child_count(); i++) { - Control *subchild = Object::cast_to<Control>(p_control->get_child(i)); - if (!subchild) { + Control *child_rect = Object::cast_to<Control>(p_control->get_child(i)); + if (!child_rect) { continue; } - if (_check_clickable_control(subchild, pos - subchild->get_position())) { + if (_check_clickable_control(child_rect, mpos, control_rect.position)) { return true; } } @@ -798,7 +816,13 @@ bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, } bool GraphEdit::is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) { - if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos)) { + Rect2 hotzone = Rect2( + pos.x - (p_left ? port_hotzone_outer_extent : port_hotzone_inner_extent), + pos.y - p_port_size.height / 2.0, + port_hotzone_inner_extent + port_hotzone_outer_extent, + p_port_size.height); + + if (!hotzone.has_point(p_mouse_pos)) { return false; } @@ -807,23 +831,17 @@ bool GraphEdit::is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_po if (!child) { continue; } - Rect2 rect = child->get_rect(); - - // To prevent intersections with other nodes. - rect.position *= zoom; - rect.size *= zoom; - - if (rect.has_point(p_mouse_pos)) { - //check sub-controls - Vector2 subpos = p_mouse_pos - rect.position; + Rect2 child_rect = child->get_rect(); + child_rect.size *= zoom; + if (child_rect.has_point(p_mouse_pos * zoom)) { for (int j = 0; j < child->get_child_count(); j++) { Control *subchild = Object::cast_to<Control>(child->get_child(j)); if (!subchild) { continue; } - if (_check_clickable_control(subchild, subpos - subchild->get_position())) { + if (_check_clickable_control(subchild, p_mouse_pos * zoom, child_rect.position)) { return false; } } @@ -839,13 +857,23 @@ PackedVector2Array GraphEdit::get_connection_line(const Vector2 &p_from, const V return ret; } + float x_diff = (p_to.x - p_from.x); + float cp_offset = x_diff * lines_curvature; + if (x_diff < 0) { + cp_offset *= -1; + } + Curve2D curve; - Vector<Color> colors; curve.add_point(p_from); - curve.set_point_out(0, Vector2(60, 0)); + curve.set_point_out(0, Vector2(cp_offset, 0)); curve.add_point(p_to); - curve.set_point_in(1, Vector2(-60, 0)); - return curve.tessellate(); + curve.set_point_in(1, Vector2(-cp_offset, 0)); + + if (lines_curvature > 0) { + return curve.tessellate(5, 2.0); + } else { + return curve.tessellate(1); + } } void GraphEdit::_draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom) { @@ -1666,6 +1694,15 @@ void GraphEdit::_minimap_toggled() { } } +void GraphEdit::set_connection_lines_curvature(float p_curvature) { + lines_curvature = p_curvature; + update(); +} + +float GraphEdit::get_connection_lines_curvature() const { + return lines_curvature; +} + void GraphEdit::set_connection_lines_thickness(float p_thickness) { lines_thickness = p_thickness; update(); @@ -2244,6 +2281,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_snap", "enable"), &GraphEdit::set_use_snap); ClassDB::bind_method(D_METHOD("is_using_snap"), &GraphEdit::is_using_snap); + ClassDB::bind_method(D_METHOD("set_connection_lines_curvature", "curvature"), &GraphEdit::set_connection_lines_curvature); + ClassDB::bind_method(D_METHOD("get_connection_lines_curvature"), &GraphEdit::get_connection_lines_curvature); + ClassDB::bind_method(D_METHOD("set_connection_lines_thickness", "pixels"), &GraphEdit::set_connection_lines_thickness); ClassDB::bind_method(D_METHOD("get_connection_lines_thickness"), &GraphEdit::get_connection_lines_thickness); @@ -2280,6 +2320,7 @@ void GraphEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme"); ADD_GROUP("Connection Lines", "connection_lines"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_curvature"), "set_connection_lines_curvature", "get_connection_lines_curvature"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "connection_lines_antialiased"), "set_connection_lines_antialiased", "is_connection_lines_antialiased"); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 5484a2317c..02e90e4717 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -124,8 +124,8 @@ private: HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; - float port_grab_distance_horizontal = 0.0; - float port_grab_distance_vertical = 0.0; + float port_hotzone_inner_extent = 0.0; + float port_hotzone_outer_extent = 0.0; Ref<ViewPanner> panner; bool warped_panning = true; @@ -178,6 +178,7 @@ private: List<Connection> connections; float lines_thickness = 2.0f; + float lines_curvature = 0.5f; bool lines_antialiased = true; PackedVector2Array get_connection_line(const Vector2 &p_from, const Vector2 &p_to); @@ -250,7 +251,7 @@ private: friend class GraphEditMinimap; void _minimap_toggled(); - bool _check_clickable_control(Control *p_control, const Vector2 &pos); + bool _check_clickable_control(Control *p_control, const Vector2 &r_mouse_pos, const Vector2 &p_offset); bool arranging_graph = false; @@ -344,6 +345,9 @@ public: int get_snap() const; void set_snap(int p_snap); + void set_connection_lines_curvature(float p_curvature); + float get_connection_lines_curvature() const; + void set_connection_lines_thickness(float p_thickness); float get_connection_lines_thickness() const; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 45f036d8fc..5cb28a30e8 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -832,6 +832,7 @@ void GraphNode::_connpos_update() { cc.pos = Point2i(edgeofs, y + h / 2); cc.type = slot_info[idx].type_left; cc.color = slot_info[idx].color_left; + cc.height = size.height; conn_input_cache.push_back(cc); } if (slot_info[idx].enable_right) { @@ -839,6 +840,7 @@ void GraphNode::_connpos_update() { cc.pos = Point2i(get_size().width - edgeofs, y + h / 2); cc.type = slot_info[idx].type_right; cc.color = slot_info[idx].color_right; + cc.height = size.height; conn_output_cache.push_back(cc); } } @@ -859,12 +861,13 @@ int GraphNode::get_connection_input_count() { return conn_input_cache.size(); } -int GraphNode::get_connection_output_count() { +int GraphNode::get_connection_input_height(int p_idx) { if (connpos_dirty) { _connpos_update(); } - return conn_output_cache.size(); + ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), 0); + return conn_input_cache[p_idx].height; } Vector2 GraphNode::get_connection_input_position(int p_idx) { @@ -897,6 +900,23 @@ Color GraphNode::get_connection_input_color(int p_idx) { return conn_input_cache[p_idx].color; } +int GraphNode::get_connection_output_count() { + if (connpos_dirty) { + _connpos_update(); + } + + return conn_output_cache.size(); +} + +int GraphNode::get_connection_output_height(int p_idx) { + if (connpos_dirty) { + _connpos_update(); + } + + ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), 0); + return conn_output_cache[p_idx].height; +} + Vector2 GraphNode::get_connection_output_position(int p_idx) { if (connpos_dirty) { _connpos_update(); @@ -1066,15 +1086,17 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphNode::set_selected); ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected); - ClassDB::bind_method(D_METHOD("get_connection_output_count"), &GraphNode::get_connection_output_count); ClassDB::bind_method(D_METHOD("get_connection_input_count"), &GraphNode::get_connection_input_count); + ClassDB::bind_method(D_METHOD("get_connection_input_height", "idx"), &GraphNode::get_connection_input_height); + ClassDB::bind_method(D_METHOD("get_connection_input_position", "idx"), &GraphNode::get_connection_input_position); + ClassDB::bind_method(D_METHOD("get_connection_input_type", "idx"), &GraphNode::get_connection_input_type); + ClassDB::bind_method(D_METHOD("get_connection_input_color", "idx"), &GraphNode::get_connection_input_color); + ClassDB::bind_method(D_METHOD("get_connection_output_count"), &GraphNode::get_connection_output_count); + ClassDB::bind_method(D_METHOD("get_connection_output_height", "idx"), &GraphNode::get_connection_output_height); ClassDB::bind_method(D_METHOD("get_connection_output_position", "idx"), &GraphNode::get_connection_output_position); ClassDB::bind_method(D_METHOD("get_connection_output_type", "idx"), &GraphNode::get_connection_output_type); ClassDB::bind_method(D_METHOD("get_connection_output_color", "idx"), &GraphNode::get_connection_output_color); - ClassDB::bind_method(D_METHOD("get_connection_input_position", "idx"), &GraphNode::get_connection_input_position); - ClassDB::bind_method(D_METHOD("get_connection_input_type", "idx"), &GraphNode::get_connection_input_type); - ClassDB::bind_method(D_METHOD("get_connection_input_color", "idx"), &GraphNode::get_connection_input_color); ClassDB::bind_method(D_METHOD("set_show_close_button", "show"), &GraphNode::set_show_close_button); ClassDB::bind_method(D_METHOD("is_close_button_visible"), &GraphNode::is_close_button_visible); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 9481a7452d..f6c943dc89 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -81,6 +81,7 @@ private: Vector2 pos; int type = 0; Color color; + int height; }; Vector<ConnCache> conn_input_cache; @@ -167,10 +168,13 @@ public: bool is_close_button_visible() const; int get_connection_input_count(); - int get_connection_output_count(); + int get_connection_input_height(int p_idx); Vector2 get_connection_input_position(int p_idx); int get_connection_input_type(int p_idx); Color get_connection_input_color(int p_idx); + + int get_connection_output_count(); + int get_connection_output_height(int p_idx); Vector2 get_connection_output_position(int p_idx); int get_connection_output_type(int p_idx); Color get_connection_output_color(int p_idx); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 73188d6602..fd9db4ea1b 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -695,7 +695,7 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const { return false; } Ref<Texture2D> icon = Control::get_theme_icon(SNAME("clear")); - int x_ofs = get_theme_stylebox(SNAME("normal"))->get_offset().x; + int x_ofs = get_theme_stylebox(SNAME("normal"))->get_margin(SIDE_RIGHT); return p_pos.x > get_size().width - icon->get_width() - x_ofs; } diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index b96ba0ebf9..fec8d11bef 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -862,6 +862,7 @@ void TabBar::_update_hover() { void TabBar::_update_cache() { if (tabs.is_empty()) { + buttons_visible = false; return; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index bafa83392b..dee5ff3db9 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2164,7 +2164,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } // Draw relationship lines. - if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { + if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root) && c->is_visible()) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); int parent_ofs = p_pos.x + cache.item_margin; Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index ba22fdcad3..5fcaf8f2c4 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -1004,13 +1004,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("selection_fill", "GraphEdit", Color(1, 1, 1, 0.3)); theme->set_color("selection_stroke", "GraphEdit", Color(1, 1, 1, 0.8)); theme->set_color("activity", "GraphEdit", Color(1, 1, 1)); - theme->set_constant("bezier_len_pos", "GraphEdit", 80 * scale); - theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale); // Visual Node Ports - theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 24 * scale); - theme->set_constant("port_grab_distance_vertical", "GraphEdit", 26 * scale); + theme->set_constant("port_hotzone_inner_extent", "GraphEdit", 22 * scale); + theme->set_constant("port_hotzone_outer_extent", "GraphEdit", 26 * scale); theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0)); Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0, 0); diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index bed9b02da1..b735283ebe 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -1671,7 +1671,7 @@ void GodotPhysicsServer3D::flush_queries() { values.push_back("flush_queries"); values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); - values.push_front("physics"); + values.push_front("physics_3d"); EngineDebugger::profiler_add_frame_data("servers", values); } #endif diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp index 49417bd3a6..163a24247e 100644 --- a/servers/rendering/renderer_canvas_render.cpp +++ b/servers/rendering/renderer_canvas_render.cpp @@ -95,7 +95,7 @@ const Rect2 &RendererCanvasRender::Item::get_rect() const { case Item::Command::TYPE_PARTICLES: { const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); if (particles_cmd->particles.is_valid()) { - AABB aabb = RendererRD::ParticlesStorage::get_singleton()->particles_get_aabb(particles_cmd->particles); + AABB aabb = RSG::particles_storage->particles_get_aabb(particles_cmd->particles); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); } diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index 9da022341c..1724a99b20 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -31,8 +31,6 @@ #ifndef RENDERINGSERVERCANVASRENDER_H #define RENDERINGSERVERCANVASRENDER_H -#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h" -#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h" #include "servers/rendering/renderer_storage.h" class RendererCanvasRender { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 7b92e92f8c..181d7819da 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1391,7 +1391,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -1401,7 +1401,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } |