Files
PNGTuber-Plus/ui_scenes/components/LabeledSlider.gd

141 lines
3.8 KiB
GDScript

@tool
## A reusable component that combines a label and slider
## Provides consistent formatting and behavior for all sliders in the UI
extends VBoxContainer
class_name LabeledSlider
## Emitted when the slider value changes
signal value_changed(value: float)
## The base text that appears in the label (without the value)
@export var label_text: String = "Value" : set = set_label_text
## The minimum value of the slider
@export var min_value: float = 0.0 : set = set_min_value
## The maximum value of the slider
@export var max_value: float = 100.0 : set = set_max_value
## The step value for the slider
@export var step: float = 1.0 : set = set_step
## The current value of the slider
@export var value: float = 0.0 : set = set_value
## Whether to show the value in the label
@export var show_value_in_label: bool = true : set = set_show_value_in_label
## Format string for the value display (e.g., "%.1f" for one decimal place)
@export var value_format: String = "%.0f" : set = set_value_format
## Optional suffix to add after the value (e.g., "%", "Hz")
@export var value_suffix: String = "" : set = set_value_suffix
## Whether the slider is editable
@export var editable: bool = true : set = set_editable
@onready var label: Label = $Label
@onready var slider: HSlider = $HSlider
func _ready():
if slider:
slider.value_changed.connect(_on_slider_value_changed)
_update_slider_properties()
# Ensure label is updated after all properties are set
call_deferred("_update_label")
func _notification(what):
if what == NOTIFICATION_SCENE_INSTANTIATED:
# Update label when scene is instantiated (important for editor)
call_deferred("_update_label")
## Set the label text
func set_label_text(new_text: String):
label_text = new_text
if is_inside_tree():
_update_label()
else:
call_deferred("_update_label")
## Set the minimum value
func set_min_value(new_min: float):
min_value = new_min
if is_inside_tree():
_update_slider_properties()
## Set the maximum value
func set_max_value(new_max: float):
max_value = new_max
if is_inside_tree():
_update_slider_properties()
## Set the step value
func set_step(new_step: float):
step = new_step
if is_inside_tree():
_update_slider_properties()
## Set the current value
func set_value(new_value: float):
value = new_value
if slider:
slider.value = value
if is_inside_tree():
_update_label()
## Set whether to show value in label
func set_show_value_in_label(show: bool):
show_value_in_label = show
if is_inside_tree():
_update_label()
## Set the value format string
func set_value_format(format: String):
value_format = format
if is_inside_tree():
_update_label()
## Set the value suffix
func set_value_suffix(suffix: String):
value_suffix = suffix
if is_inside_tree():
_update_label()
## Set whether the slider is editable
func set_editable(is_editable: bool):
editable = is_editable
if slider:
slider.editable = editable
## Update the slider properties
func _update_slider_properties():
if not slider:
return
slider.min_value = min_value
slider.max_value = max_value
slider.step = step
slider.value = value
slider.editable = editable
## Update the label text
func _update_label():
if not label:
# If label isn't ready yet, try to find it
label = get_node_or_null("Label")
if not label:
# Call again after a frame when nodes are ready
call_deferred("_update_label")
return
var text = label_text
if show_value_in_label:
var formatted_value = value_format % value
text += ": " + formatted_value + value_suffix
label.text = text
## Handle slider value changes
func _on_slider_value_changed(new_value: float):
value = new_value
_update_label()
value_changed.emit(value)
## Set the modulate color for visual feedback
func set_modulate_color(color: Color):
if slider:
slider.modulate = color