228 lines
5.4 KiB
GDScript
228 lines
5.4 KiB
GDScript
@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
|
||
@onready var clear_button: Button = %ClearButton
|
||
|
||
@onready var index: Label = %Index
|
||
|
||
var _cached_single_act: SingleAct = null
|
||
var _cached_prop_id: int = -1
|
||
var _cached_info: Dictionary
|
||
|
||
var _state: int = 0
|
||
|
||
const NORMAL_STATE_LABLE: String = "Drag state node to icon."
|
||
const NORMAL_CONTEXT: String = "Information will be show here."
|
||
|
||
#const ICON_COLOR: Dictionary = {
|
||
#"Idle": Color.GRAY,
|
||
#""
|
||
#}
|
||
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
|
||
|
||
signal prop_info_cached(info: Dictionary,slot:StateDrapSlot)
|
||
signal prop_info_released(id:int, slot:StateDrapSlot)
|
||
|
||
func _ready() -> void:
|
||
_btn_init()
|
||
|
||
_reset_to_default()
|
||
_reset_cb_use_trans()
|
||
|
||
if drop_area:
|
||
drop_area.node_path_dropped.connect(_on_node_path_dropped)
|
||
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: ## 初始狀態,什麽都沒有
|
||
_reset_to_default()
|
||
1: ## vaild 狀態,可以插入了
|
||
drop_area.vaild = true
|
||
_update_context()
|
||
prop_info_cached.emit(_cached_info,self)
|
||
|
||
func _btn_init() -> void:
|
||
clear_button.pressed.connect(_on_clear_pressed)
|
||
|
||
func _on_clear_pressed() -> void:
|
||
_set_state(0)
|
||
|
||
func init(index: int) -> void:
|
||
self.index.text = str(index)
|
||
|
||
func _on_node_path_dropped(path: NodePath) -> void:
|
||
if _state == 1:
|
||
_set_state(0)
|
||
|
||
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
|
||
|
||
##缓存一遍有效的info
|
||
_cached_info = info
|
||
|
||
# 创建 / 更新 cached
|
||
_cached_single_act = SingleAct.new()
|
||
_cached_single_act.state_id = state.state_id
|
||
_cached_single_act.use_trans = cb_use_trans.button_pressed
|
||
_cached_single_act.context = {}
|
||
|
||
_cached_prop_id = int(info.prop_id)
|
||
|
||
_set_state(1)
|
||
|
||
func _on_drap_area_state_change(state:int) -> void:
|
||
pass
|
||
|
||
func _on_use_trans_toggled(pressed: bool) -> void:
|
||
# 如果存在就改,不存在無事發生
|
||
if _cached_single_act:
|
||
_cached_single_act.use_trans = pressed
|
||
|
||
_update_context()
|
||
|
||
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:
|
||
_clear_cached_act()
|
||
state_label.text = NORMAL_STATE_LABLE
|
||
state_label.modulate = COLOR_IDLE
|
||
|
||
context.text = NORMAL_CONTEXT
|
||
context.modulate = COLOR_IDLE
|
||
drop_area.vaild = false
|
||
|
||
|
||
## 初始化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:
|
||
##如果清除前存在CahcedInfo,就释放信号
|
||
if _cached_info.has("prop_id"):
|
||
var id = _cached_info.prop_id
|
||
prop_info_released.emit(id, self)
|
||
|
||
_cached_single_act = null
|
||
_cached_prop_id = -1
|
||
_cached_info = {}
|
||
|
||
## 设置文本
|
||
func _update_context(info:Dictionary = {}) ->void:
|
||
## 如果没有传入有效的info且没有cached过act,则直接返回
|
||
## TODO:这里后续应该有一个报错的Message
|
||
if info == {} :
|
||
if _cached_info == {}:
|
||
_reset_to_default()
|
||
return
|
||
else:
|
||
info = _cached_info
|
||
|
||
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
|
||
|
||
|
||
## 外部調用,可以返回當前的Slot是否有效,懶檢查
|
||
func get_ready_to_insert() -> bool:
|
||
return (
|
||
_cached_single_act != null
|
||
and _cached_prop_id >= 0
|
||
and _cached_info != null
|
||
and _cached_info != {}
|
||
)
|