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

228 lines
5.4 KiB
GDScript3
Raw Normal View History

2026-01-03 23:21:04 +08:00
@tool
class_name StateDrapSlot
extends Control
@onready var drop_area: StateDropArea = %DropArea
@onready var state_label: Label = %StateLabel
@onready var context: RichTextLabel = %Context
@onready var cb_use_trans: CheckBox = %CB_UseTrans
2026-01-05 11:39:42 +08:00
@onready var clear_button: Button = %ClearButton
2026-01-03 23:21:04 +08:00
2026-01-04 21:21:01 +08:00
@onready var index: Label = %Index
2026-01-03 23:21:04 +08:00
var _cached_single_act: SingleAct = null
var _cached_prop_id: int = -1
2026-01-04 21:21:01 +08:00
var _cached_info: Dictionary
2026-01-03 23:21:04 +08:00
2026-01-05 11:39:42 +08:00
var _state: int = 0
2026-01-03 23:21:04 +08:00
const NORMAL_STATE_LABLE: String = "Drag state node to icon."
const NORMAL_CONTEXT: String = "Information will be show here."
2026-01-05 11:39:42 +08:00
#const ICON_COLOR: Dictionary = {
#"Idle": Color.GRAY,
#""
#}
2026-01-03 23:21:04 +08:00
const COLOR_IDLE: Color = Color.GRAY
const COLOR_CHECKED_1: Color = Color.GREEN
const COLOR_CHECKED_2: Color = Color.YELLOW
const COLOR_CHECKED_3: Color = Color.ORANGE_RED
2026-01-05 15:28:43 +08:00
signal prop_info_cached(info: Dictionary,slot:StateDrapSlot)
signal prop_info_released(id:int, slot:StateDrapSlot)
2026-01-05 11:39:42 +08:00
2026-01-03 23:21:04 +08:00
func _ready() -> void:
2026-01-05 15:28:43 +08:00
_btn_init()
2026-01-03 23:21:04 +08:00
_reset_to_default()
_reset_cb_use_trans()
if drop_area:
drop_area.node_path_dropped.connect(_on_node_path_dropped)
2026-01-05 11:39:42 +08:00
drop_area.state_change.connect(_on_drap_area_state_change)
## 核心函數通過狀態機來控制UI組件的狀態。
func _set_state(new_state: int) -> void:
if _state == new_state:
return
_state = new_state
match _state:
0: ## 初始狀態,什麽都沒有
2026-01-05 15:28:43 +08:00
_reset_to_default()
2026-01-05 11:39:42 +08:00
1: ## vaild 狀態,可以插入了
2026-01-05 15:28:43 +08:00
drop_area.vaild = true
_update_context()
prop_info_cached.emit(_cached_info,self)
2026-01-05 11:39:42 +08:00
func _btn_init() -> void:
clear_button.pressed.connect(_on_clear_pressed)
func _on_clear_pressed() -> void:
2026-01-05 15:28:43 +08:00
_set_state(0)
2026-01-03 23:21:04 +08:00
2026-01-04 21:21:01 +08:00
func init(index: int) -> void:
self.index.text = str(index)
2026-01-03 23:21:04 +08:00
func _on_node_path_dropped(path: NodePath) -> void:
2026-01-05 15:28:43 +08:00
if _state == 1:
_set_state(0)
2026-01-05 11:39:42 +08:00
2026-01-03 23:21:04 +08:00
var state := StateResolveUtils.get_state_node_from_path(path)
if state == null:
_reset_to_default()
return
var info := StateResolveUtils.resolve_state_display_info(state)
if info == null:
_reset_to_default()
return
2026-01-04 21:21:01 +08:00
##缓存一遍有效的info
_cached_info = info
2026-01-03 23:21:04 +08:00
# 创建 / 更新 cached
_cached_single_act = SingleAct.new()
_cached_single_act.state_id = state.state_id
2026-01-04 21:21:01 +08:00
_cached_single_act.use_trans = cb_use_trans.button_pressed
2026-01-03 23:21:04 +08:00
_cached_single_act.context = {}
_cached_prop_id = int(info.prop_id)
2026-01-05 15:28:43 +08:00
_set_state(1)
2026-01-05 11:39:42 +08:00
func _on_drap_area_state_change(state:int) -> void:
pass
2026-01-03 23:21:04 +08:00
func _on_use_trans_toggled(pressed: bool) -> void:
2026-01-04 21:21:01 +08:00
# 如果存在就改,不存在無事發生
if _cached_single_act:
_cached_single_act.use_trans = pressed
_update_context()
2026-01-03 23:21:04 +08:00
func _resolve_state_from_path(path: NodePath) -> ReedPropState:
var root := EditorInterface.get_edited_scene_root()
if root == null:
return null
var node := root.get_node_or_null(path)
if node is ReedPropState:
return node
return null
## 重置回默认
func _reset_to_default() ->void:
2026-01-05 15:28:43 +08:00
_clear_cached_act()
2026-01-03 23:21:04 +08:00
state_label.text = NORMAL_STATE_LABLE
state_label.modulate = COLOR_IDLE
context.text = NORMAL_CONTEXT
context.modulate = COLOR_IDLE
2026-01-05 15:28:43 +08:00
drop_area.vaild = false
2026-01-04 21:21:01 +08:00
2026-01-03 23:21:04 +08:00
## 初始化use trans 的 check box
func _reset_cb_use_trans() ->void:
cb_use_trans.button_pressed = false
if not cb_use_trans.toggled.is_connected(_on_use_trans_toggled):
cb_use_trans.toggled.connect(_on_use_trans_toggled)
## 创建一个CachedAct
func _build_cached_act(state: ReedPropState, info: Dictionary) -> void:
if _cached_single_act == null:
_cached_single_act = SingleAct.new()
_cached_single_act.state_id = state.state_id
_cached_single_act.use_trans = false # 默认值,可后续切换
_cached_single_act.context = {} # 预留
# Prop ID 缓存
_cached_prop_id = int(info.prop_id)
## 清空Cached Act
func _clear_cached_act() -> void:
2026-01-05 15:28:43 +08:00
##如果清除前存在CahcedInfo就释放信号
if _cached_info.has("prop_id"):
var id = _cached_info.prop_id
prop_info_released.emit(id, self)
2026-01-03 23:21:04 +08:00
_cached_single_act = null
_cached_prop_id = -1
2026-01-05 11:39:42 +08:00
_cached_info = {}
2026-01-03 23:21:04 +08:00
## 设置文本
2026-01-04 21:21:01 +08:00
func _update_context(info:Dictionary = {}) ->void:
## 如果没有传入有效的info且没有cached过act则直接返回
## TODO:这里后续应该有一个报错的Message
if info == {} :
if _cached_info == {}:
2026-01-05 15:28:43 +08:00
_reset_to_default()
2026-01-04 21:21:01 +08:00
return
else:
info = _cached_info
2026-01-03 23:21:04 +08:00
context.clear()
# —— 配置颜色变量 —— #
var prop_color_str := COLOR_CHECKED_1.to_html(false)
var state_color_str := COLOR_CHECKED_1.to_html(false)
var id_color_str := COLOR_CHECKED_2.to_html(false)
var use_trans := _cached_single_act.use_trans
var use_mark := "\u2714" if use_trans else "\u2716"
var use_mark_color_str := (
COLOR_CHECKED_1 if use_trans else COLOR_CHECKED_3
).to_html(false)
var bbcode := ""
bbcode += "[table=1][cell]"
# Prop
bbcode += "[b][color=%s]%s[/color][/b] [color=%s](ID_%s)[/color]" % [
prop_color_str,
info.prop_name,
id_color_str,
info.prop_id
]
# 空白占位
bbcode += "[color=#00000000] [/color]"
# State
bbcode += "[b][color=%s]%s[/color][/b] [color=%s](ID_%s)[/color]" % [
state_color_str,
info.state_name,
id_color_str,
info.state_id
]
# 再空白
bbcode += "[color=#00000000] [/color]"
# Use Trans 显示
bbcode += "[color=%s]%s[/color] Use Trans" % [
use_mark_color_str,
use_mark
]
bbcode += "[/cell][/table]"
context.text = bbcode
2026-01-05 11:39:42 +08:00
## 外部調用可以返回當前的Slot是否有效懶檢查
func get_ready_to_insert() -> bool:
return (
_cached_single_act != null
and _cached_prop_id >= 0
and _cached_info != null
and _cached_info != {}
)