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

228 lines
5.4 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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