straywild/ui/components/bubble_menu/bubble_gradient_background.gd

79 lines
2 KiB
GDScript

class_name BubbleGradientBackground
extends Control
const CORNER_SEGMENTS: int = 8
var host_button: BaseButton
var profile: BubbleMenuProfile
func configure(
button: BaseButton,
menu_profile: BubbleMenuProfile,
) -> void:
host_button = button
profile = menu_profile
mouse_filter = Control.MOUSE_FILTER_IGNORE
show_behind_parent = true
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
queue_redraw()
func _draw() -> void:
if host_button == null or profile == null or size.x <= 0.0 or size.y <= 0.0:
return
var fill_color: Color = _get_fill_color()
var top_color: Color = fill_color.lightened(profile.gradient_top_lift)
var points := PackedVector2Array()
_append_arc(points, Vector2(profile.corner_radius, profile.corner_radius), PI, PI * 1.5)
_append_arc(
points,
Vector2(size.x - profile.corner_radius, profile.corner_radius),
PI * 1.5,
TAU,
)
_append_arc(
points,
Vector2(size.x - profile.corner_radius, size.y - profile.corner_radius),
0.0,
PI * 0.5,
)
_append_arc(
points,
Vector2(profile.corner_radius, size.y - profile.corner_radius),
PI * 0.5,
PI,
)
var colors := PackedColorArray()
for point: Vector2 in points:
colors.append(top_color.lerp(fill_color, clampf(point.y / size.y, 0.0, 1.0)))
draw_polygon(points, colors)
func _append_arc(
points: PackedVector2Array,
center: Vector2,
start_angle: float,
end_angle: float,
) -> void:
var radius: float = minf(
float(profile.corner_radius),
minf(size.x, size.y) * 0.5,
)
for index: int in range(CORNER_SEGMENTS + 1):
var weight: float = float(index) / float(CORNER_SEGMENTS)
var angle: float = lerpf(start_angle, end_angle, weight)
points.append(center + Vector2(cos(angle), sin(angle)) * radius)
func _get_fill_color() -> Color:
if host_button.disabled:
return profile.disabled_fill
match host_button.get_draw_mode():
BaseButton.DRAW_PRESSED, BaseButton.DRAW_HOVER_PRESSED:
return profile.pressed_fill
BaseButton.DRAW_HOVER:
return profile.hover_fill
if host_button.has_focus():
return profile.hover_fill
return profile.normal_fill