immersive-home/content/ui/components/button/button.gd

170 lines
3.6 KiB
GDScript3
Raw Normal View History

@tool
2023-11-28 00:46:05 +02:00
extends Node3D
2023-11-16 20:23:17 +02:00
class_name Button3D
2023-11-22 02:44:07 +02:00
signal on_button_down()
signal on_button_up()
2024-03-07 15:21:31 +02:00
const IconFont = preload ("res://assets/icons/icons.tres")
2023-11-28 00:46:05 +02:00
@onready var label_node: Label3D = $Body/Label
@onready var finger_area: Area3D = $FingerArea
@export var focusable: bool = true:
set(value):
focusable = value
2023-11-28 15:20:38 +02:00
if value == false:
add_to_group("ui_focus_stop")
2023-11-28 00:46:05 +02:00
else:
2023-11-28 15:20:38 +02:00
remove_from_group("ui_focus_stop")
2023-11-28 00:46:05 +02:00
@export var font_size: int = 10:
set(value):
font_size = value
if !is_node_ready(): await ready
label_node.font_size = value
@export var label: String = "":
set(value):
2023-11-26 04:06:31 +02:00
label = value
2023-11-26 13:58:31 +02:00
if !is_node_ready(): await ready
label_node.text = value
@export var icon: bool = false:
set(value):
icon = value
2023-11-26 13:58:31 +02:00
if !is_node_ready(): await ready
2023-11-26 04:06:31 +02:00
if value:
label_node.font = IconFont
2024-01-23 19:02:41 +02:00
label_node.font_size = 36
2023-11-26 04:06:31 +02:00
label_node.width = 1000
label_node.autowrap_mode = TextServer.AUTOWRAP_OFF
2023-11-28 00:46:05 +02:00
else:
label_node.font = null
label_node.font_size = font_size
label_node.width = 50
label_node.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
2023-11-26 04:06:31 +02:00
2023-11-16 20:23:17 +02:00
@export var toggleable: bool = false
@export var disabled: bool = false
2023-11-18 15:27:42 +02:00
@export var initial_active: bool = false
2024-01-23 18:48:13 +02:00
var external_value: Proxy = null:
set(value):
2024-01-23 19:02:41 +02:00
if !is_node_ready(): await ready
2024-01-23 18:48:13 +02:00
external_value = value
if value != null:
value.on_set.connect(func(_value):
update_animation()
)
2023-11-28 00:46:05 +02:00
var active: bool = false:
get:
if external_value != null:
return external_value.value
return active
2023-11-16 20:23:17 +02:00
set(value):
2024-01-23 19:02:41 +02:00
if !is_node_ready(): await ready
2023-11-28 00:46:05 +02:00
if external_value != null:
external_value.value = value
2023-11-16 20:23:17 +02:00
else:
2023-11-28 00:46:05 +02:00
active = value
update_animation()
2023-11-16 20:23:17 +02:00
@onready var animation_player: AnimationPlayer = $AnimationPlayer
2024-03-07 15:21:31 +02:00
@onready var console = get_node("/root/Main/Console")
2023-11-16 20:23:17 +02:00
2023-11-18 15:27:42 +02:00
func _ready():
if initial_active:
active = true
2023-11-28 00:46:05 +02:00
func update_animation():
var length = animation_player.get_animation("down").length
2024-03-07 15:21:31 +02:00
if active&&animation_player.current_animation_position != length:
2023-11-28 00:46:05 +02:00
animation_player.play("down")
2024-03-07 15:21:31 +02:00
elif !active&&animation_player.current_animation_position != 0:
2023-11-28 00:46:05 +02:00
animation_player.play_backwards("down")
2023-11-22 02:44:07 +02:00
func _on_press_down(event):
2023-11-16 20:23:17 +02:00
if disabled:
2023-11-22 02:44:07 +02:00
event.bubbling = false
2023-11-16 20:23:17 +02:00
return
AudioPlayer.play_effect("click")
2023-11-28 00:46:05 +02:00
if toggleable:
2023-11-16 20:23:17 +02:00
return
2023-11-22 02:44:07 +02:00
active = true
on_button_down.emit()
2023-11-16 20:23:17 +02:00
2023-11-22 02:44:07 +02:00
func _on_press_up(event):
2023-11-16 20:23:17 +02:00
if disabled:
2023-11-22 02:44:07 +02:00
event.bubbling = false
2023-11-16 20:23:17 +02:00
return
2023-11-22 02:44:07 +02:00
if toggleable:
active = !active
2023-11-22 02:44:07 +02:00
if active:
on_button_down.emit()
else:
on_button_up.emit()
else:
active = false
on_button_up.emit()
2023-11-28 00:46:05 +02:00
func _on_touch_enter(event: EventTouch):
2024-03-07 15:21:31 +02:00
if event.target != finger_area:
return
2023-11-28 00:46:05 +02:00
animation_player.stop()
animation_player.speed_scale = 0
animation_player.current_animation = "down"
2023-11-28 01:51:44 +02:00
AudioPlayer.play_effect("click")
2023-11-28 00:46:05 +02:00
_touch_change(event)
func _on_touch_move(event: EventTouch):
_touch_change(event)
func _on_touch_leave(_event: EventTouch):
animation_player.stop()
animation_player.speed_scale = 1
if toggleable:
active = !active
if active:
2024-03-07 15:21:31 +02:00
on_button_up.emit()
2023-11-28 00:46:05 +02:00
else:
on_button_down.emit()
func _touch_change(event: EventTouch):
if disabled:
event.bubbling = false
return
var pos = Vector3(0, 1, 0)
for finger in event.fingers:
var finger_pos = to_local(finger.area.global_position)
if pos.y > finger_pos.y:
pos = finger_pos
2024-03-07 15:21:31 +02:00
var button_height = 0.2
var button_center = 0.1
2023-11-28 00:46:05 +02:00
var percent = clamp((button_center + button_height / 2 - pos.y) / (button_height / 2), 0, 1)
2024-03-07 15:21:31 +02:00
if !active&&percent < 1:
2023-11-28 00:46:05 +02:00
on_button_down.emit()
2024-03-07 15:21:31 +02:00
elif active&&percent >= 1:
2023-11-28 00:46:05 +02:00
on_button_up.emit()
animation_player.seek(percent * animation_player.current_animation_length, true)
if toggleable:
return
active = percent < 1