HoverLightClickArea
This commit is contained in:
parent
92e5ff60fb
commit
158fdef689
102
scene/entity/ux/hover_light_click_area.gd
Normal file
102
scene/entity/ux/hover_light_click_area.gd
Normal file
@ -0,0 +1,102 @@
|
||||
class_name HoverLightClickArea extends Area2D
|
||||
|
||||
signal interacted
|
||||
|
||||
@export var freezing := false:
|
||||
set(val):
|
||||
freezing = val
|
||||
if freezing and touching:
|
||||
_on_mouse_exited()
|
||||
|
||||
var touching = false
|
||||
static var _focus_mutex = Mutex.new()
|
||||
static var current_focusing_item = "":
|
||||
set(val):
|
||||
current_focusing_item = val
|
||||
if GlobalConfig.DEBUG:
|
||||
print("HoverLightClickArea current_focusing_item=", current_focusing_item)
|
||||
static var pending_enter_callables := [] as Array[Callable]
|
||||
|
||||
# to pointlight2d
|
||||
var lights: Array[NodePath] = []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for c in get_children():
|
||||
if c is PointLight2D:
|
||||
lights.append(self.get_path_to(c))
|
||||
if lights.is_empty():
|
||||
printerr("HoverLightButton has no PointLight2D children. auto freezed name=", name)
|
||||
freezing = true
|
||||
mouse_entered.connect(_on_mouse_entered)
|
||||
mouse_exited.connect(_on_mouse_exited)
|
||||
# 默认先熄灭
|
||||
_toggle_light(false)
|
||||
|
||||
|
||||
func is_focused() -> bool:
|
||||
return current_focusing_item == name
|
||||
|
||||
|
||||
func _on_mouse_entered() -> bool:
|
||||
touching = true
|
||||
if freezing or not is_visible_in_tree():
|
||||
return false
|
||||
if is_focused():
|
||||
return true
|
||||
_focus_mutex.lock()
|
||||
# 尝试获得 current_focusing_item
|
||||
if current_focusing_item != "":
|
||||
if not pending_enter_callables.has(_on_mouse_entered):
|
||||
pending_enter_callables.append(_on_mouse_entered)
|
||||
_focus_mutex.unlock()
|
||||
return false
|
||||
current_focusing_item = name
|
||||
_focus_mutex.unlock()
|
||||
_toggle_light(true)
|
||||
return true
|
||||
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
touching = false
|
||||
_focus_mutex.lock()
|
||||
pending_enter_callables.erase(_on_mouse_entered)
|
||||
# frezzing 不影响 mouse exited
|
||||
if is_focused():
|
||||
current_focusing_item = ""
|
||||
for c in pending_enter_callables:
|
||||
if c.call():
|
||||
break
|
||||
_focus_mutex.unlock()
|
||||
_toggle_light(false)
|
||||
|
||||
|
||||
func _toggle_light(on: bool) -> void:
|
||||
for l in lights:
|
||||
var light = get_node(l) as PointLight2D
|
||||
if light:
|
||||
light.enabled = on
|
||||
|
||||
|
||||
func invalid_blink() -> void:
|
||||
for l in lights:
|
||||
var light = get_node(l) as PointLight2D
|
||||
if light:
|
||||
var tween = create_tween()
|
||||
tween.tween_property(light, "color", Color.RED, 0.2)
|
||||
tween.tween_property(light, "color", Color.WHITE, 0.3)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if freezing or Engine.is_editor_hint() or not is_visible_in_tree():
|
||||
return
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
if is_focused():
|
||||
get_viewport().set_input_as_handled()
|
||||
interacted.emit()
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if touching:
|
||||
_on_mouse_exited()
|
1
scene/entity/ux/hover_light_click_area.gd.uid
Normal file
1
scene/entity/ux/hover_light_click_area.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://ubn3pgywffro
|
9
scene/entity/ux/hover_light_click_area.tscn
Normal file
9
scene/entity/ux/hover_light_click_area.tscn
Normal file
@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bkk1rxx36ghrl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ubn3pgywffro" path="res://scene/entity/ux/hover_light_click_area.gd" id="1_qoyst"]
|
||||
|
||||
[node name="HoverLightClickArea" type="Area2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
monitorable = false
|
||||
script = ExtResource("1_qoyst")
|
Loading…
Reference in New Issue
Block a user