@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 func _ready() -> void: _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: ## 初始狀態,什麽都沒有 pass 1: ## vaild 狀態,可以插入了 pass func _btn_init() -> void: clear_button.pressed.connect(_on_clear_pressed) func _on_clear_pressed() -> void: _clear_cached_act() func init(index: int) -> void: self.index.text = str(index) func _on_node_path_dropped(path: NodePath) -> void: ## 如果已經可以插入但是重新被插入了一個State,先clear再插入。 if get_ready_to_insert(): _clear_cached_act() var state := StateResolveUtils.get_state_node_from_path(path) if state == null: _clear_cached_act() _reset_to_default() return var info := StateResolveUtils.resolve_state_display_info(state) if info == null: _clear_cached_act() _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) _update_context(info) drop_area.vaild = true 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: state_label.text = NORMAL_STATE_LABLE state_label.modulate = COLOR_IDLE context.text = NORMAL_CONTEXT context.modulate = COLOR_IDLE ## 初始化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: _cached_single_act = null _cached_prop_id = -1 _cached_info = {} drop_area.vaild = false _update_context() ## 设置文本 func _update_context(info:Dictionary = {}) ->void: ## 如果没有传入有效的info且没有cached过act,则直接返回 ## TODO:这里后续应该有一个报错的Message if info == {} : if _cached_info == {}: 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 != {} )