From 77c7a91f2ce3885b2f69aa7a8424fa3a8c1c0a74 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Sun, 30 Nov 2025 18:22:13 -0300 Subject: [PATCH 1/9] Enable line numbers and auto indentation for HBCodeEdit. --- tools/editor/controls/HBEditorCodeEdit.gd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/editor/controls/HBEditorCodeEdit.gd b/tools/editor/controls/HBEditorCodeEdit.gd index 3b52dca0..4b4ed953 100644 --- a/tools/editor/controls/HBEditorCodeEdit.gd +++ b/tools/editor/controls/HBEditorCodeEdit.gd @@ -843,6 +843,10 @@ func _init(): file.store_string(FONT_LICENSE) func _ready(): + # Setup editing options. + self.indent_automatic = true + self.gutters_draw_line_numbers = true + # Setup syntax highlighting. syntax_highlighter = CodeHighlighter.new() From 5eb767ffbd1a3b11ee15dee478f59c2adba0acc0 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Mon, 1 Dec 2025 14:03:23 -0300 Subject: [PATCH 2/9] Reorganize arrange module slightly. --- graphics/icons/autoangles.svg | 39 +++++++ graphics/icons/autoangles.svg.import | 37 ++++++ graphics/icons/reverse-arrange.svg | 47 ++++++++ graphics/icons/reverse-arrange.svg.import | 37 ++++++ tools/editor/editor_modules/ArrangeModule.gd | 14 +-- .../editor/editor_modules/ArrangeModule.tscn | 109 ++++++++++-------- 6 files changed, 228 insertions(+), 55 deletions(-) create mode 100644 graphics/icons/autoangles.svg create mode 100644 graphics/icons/autoangles.svg.import create mode 100644 graphics/icons/reverse-arrange.svg create mode 100644 graphics/icons/reverse-arrange.svg.import diff --git a/graphics/icons/autoangles.svg b/graphics/icons/autoangles.svg new file mode 100644 index 00000000..16424d9c --- /dev/null +++ b/graphics/icons/autoangles.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/graphics/icons/autoangles.svg.import b/graphics/icons/autoangles.svg.import new file mode 100644 index 00000000..e3ef61b7 --- /dev/null +++ b/graphics/icons/autoangles.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7xk8p6rfcm3r" +path="res://.godot/imported/autoangles.svg-4f938c9fbf9b3b3b67c37939d085293e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://graphics/icons/autoangles.svg" +dest_files=["res://.godot/imported/autoangles.svg-4f938c9fbf9b3b3b67c37939d085293e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=20.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/graphics/icons/reverse-arrange.svg b/graphics/icons/reverse-arrange.svg new file mode 100644 index 00000000..47d432ac --- /dev/null +++ b/graphics/icons/reverse-arrange.svg @@ -0,0 +1,47 @@ + + + + + + + + + diff --git a/graphics/icons/reverse-arrange.svg.import b/graphics/icons/reverse-arrange.svg.import new file mode 100644 index 00000000..9c15535b --- /dev/null +++ b/graphics/icons/reverse-arrange.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ruj0nqhq6wf5" +path="res://.godot/imported/reverse-arrange.svg-1edab6754c9408412d0b073d3a56d1cd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://graphics/icons/reverse-arrange.svg" +dest_files=["res://.godot/imported/reverse-arrange.svg-1edab6754c9408412d0b073d3a56d1cd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=20.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/tools/editor/editor_modules/ArrangeModule.gd b/tools/editor/editor_modules/ArrangeModule.gd index f90ce283..c25ec15e 100644 --- a/tools/editor/editor_modules/ArrangeModule.gd +++ b/tools/editor/editor_modules/ArrangeModule.gd @@ -186,25 +186,25 @@ func update_shortcuts(): var arrange_ev = arrange_event_list[0] if arrange_event_list else null if arrange_ev: - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/Label.show() - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/Label.text = \ + $%QuickPlacingLabel.show() + $%QuickPlacingLabel.text = \ "Hold " + get_event_text(arrange_ev) + " for quick placing." - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/Label.tooltip_text = \ + $%QuickPlacingLabel.tooltip_text = \ "The arrange wheel helps you place notes quickly.\n" + \ "Hold Shift for reverse arranging.\n" + \ "Hold Control to toggle automatic angles.\n" + \ "Shortcut: " + get_event_text(arrange_ev) else: - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/Label.hide() + $%QuickPlacingLabel.hide() var size_up_event_list = InputMap.action_get_events("editor_circle_size_bigger") var size_down_event_list = InputMap.action_get_events("editor_circle_size_smaller") var size_up_ev = size_up_event_list[0] if size_up_event_list else null var size_down_ev = size_down_event_list[0] if size_down_event_list else null - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2.tooltip_text = "Amount of 8th notes required for \na full revolution." - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2.tooltip_text += "\nShortcut (increase): " + get_event_text(size_up_ev) - $MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2.tooltip_text += "\nShortcut (decrease): " + get_event_text(size_down_ev) + $%CircleSizeHBoxContainer.tooltip_text = "Amount of 8th notes required for \na full revolution." + $%CircleSizeHBoxContainer.tooltip_text += "\nShortcut (increase): " + get_event_text(size_up_ev) + $%CircleSizeHBoxContainer.tooltip_text += "\nShortcut (decrease): " + get_event_text(size_down_ev) func apply_transform(id: int): hide_transform() diff --git a/tools/editor/editor_modules/ArrangeModule.tscn b/tools/editor/editor_modules/ArrangeModule.tscn index cb257e23..d5fcf65a 100644 --- a/tools/editor/editor_modules/ArrangeModule.tscn +++ b/tools/editor/editor_modules/ArrangeModule.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=25 format=3 uid="uid://dp3dxv1k748mt"] +[gd_scene load_steps=27 format=3 uid="uid://dp3dxv1k748mt"] [ext_resource type="Texture2D" uid="uid://d0x0jbwaj58e" path="res://graphics/icons/rotate-relative-right.svg" id="2"] [ext_resource type="Script" uid="uid://d3j8dwm1jc0vn" path="res://tools/editor/editor_modules/ArrangeModule.gd" id="3"] [ext_resource type="Script" uid="uid://clphuuunv7ko1" path="res://tools/editor/controls/HBEditorSpinBox.gd" id="4"] [ext_resource type="Script" uid="uid://bp3qrjahqrk31" path="res://tools/editor/controls/HBEditorButtonPad.gd" id="4_dfckn"] +[ext_resource type="Texture2D" uid="uid://ruj0nqhq6wf5" path="res://graphics/icons/reverse-arrange.svg" id="4_o6l4o"] [ext_resource type="Texture2D" uid="uid://c2gg4gcju4k0o" path="res://graphics/icons/rotate-relative-left.svg" id="5"] [ext_resource type="Texture2D" uid="uid://duqakdxh3srcf" path="res://graphics/icons/arrange-pad.svg" id="5_52snf"] +[ext_resource type="Texture2D" uid="uid://b7xk8p6rfcm3r" path="res://graphics/icons/autoangles.svg" id="5_lnkft"] [ext_resource type="Texture2D" uid="uid://bgi10pnx3ybc0" path="res://graphics/icons/circle-clockwise.svg" id="7_5egqo"] [ext_resource type="Texture2D" uid="uid://2uvl0wk3sttg" path="res://graphics/icons/arrow-left-right.svg" id="8"] [ext_resource type="Texture2D" uid="uid://d260pibrxbfsb" path="res://graphics/icons/circle-counterclockwise.svg" id="8_y761g"] @@ -37,17 +39,21 @@ anchors_preset = 15 grow_horizontal = 2 grow_vertical = 2 -[node name="VBoxContainer" parent="MarginContainer/ScrollContainer" index="0"] -size_flags_horizontal = 3 - [node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="0"] layout_mode = 2 size_flags_horizontal = 3 text = "Arrange in a line..." horizontal_alignment = 1 -autowrap_mode = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="1"] +[node name="QuickPlacingLabel" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="1"] +unique_name_in_owner = true +layout_mode = 2 +tooltip_text = "The arrange wheel helps you place notes quickly (Hold Shift for reverse)." +mouse_filter = 0 +text = "Hold SHORTCUT for quick placing." +horizontal_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="2"] layout_mode = 2 [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer" index="0"] @@ -55,14 +61,7 @@ layout_mode = 2 size_flags_horizontal = 3 alignment = 1 -[node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="0"] -layout_mode = 2 -tooltip_text = "The arrange wheel helps you place notes quickly (Hold Shift for reverse)." -mouse_filter = 0 -text = "Hold SHORTCUT for quick placing." -horizontal_alignment = 1 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="1"] +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="0"] layout_mode = 2 tooltip_text = "Angle at which to place the notes." alignment = 1 @@ -77,7 +76,7 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 -[node name="StandardHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="2"] +[node name="StandardHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="1"] unique_name_in_owner = true layout_mode = 2 tooltip_text = "Angle at which to place the notes." @@ -100,7 +99,7 @@ suffix = "ยบ" custom_arrow_step = 1.0 script = ExtResource("4") -[node name="DiagonalStepHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="3"] +[node name="DiagonalStepHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="2"] unique_name_in_owner = true visible = false layout_mode = 2 @@ -137,7 +136,7 @@ suffix = "px" custom_arrow_step = 1.0 script = ExtResource("4") -[node name="FullWidthHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="4"] +[node name="FullWidthHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="3"] unique_name_in_owner = true visible = false layout_mode = 2 @@ -159,41 +158,54 @@ suffix = "px" custom_arrow_step = 1.0 script = ExtResource("4") -[node name="HBoxContainer3" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="5"] +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer" index="4"] layout_mode = 2 alignment = 1 -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3" index="0"] +[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer" index="0"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer" index="1"] layout_mode = 2 tooltip_text = "Arrange from the last note rather than the first. Shortcut: Shift" alignment = 1 -[node name="ReverseArrangeCheckBox" type="CheckBox" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3/HBoxContainer" index="0" groups=["disabled_ui"]] -unique_name_in_owner = true +[node name="TextureRect" type="TextureRect" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer" index="0"] layout_mode = 2 +texture = ExtResource("4_o6l4o") +expand_mode = 2 -[node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3/HBoxContainer" index="1"] +[node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer" index="1"] layout_mode = 2 text = "Arrange from last note" -[node name="VSeparator" type="VSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3" index="1"] +[node name="ReverseArrangeCheckBox" type="CheckBox" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer" index="2" groups=["disabled_ui"]] +unique_name_in_owner = true layout_mode = 2 -[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3" index="2"] +[node name="HSeparator2" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer" index="2"] +layout_mode = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer" index="3"] layout_mode = 2 tooltip_text = "Set basic angles while arranging. Shortcut: Control" alignment = 1 -[node name="AutoAngleCheckBox" type="CheckBox" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3/HBoxContainer2" index="0" groups=["disabled_ui"]] -unique_name_in_owner = true +[node name="TextureRect" type="TextureRect" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer2" index="0"] +layout_mode = 2 +texture = ExtResource("5_lnkft") +expand_mode = 2 + +[node name="Label2" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer2" index="1"] layout_mode = 2 +text = "Automatic angles" -[node name="Label2" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3/HBoxContainer2" index="1"] +[node name="AutoAngleCheckBox" type="CheckBox" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer2" index="2" groups=["disabled_ui"]] +unique_name_in_owner = true layout_mode = 2 -text = "Change angles" [node name="ArrangeButtonPad" type="Container" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer" index="1" groups=["arrange_buttons"]] unique_name_in_owner = true @@ -211,29 +223,30 @@ line direction." texture = ExtResource("5_52snf") button_mode = "function" function_name = "_menu_arrange_button_pressed" -metadata/_custom_type_script = ExtResource("4_dfckn") +metadata/_custom_type_script = "uid://bp3qrjahqrk31" -[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="2"] +[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="3"] layout_mode = 2 -[node name="Label2" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="3"] +[node name="Label2" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="4"] layout_mode = 2 text = "Arrange in a circle..." horizontal_alignment = 1 -[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="4"] +[node name="CircleSizeHBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="5"] +unique_name_in_owner = true layout_mode = 2 tooltip_text = "Amount of 8th notes required for a full revolution." -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2" index="0"] +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/CircleSizeHBoxContainer" index="0"] layout_mode = 2 -[node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2/HBoxContainer" index="0"] +[node name="Label" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/CircleSizeHBoxContainer/HBoxContainer" index="0"] layout_mode = 2 text = "Size:" -[node name="CircleSizeSpinBox" type="SpinBox" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2/HBoxContainer" index="1" groups=["disabled_ui"]] +[node name="CircleSizeSpinBox" type="SpinBox" parent="MarginContainer/ScrollContainer/VBoxContainer/CircleSizeHBoxContainer/HBoxContainer" index="1" groups=["disabled_ui"]] unique_name_in_owner = true layout_mode = 2 min_value = 4.0 @@ -241,7 +254,7 @@ max_value = 64.0 value = 16.0 script = ExtResource("4") -[node name="CircleSizeHSlider" type="HSlider" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer2" index="1" groups=["disabled_ui"]] +[node name="CircleSizeHSlider" type="HSlider" parent="MarginContainer/ScrollContainer/VBoxContainer/CircleSizeHBoxContainer" index="1" groups=["disabled_ui"]] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 @@ -251,7 +264,7 @@ value = 16.0 tick_count = 8 ticks_on_borders = true -[node name="HBoxContainer3" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="5"] +[node name="HBoxContainer3" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="6"] layout_mode = 2 alignment = 1 @@ -335,15 +348,15 @@ texture = ExtResource("8_y761g") transform_id = 1 action = "editor_make_circle_ccw" -[node name="HSeparator4" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="6"] +[node name="HSeparator4" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="7"] layout_mode = 2 -[node name="Label5" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="7"] +[node name="Label5" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="8"] layout_mode = 2 text = "Arrange in an arc..." horizontal_alignment = 1 -[node name="HBoxContainer4" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="8"] +[node name="HBoxContainer4" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="9"] layout_mode = 2 alignment = 1 @@ -440,15 +453,15 @@ texture = ExtResource("12_1o5sg") transform_id = 11 action = "editor_make_arc_ccw" -[node name="HSeparator2" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="9"] +[node name="HSeparator2" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="10"] layout_mode = 2 -[node name="Label3" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="10"] +[node name="Label3" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="11"] layout_mode = 2 text = "Flip and mirror..." horizontal_alignment = 1 -[node name="HBoxRatioContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="11"] +[node name="HBoxRatioContainer" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="12"] custom_minimum_size = Vector2(312, 0) layout_mode = 2 script = ExtResource("21") @@ -505,15 +518,15 @@ texture = ExtResource("8") transform_id = 7 action = "editor_flip_h" -[node name="HSeparator3" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="12"] +[node name="HSeparator3" type="HSeparator" parent="MarginContainer/ScrollContainer/VBoxContainer" index="13"] layout_mode = 2 -[node name="Label4" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="13"] +[node name="Label4" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer" index="14"] layout_mode = 2 text = "Rotate notes..." horizontal_alignment = 1 -[node name="HBoxContainer5" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="14"] +[node name="HBoxContainer5" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="15"] layout_mode = 2 tooltip_text = "Amount of 8th notes required for a full revolution." @@ -542,7 +555,7 @@ max_value = 180.0 tick_count = 9 ticks_on_borders = true -[node name="HBoxRatioContainer2" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="15"] +[node name="HBoxRatioContainer2" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer" index="16"] custom_minimum_size = Vector2(276, 0) layout_mode = 2 script = ExtResource("21") @@ -608,4 +621,4 @@ visible = false [connection signal="value_changed" from="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/DiagonalStepHBoxContainer/DiagonalStepXSpinBox" to="." method="_on_arrange_diagonal_step_spinbox_value_changed"] [connection signal="value_changed" from="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/DiagonalStepHBoxContainer/DiagonalStepYSpinBox" to="." method="_on_arrange_diagonal_step_spinbox_value_changed"] [connection signal="value_changed" from="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/FullWidthHBoxContainer/VerticalStepSpinBox" to="." method="_on_arrange_vstep_spinbox_value_changed"] -[connection signal="toggled" from="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/HBoxContainer3/HBoxContainer2/AutoAngleCheckBox" to="." method="_on_auto_angle_check_box_toggled"] +[connection signal="toggled" from="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer2/AutoAngleCheckBox" to="." method="_on_auto_angle_check_box_toggled"] From 5cf3a23360a985df6f3c6d9cc7a257eb2aae4f4f Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Tue, 3 Feb 2026 08:02:24 -0300 Subject: [PATCH 3/9] Properly save timing_method (by IdolInTeal). --- scripts/HBUserSettings.gd | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/HBUserSettings.gd b/scripts/HBUserSettings.gd index 7949eecf..d98c8f29 100644 --- a/scripts/HBUserSettings.gd +++ b/scripts/HBUserSettings.gd @@ -287,6 +287,7 @@ func _init(): "lag_compensation", "resource_pack", "romanized_titles_enabled", "show_latency", "enable_voice_fade", "ui_skin", + "timing_method", "note_size", "input_map", "input_map_version", "fps_limit", "display_mode", "display", "desired_video_fps", "ytdlp_custom_command_line", "desired_video_resolution", "disable_video", "disable_ppd_video", "use_visualizer_with_video", "sort_filter_settings", "last_selected_difficulty", "leading_trail_enabled", From bcbdc77397cad1dc28cd94c43ac0681e8f476b3d Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 08:17:51 -0300 Subject: [PATCH 4/9] Remove playlist arguments from youtube url. (fixes #416) --- .../YoutubeDLDownloaderUI.gd | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/youtube_dl_downloader_ui/YoutubeDLDownloaderUI.gd b/tools/youtube_dl_downloader_ui/YoutubeDLDownloaderUI.gd index 7c4abebe..212f109b 100644 --- a/tools/youtube_dl_downloader_ui/YoutubeDLDownloaderUI.gd +++ b/tools/youtube_dl_downloader_ui/YoutubeDLDownloaderUI.gd @@ -18,6 +18,22 @@ enum State { var current_process: Process func _start_download(url: String, save_to: String, download_video: bool): + # Remove playlist parameters from url + var url_params := url.split("?", true, 1) + if url_params.size() == 2: + var params = url_params[1].split("&") + + var new_params = PackedStringArray() + for param in params: + if not param.begins_with("list"): + new_params.append(param) + + url_params[1] = "&".join(new_params) + + print(url) + url = "?".join(url_params) + print(url) + var yt_dlp_path := YoutubeDL.get_ytdl_executable() as String var shared_params := YoutubeDL.get_ytdl_shared_params(false, false) as Array var format_options: PackedStringArray = PackedStringArray([ From 6f818c70acaef9e110b70fcc23c5b330ef8de0bf Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 08:38:28 -0300 Subject: [PATCH 5/9] Remove nonexistant signals from song list. (fixes #417) --- menus/song_list/SongList.gd | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/menus/song_list/SongList.gd b/menus/song_list/SongList.gd index 871cc956..f00e91b0 100644 --- a/menus/song_list/SongList.gd +++ b/menus/song_list/SongList.gd @@ -143,15 +143,14 @@ func _on_menu_enter(force_hard_transition=false, args = {}): MouseTrap.ppd_dialog.connect("youtube_url_selected", Callable(self, "_on_youtube_url_selected")) MouseTrap.ppd_dialog.connect("file_selected", Callable(self, "_on_ppd_audio_file_selected")) MouseTrap.ppd_dialog.connect("file_selector_hidden", Callable(song_container, "grab_focus").bind(), CONNECT_DEFERRED) - MouseTrap.ppd_dialog.connect("visibility_changed", self._on_ppd_dialog_visiblity_changed, CONNECT_DEFERRED) -# song_container.hard_arrange_all() - #sort_button_texture_rect.texture = IconPackLoader.get_graphic("UP", "note") - #fav_button_texture_rect.texture = IconPackLoader.get_graphic("LEFT", "note") + if not MouseTrap.ppd_dialog.is_connected("visibility_changed", self._on_ppd_dialog_visibility_changed): + MouseTrap.ppd_dialog.connect("visibility_changed", self._on_ppd_dialog_visibility_changed, CONNECT_DEFERRED) + if "force_url_request" in args: _on_PPDAudioBrowseWindow_accept() song_container.grab_focus() -func _on_ppd_dialog_visiblity_changed(): +func _on_ppd_dialog_visibility_changed(): if MouseTrap.ppd_dialog.visible: song_container.grab_focus() @@ -186,7 +185,6 @@ func _on_menu_exit(force_hard_transition = false): MouseTrap.ppd_dialog.disconnect("youtube_url_selected", Callable(self, "_on_youtube_url_selected")) MouseTrap.ppd_dialog.disconnect("file_selected", Callable(self, "_on_ppd_audio_file_selected")) MouseTrap.ppd_dialog.disconnect("file_selector_hidden", Callable(song_container, "grab_focus")) - MouseTrap.ppd_dialog.disconnect("popup_hide", Callable(song_container, "grab_focus")) if PlatformService.service_provider.implements_ugc: PlatformService.service_provider.ugc_provider.disconnect("ugc_song_meta_updated", Callable(self, "_on_ugc_song_meta_updated")) HBGame.rich_presence.notify_at_main_menu() From 81449c9ea2a39e1ff479780c26d0f97a042ff316 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 08:56:31 -0300 Subject: [PATCH 6/9] Dont apply per-song latency on editor seek and autoplay. (fixes #370) --- rythm_game/game_modes/RhythmGameBase.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rythm_game/game_modes/RhythmGameBase.gd b/rythm_game/game_modes/RhythmGameBase.gd index b5b4df95..990a5478 100644 --- a/rythm_game/game_modes/RhythmGameBase.gd +++ b/rythm_game/game_modes/RhythmGameBase.gd @@ -620,7 +620,7 @@ func _process_game(_delta): func get_latency_compensation_msec() -> int: var latency_compensation = UserSettings.user_settings.lag_compensation - if current_song.id in UserSettings.user_settings.per_song_settings: + if current_song.id in UserSettings.user_settings.per_song_settings and game_mode == GAME_MODE.NORMAL: latency_compensation += UserSettings.user_settings.per_song_settings[current_song.id].lag_compensation return latency_compensation From cc433f2928596ce11631904f38e29ee2402774f2 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 12:12:51 -0300 Subject: [PATCH 7/9] Add default value to get_meta in the transformation display (Fixes #412) --- .../transformation_display/EditorTransformationTemplate.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/transformation_display/EditorTransformationTemplate.gd b/tools/editor/transformation_display/EditorTransformationTemplate.gd index 85057588..f0d462dd 100644 --- a/tools/editor/transformation_display/EditorTransformationTemplate.gd +++ b/tools/editor/transformation_display/EditorTransformationTemplate.gd @@ -13,6 +13,6 @@ func transform_notes(notes: Array) -> Dictionary: for note in notes: if template.has_type_template(note.note_type, note.get_meta("second_layer", false)): - notes_to_transform_map[note] = template.get_type_template(note.note_type, note.get_meta("second_layer")) + notes_to_transform_map[note] = template.get_type_template(note.note_type, note.get_meta("second_layer", false)) return notes_to_transform_map From 685a550ac3009eca59505013ad8851dda32655c4 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 12:58:00 -0300 Subject: [PATCH 8/9] Add metadata support for timing points and related script functions. This commit adds 2 functions to the public scripting API: - set_timing_point_meta(timing_point, key, value) - get_timing_point_meta(timing_point, key, default_value) --- scripts/timing_points/HBTimingPoint.gd | 3 ++- .../ScriptsModule/ScriptRunnerScript.gd | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/timing_points/HBTimingPoint.gd b/scripts/timing_points/HBTimingPoint.gd index ea393748..2b341199 100644 --- a/scripts/timing_points/HBTimingPoint.gd +++ b/scripts/timing_points/HBTimingPoint.gd @@ -3,6 +3,7 @@ extends HBSerializable class_name HBTimingPoint var time: int +var meta := {} var _class_name: String = "HBTimingPoint" # Workaround for godot#4708 var _inheritance: Array = [] # HACK: ClassDB.get_parent_class() is retarded @@ -13,7 +14,7 @@ func get_log_name(): return get_serialized_type() func _init(): - serializable_fields += ["time"] + serializable_fields += ["time", "meta"] func get_serialized_type(): return "TimingPoint" diff --git a/tools/editor/editor_modules/ScriptsModule/ScriptRunnerScript.gd b/tools/editor/editor_modules/ScriptsModule/ScriptRunnerScript.gd index 6b39c3ab..130f0926 100644 --- a/tools/editor/editor_modules/ScriptsModule/ScriptRunnerScript.gd +++ b/tools/editor/editor_modules/ScriptsModule/ScriptRunnerScript.gd @@ -28,6 +28,21 @@ func set_timing_point_property(timing_point: HBTimingPoint, property_name: Strin _timing_point_changed_properties[timing_point] = {} _timing_point_changed_properties[timing_point][property_name] = value +func get_timing_point_meta(timing_point: HBTimingPoint, key: String, default_value = null): + if key in timing_point.meta: + return timing_point.meta[key] + else: + return default_value + +func set_timing_point_meta(timing_point: HBTimingPoint, key: String, value): + if not timing_point in _timing_point_changed_properties: + _timing_point_changed_properties[timing_point] = {} + + if "meta" in _timing_point_changed_properties[timing_point]: + _timing_point_changed_properties[timing_point]["meta"][key] = value + else: + _timing_point_changed_properties[timing_point]["meta"] = {key: value} + func bsearch_time(a, b): var a_t = a var b_t = b From b3929679d4dd9a642f661a70550215b1517a8fe2 Mon Sep 17 00:00:00 2001 From: Lino Bigatti Date: Wed, 4 Feb 2026 13:18:14 -0300 Subject: [PATCH 9/9] Select variant correctly for editor playback. (Fixes #354) --- tools/editor/EditorPlayback.gd | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/tools/editor/EditorPlayback.gd b/tools/editor/EditorPlayback.gd index e6d592ca..8215a825 100644 --- a/tools/editor/EditorPlayback.gd +++ b/tools/editor/EditorPlayback.gd @@ -29,24 +29,6 @@ func _init(_game: HBRhythmGame): self.game = _game func _process(delta): - var time = 0.0 - if is_playing() and false: - time = (Time.get_ticks_usec() - time_begin) / 1000000.0 - time *= playback_speed - # Compensate for latency. - time -= time_delay - time -= UserSettings.user_settings.lag_compensation / 1000.0 - # May be below 0 (did not being yet). - time = max(0, time) - - time = time + _audio_play_offset - - var variant_offset = 0 - if current_song: - variant_offset = current_song.get_variant_offset(selected_variant) / 1000.0 - time += variant_offset - game.time_msec = time * 1000.0 - if is_playing() and game.audio_playback.is_playing(): emit_signal("time_changed", game.time_msec / 1000.0) @@ -56,6 +38,7 @@ func get_song_volume(): func set_song(song: HBSong, difficulty: String, assets: SongAssetLoader.AssetLoadToken, variant=-1): current_song = song selected_variant = variant + game.current_variant = variant game.audio_playback = null game.voice_audio_playback = null