79 lines
2 KiB
GDScript
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
|