mirror of
https://github.com/Cuteminded/jellyframe.git
synced 2026-10-29 04:01:14 +01:00
73 lines
3.0 KiB
GDScript
73 lines
3.0 KiB
GDScript
class_name PlaybackTimeline
|
|
extends VBoxContainer
|
|
|
|
signal seek_requested(milliseconds: int)
|
|
var slider: HSlider
|
|
var elapsed_label: Label
|
|
var duration_label: Label
|
|
var dragging := false
|
|
var buffered_bar: ProgressBar
|
|
|
|
func _ready() -> void:
|
|
var times := HBoxContainer.new()
|
|
add_child(times)
|
|
elapsed_label = Widgets.label("0:00", times, 20)
|
|
elapsed_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
duration_label = Widgets.label("--:--", times, 20)
|
|
var track_area := Control.new()
|
|
track_area.custom_minimum_size.y = 56
|
|
add_child(track_area)
|
|
buffered_bar = ProgressBar.new()
|
|
buffered_bar.show_percentage = false
|
|
buffered_bar.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
buffered_bar.set_anchors_and_offsets_preset(Control.PRESET_TOP_WIDE)
|
|
buffered_bar.offset_top = 23
|
|
buffered_bar.offset_bottom = 33
|
|
buffered_bar.add_theme_stylebox_override("background", Widgets.surface(Color("445268"), 5))
|
|
buffered_bar.add_theme_stylebox_override("fill", Widgets.surface(Color("8998af"), 5))
|
|
track_area.add_child(buffered_bar)
|
|
slider = HSlider.new()
|
|
slider.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
slider.custom_minimum_size.y = 56
|
|
slider.step = 1000
|
|
slider.scrollable = false
|
|
slider.editable = false
|
|
slider.tooltip_text = "Seek to a time"
|
|
var track := Widgets.surface(Color.TRANSPARENT, 5)
|
|
track.content_margin_top = 5
|
|
track.content_margin_bottom = 5
|
|
slider.add_theme_stylebox_override("slider", track)
|
|
var fill := track.duplicate() as StyleBoxFlat
|
|
fill.bg_color = Color("6de3cf")
|
|
slider.add_theme_stylebox_override("grabber_area", fill)
|
|
slider.add_theme_stylebox_override("grabber_area_highlight", fill)
|
|
track_area.add_child(slider)
|
|
slider.drag_started.connect(func(): dragging = true)
|
|
slider.value_changed.connect(func(value: float):
|
|
elapsed_label.text = format_time(int(value))
|
|
if not dragging: seek_requested.emit(int(value)))
|
|
slider.drag_ended.connect(func(changed: bool):
|
|
dragging = false
|
|
if changed: seek_requested.emit(int(slider.value)))
|
|
visibility_changed.connect(func():
|
|
if not is_visible_in_tree(): dragging = false)
|
|
|
|
func update_time(position_ms: int, duration_ms: int, ready: bool = true) -> void:
|
|
if dragging: return
|
|
slider.editable = ready and duration_ms > 0
|
|
slider.set_block_signals(true)
|
|
slider.max_value = maxi(1, duration_ms)
|
|
slider.value = clampi(position_ms, 0, duration_ms) if duration_ms > 0 else 0
|
|
slider.set_block_signals(false)
|
|
elapsed_label.text = format_time(maxi(0, position_ms))
|
|
duration_label.text = format_time(duration_ms) if duration_ms > 0 else "--:--"
|
|
|
|
func update_buffer(buffered_ms: int, duration_ms: int, ready: bool) -> void:
|
|
buffered_bar.max_value = maxi(1, duration_ms)
|
|
buffered_bar.value = clampi(buffered_ms, 0, duration_ms) if ready and buffered_ms >= 0 and duration_ms > 0 else 0
|
|
|
|
static func format_time(milliseconds: int) -> String:
|
|
var seconds := maxi(0, milliseconds / 1000)
|
|
if seconds >= 3600: return "%d:%02d:%02d" % [seconds / 3600, (seconds / 60) % 60, seconds % 60]
|
|
return "%d:%02d" % [seconds / 60, seconds % 60]
|