【Godot4.3】基于EasyTreeData解析的扩展Tree控件 - ETDTree

概述

基于EasyTreeData解析的扩展Tree控件。

EasyTreeData(ETD)

EasyTreeData(ETD)是一种基于Tab缩进的简单层级结构数据,可以用于描述树形结构。能够被解析为Tree控件或表示树形结构的其他类或控件。

根目录 | 0
	节点1
	节点2 | 0
		节点3
			节点4
	节点5
		节点6

ETD相关文章

Godot4.2自定义控件系列目录

类图关系

在这里插入图片描述

代码

# =============================================
# 名称:ETDTree
# 类型:自定义节点(扩展控件)
# 描述:基于EasyTreeDataETD)数据的扩展Tree控件
# 作者:巽星石
# Godot版本:v4.3.stable.steam [77dcf97d8]
# 创建时间:202491923:40:06
# 最后修改时间:202491923:55:59
# =============================================
@tool
class_name ETDTree extends Tree

# ================================ 参数 ================================
## EasyTreeData
@export_multiline var data:String:
	set(val):
		data = val
		reload()

## 图标集
@export var icons:Array[Texture2D]:
	set(val):
		icons = val
		reload()

## 图标最大宽度
@export var icon_width = 16:
	set(val):
		icon_width = val
		reload()

# ================================ 方法 ================================
# 解析和重新加载Tree结构
func reload():
	clear() # 清空
	var items = data.split("\n",false)    # 将ETD字符串按行切分为字符串数组
	var pre_itm:TreeItem                  # 记录前一项对应的TreeItem
	var p_itm = null                      # 记录父节点

	# 遍历每行数据
	for i in range(items.size()):
		# 第1行直接添加为Tree控件的根节点(跳过下面if部分)
		# 从第2行开始比较当前行与前一行的缩进深度(也就是\t的数目)
		if i > 0: 
			var d_deep = deep(items[i-1]) - deep(items[i])  # 与前一行数据的缩进差值
			match d_deep:
				-1:                                # 缩进比前一项深:
					p_itm = pre_itm                # 将前一项作为父节点
				0:                                 # 缩进深度与前一项一样:
					p_itm = pre_itm.get_parent()   # 父节点与前一项父节点一样
				_:                                 
					if d_deep>0:                   # 缩进比前一项浅
												   # 通过缩进差值计算获得合适的父节点
						p_itm = pre_itm            
						for j in range(d_deep+1):
							p_itm = p_itm.get_parent()
		
		# 实际创建和添加TreeItemTree控件
		var itm:TreeItem = create_item(p_itm)
		# 解析单项的具体信息
		if items[i].find(" | ")>0:
			var itm_data = items[i].split(" | ")
			itm.set_text(0,itm_data[0])
			if icons.size() > int(itm_data[1]):
				itm.set_icon(0,icons[int(itm_data[1])])
			itm.set_icon_max_width(0,icon_width)
		else:
			itm.set_text(0,items[i])
		pre_itm = itm                              # 将当前项记录为前一项

# 返回字符串的Tab缩进值
func deep(sttr:String):
	return sttr.rstrip(" ").count("\t")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巽星石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值