Files
whale-town-front-v2/scenes/ui/SettingsSlider.gd

84 lines
3.0 KiB
GDScript

extends Control
# ============================================================================
# SettingsSlider.gd - 设置面板自绘滑条
# ============================================================================
# 使用白色圆形滑块和柔和轨道,贴近概念图里的轻量滑条样式。
# ============================================================================
signal value_changed(value: float)
const TRACK_COLOR: Color = Color(0.842, 0.894, 0.936, 0.95)
const FILL_COLOR: Color = Color(0.258824, 0.627451, 0.913725, 1.0)
const KNOB_COLOR: Color = Color(1.0, 1.0, 1.0, 1.0)
const KNOB_SHADOW_COLOR: Color = Color(0.125, 0.282, 0.408, 0.16)
var value: float = 1.0
var _dragging: bool = false
func _ready() -> void:
custom_minimum_size = Vector2(360, 34)
mouse_filter = Control.MOUSE_FILTER_STOP
mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
func set_value(newValue: float, emitSignal: bool = false) -> void:
var clamped: float = clampf(newValue, 0.0, 1.0)
if abs(value - clamped) < 0.001:
return
value = clamped
queue_redraw()
if emitSignal:
value_changed.emit(value)
func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
var mouseEvent := event as InputEventMouseButton
if mouseEvent.button_index != MOUSE_BUTTON_LEFT:
return
_dragging = mouseEvent.pressed
if _dragging:
_update_from_x(mouseEvent.position.x)
accept_event()
return
if event is InputEventMouseMotion and _dragging:
var motionEvent := event as InputEventMouseMotion
_update_from_x(motionEvent.position.x)
accept_event()
func _draw() -> void:
var trackHeight: float = 8.0
var knobRadius: float = 12.0
var left: float = knobRadius + 1.0
var right: float = size.x - knobRadius - 1.0
var centerY: float = size.y * 0.5
var width: float = max(1.0, right - left)
var knobX: float = left + width * value
var trackRect: Rect2 = Rect2(Vector2(left, centerY - trackHeight * 0.5), Vector2(width, trackHeight))
draw_style_box(_round_box(TRACK_COLOR, int(trackHeight * 0.5)), trackRect)
var fillRect: Rect2 = Rect2(trackRect.position, Vector2(max(trackHeight, knobX - left), trackHeight))
draw_style_box(_round_box(FILL_COLOR, int(trackHeight * 0.5)), fillRect)
var knobCenter: Vector2 = Vector2(knobX, centerY)
draw_circle(knobCenter + Vector2(0, 1.4), knobRadius + 1.0, KNOB_SHADOW_COLOR)
draw_circle(knobCenter, knobRadius, KNOB_COLOR)
draw_arc(knobCenter, knobRadius, 0.0, TAU, 32, Color(0.790, 0.848, 0.902, 0.75), 1.0, true)
func _update_from_x(x: float) -> void:
var knobRadius: float = 12.0
var left: float = knobRadius + 1.0
var right: float = size.x - knobRadius - 1.0
var width: float = max(1.0, right - left)
set_value((x - left) / width, true)
func _round_box(color: Color, radius: int) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = color
style.corner_radius_top_left = radius
style.corner_radius_top_right = radius
style.corner_radius_bottom_left = radius
style.corner_radius_bottom_right = radius
return style