From ec1602315890a94b5e4f7934f8cd0321797c5608 Mon Sep 17 00:00:00 2001 From: dnesov Date: Sun, 16 Feb 2025 17:17:53 +0100 Subject: [PATCH] WIP: audio clip controls and UI --- Assets/DefaultTheme.tres | 2 ++ Controls/AudioClip.tscn | 42 +++++++++++++++++++++++++++ Scripts/AudioClip.gd | 63 ++++++++++++++++++++++++++++++++++++++++ Scripts/Timeline.gd | 17 +++++++++++ Views/Timeline.tscn | 15 +++++++++- 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 Controls/AudioClip.tscn create mode 100644 Scripts/AudioClip.gd diff --git a/Assets/DefaultTheme.tres b/Assets/DefaultTheme.tres index 9ce3e06..387bec0 100644 --- a/Assets/DefaultTheme.tres +++ b/Assets/DefaultTheme.tres @@ -2677,6 +2677,8 @@ AssetLib/colors/status_color = Color(0.5, 0.5, 0.5, 1) AssetLib/icons/dismiss = null AssetLib/styles/bg = SubResource("StyleBoxEmpty_6c8sw") AssetLib/styles/panel = SubResource("StyleBoxFlat_0c4py") +AudioClip/colors/deselected_modulate = Color(0.552941, 0.552941, 0.552941, 1) +AudioClip/colors/selected_modulate = Color(1, 1, 1, 1) BottomPanelButton/styles/hover = SubResource("StyleBoxFlat_jduyo") BottomPanelButton/styles/hover_pressed = SubResource("StyleBoxFlat_jduyo") BottomPanelButton/styles/normal = SubResource("StyleBoxFlat_sxnkh") diff --git a/Controls/AudioClip.tscn b/Controls/AudioClip.tscn new file mode 100644 index 0000000..6b4e079 --- /dev/null +++ b/Controls/AudioClip.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=3 format=3 uid="uid://dmmgalpx4fcc7"] + +[ext_resource type="Script" path="res://Scripts/AudioClip.gd" id="1_iy5jd"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8tb17"] +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.273873, 0.273873, 0.273873, 1) +border_blend = true + +[node name="AudioClip" type="Panel"] +modulate = Color(0.552956, 0.552956, 0.552956, 1) +clip_contents = true +custom_minimum_size = Vector2(4, 64) +anchors_preset = -1 +anchor_right = 0.104 +anchor_bottom = 0.059 +offset_right = 0.319992 +offset_bottom = 0.279995 +theme_override_styles/panel = SubResource("StyleBoxFlat_8tb17") +script = ExtResource("1_iy5jd") + +[node name="Panel" type="Panel" parent="."] +custom_minimum_size = Vector2(0, 14) +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 + +[node name="Label" type="Label" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/font_size = 8 +text = "New Audio Clip" +vertical_alignment = 1 +text_overrun_behavior = 3 diff --git a/Scripts/AudioClip.gd b/Scripts/AudioClip.gd new file mode 100644 index 0000000..2b89cae --- /dev/null +++ b/Scripts/AudioClip.gd @@ -0,0 +1,63 @@ +class_name AudioClip +extends Panel + +@export var start_time: float = 0.0 +@export var end_time: float = 0.0 +@export var track_idx: int = 0 + +var timeline: Timeline + +var dragging: bool +var selected: bool + +func _ready(): + timeline = get_parent() + +func _input(event): + var rect = get_global_rect() + var mouse_position = get_global_mouse_position() + + if event is InputEventMouseButton: + if event.pressed and event.button_mask == MOUSE_BUTTON_LEFT: + if selected: + mouse_default_cursor_shape = CURSOR_MOVE + dragging = true + else: + dragging = false + mouse_default_cursor_shape = CURSOR_ARROW + if rect.has_point(mouse_position): + selected = true + make_selected() + return + else: + selected = false + make_deselected() + return + + if !event.pressed and dragging: + dragging = false + mouse_default_cursor_shape = CURSOR_ARROW + + if selected and dragging: + if event is InputEventMouseMotion: + var movement = event.relative.x / timeline.get_pixels_per_unit() * timeline.time_interval + + start_time += movement + end_time += movement + + if event.is_command_or_control_pressed(): + start_time = snapped(start_time, timeline.time_interval) + end_time = snapped(end_time, timeline.time_interval) + + timeline.queue_sort() + pass + +func make_selected(): + var color = get_theme_color("selected_modulate", "AudioClip") + modulate = color + pass + +func make_deselected(): + var color = get_theme_color("deselected_modulate", "AudioClip") + modulate = color + pass \ No newline at end of file diff --git a/Scripts/Timeline.gd b/Scripts/Timeline.gd index ebf8137..a30b030 100644 --- a/Scripts/Timeline.gd +++ b/Scripts/Timeline.gd @@ -34,6 +34,10 @@ func format_time_ms_minutes(ms: float) -> String: var milliseconds = fmod(ms, 1000.0) return "%02d:%02d.%03d" % [minutes, seconds, milliseconds] + +func get_pixels_per_unit() -> float: + return 50.0 * zoom + func _draw(): var primary_color = get_theme_color("line_primary_color", "Timeline") var secondary_color = get_theme_color("line_secondary_color", "Timeline") @@ -70,8 +74,21 @@ func _draw(): draw_string(font, Vector2(x - time_label_offset_x, time_label_offset_y), format_time_ms_minutes(time), HORIZONTAL_ALIGNMENT_CENTER, -1, font_size, primary_color) else: draw_line(Vector2(x, 28.0), Vector2(x, timeline_y), secondary_color, 1) + + queue_sort() pass +func _notification(what): + if what == NOTIFICATION_SORT_CHILDREN: + for c in get_children(): + if c is not AudioClip: continue + var pixels_per_unit := 50.0 * zoom + var start = ((c.start_time / time_interval) * pixels_per_unit) - time_offset + var width = (c.end_time - c.start_time) / time_interval * pixels_per_unit + + c.position = Vector2(start, 0.0) + c.size = Vector2(width, c.size.y) + func _gui_input(event): var zoom_factor = 1.1 if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_WHEEL_DOWN: diff --git a/Views/Timeline.tscn b/Views/Timeline.tscn index a439f6c..d36b318 100644 --- a/Views/Timeline.tscn +++ b/Views/Timeline.tscn @@ -1,14 +1,17 @@ -[gd_scene load_steps=2 format=3 uid="uid://v4oljx3qrk5q"] +[gd_scene load_steps=3 format=3 uid="uid://v4oljx3qrk5q"] [ext_resource type="Script" path="res://Scripts/Timeline.gd" id="1_h2mev"] +[ext_resource type="PackedScene" uid="uid://dmmgalpx4fcc7" path="res://Controls/AudioClip.tscn" id="2_an2hv"] [node name="Timeline" type="Container"] +clip_children = 2 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 +size_flags_vertical = 3 script = ExtResource("1_h2mev") end_time = 4000.0 @@ -16,3 +19,13 @@ end_time = 4000.0 visible = false custom_minimum_size = Vector2(0, 20) layout_mode = 2 + +[node name="AudioClip" parent="." instance=ExtResource("2_an2hv")] +layout_mode = 2 +start_time = 4000.0 +end_time = 8000.0 + +[node name="AudioClip2" parent="." instance=ExtResource("2_an2hv")] +layout_mode = 2 +start_time = 8000.0 +end_time = 12000.0