godot-plateformer/addons/reedscene/act/StateDropArea.gd

103 lines
2.4 KiB
GDScript

@tool
extends PanelContainer
class_name StateDropArea
signal node_dropped(node: Node)
@export var icon_path: NodePath = NodePath("TextureRect")
const COLOR_IDLE: Color = Color(1, 1, 1, 1.0)
const COLOR_CAN_DROP: Color = Color(0.4, 0.7, 1.0, 1.0)
const COLOR_CANNOT_DROP: Color = Color(1.0, 0.35, 0.35, 1.0)
const COLOR_CHECKED: Color = Color.GREEN
## 設置Locker的時候自更新一次State
var vaild: bool = false:
set(value):
_set_state(3)
vaild = value
var _icon: TextureRect
var _state := 0 # 0 idle, 1 can, 2 cannot
var _current_drag_data: Variant = null
signal node_path_dropped(node_path: NodePath)
signal state_change(state: int)
# =====================================================
# Life cycle
# =====================================================
func _ready() -> void:
_icon = get_node_or_null(icon_path) as TextureRect
mouse_filter = Control.MOUSE_FILTER_PASS
_ignore_mouse_recursive(self)
if _icon:
_icon.modulate = COLOR_IDLE
if custom_minimum_size == Vector2.ZERO:
custom_minimum_size = Vector2(32, 32)
#mouse_entered.connect(_on_mouse_entered)
mouse_exited.connect(_on_mouse_exited)
# =====================================================
# Drag & Drop
# =====================================================
func _can_drop_data(_pos: Vector2, data) -> bool:
_current_drag_data = data
var r = StateResolveUtils.is_valid_state_drag(data)
_set_state(1 if r else 2)
return r
func _drop_data(_pos: Vector2, data) -> void:
var path := StateResolveUtils.get_state_path_from_drag(data)
if path.is_empty():
return
node_path_dropped.emit(path)
func _notification(what: int) -> void:
if what == NOTIFICATION_DRAG_END:
_current_drag_data = null
_set_state(0)
# =====================================================
# Mouse events
# =====================================================
func _on_mouse_exited() -> void:
_set_state(0)
func _ignore_mouse_recursive(n: Node) -> void:
for c in n.get_children():
if c is Control:
(c as Control).mouse_filter = Control.MOUSE_FILTER_IGNORE
_ignore_mouse_recursive(c)
func _set_state(s: int) -> void:
if s == _state:
return
_state = s
if _icon == null:
return
match _state:
0:
if vaild:
_set_state(3)
return
_icon.modulate = COLOR_IDLE
1:
_icon.modulate = COLOR_CAN_DROP
2:
_icon.modulate = COLOR_CANNOT_DROP
3:
_icon.modulate = COLOR_CHECKED
state_change.emit(_state)