103 lines
2.4 KiB
GDScript
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):
|
|
vaild = value
|
|
_set_state(0)
|
|
|
|
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)
|