forked from xiangwang25/whale-town-front-v2
84 lines
3.0 KiB
GDScript
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
|