@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 != {} )