【Godot4.2】文件系统自定义控件 - GroupButtons

本文介绍了一种名为GroupButtons的Godot4.2自定义控件,用于展示分组按钮,提供直观的导航结构。通过解析自定义数据,简化了使用过程,并展示了如何处理按钮点击信号获取分组信息。
摘要由CSDN通过智能技术生成

概述

在编写Godot插件和应用时,通常都需要设计一个导航结构,除了Tree控件的树形结构之外,也可以使用分组按钮的形式,相当于一个简化的二级树形导航结构,这种形式我在自己编写的Godot插件中广泛使用。

这个自定义控件,也适用于编写Godot应用程序时,进行功能导航。本次基于Godot4.2重新编写,并通过解析自定义数据形式简化使用。

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

类图结构

在这里插入图片描述

动态生成的结构

GroupButtons本质是根据简易数据或方法,动态生成一个嵌套的分组和基于网格容器布局的多按钮形式。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/32823364b74248ef86f7efc5ea6a0614.png

使用展示

在这里插入图片描述

代码

同样只需要拷贝下面的代码到你的插件或程序项目(Godot4.2或以上)中,可以命名为“GroupButtons.gd”。

# =============================================
# 名称:GroupButtons
# 类型:自定义节点(扩展控件)
# 描述:专用于显示分组按钮
# 作者:巽星石
# Godot版本:v4.2.1.stable.official [b09f793f5]
# 创建时间:20242723:59:18
# 最后修改时间:20242801:30:44
# =============================================
@tool
extends PanelContainer
class_name GroupButtons

## 按钮点击时触发
signal button_clicked(group_title:String,title:String)


## 包含分组和具体按钮文本的自定义数据,格式如下:[br]
## 分组标题==按钮名称||按钮名称...[br]
## 分组标题==按钮名称||按钮名称...[br]
## ...
@export_multiline var data:String = "":
	set(val):
		data = val
		reload()

## 展开图标,显示在分组按钮右侧
@export var expand_icon:Texture2D:
	set(val):
		expand_icon = val
		reload()

## 收起图标,显示在分组按钮右侧
@export var fold_icon:Texture2D:
	set(val):
		fold_icon = val
		reload()

var root:VBoxContainer  # 添加分组的VBox容器

# 实例化时进行初始化构建
func _init():
	# 创建最基础的容器框架
	var scroll = ScrollContainer.new()
	var vbox = VBoxContainer.new()
	vbox.size_flags_horizontal=Control.SIZE_EXPAND_FILL
	scroll.add_child(vbox)
	add_child(scroll)
	root = vbox

# 根据data重新加载整个分组按钮列表
func reload():
	# 清空原有分组
	for child in root.get_children():
		child.queue_free()
	# 加载新分组
	var datas = data.split("\n")
	for dt in datas:
		add_group(dt)


# 根据分组数据(形如“分组标题==按钮名称||按钮名称”)添加一个分组
func add_group(gup_data:String):
	var gup_name = gup_data
	var datas = gup_data.split("==")
	if datas.size()>0:
		gup_name = datas[0]
	# 创建分组和分组标题按钮
	var vbox = vbox(group_button(gup_name))
	var grid = grid()
	grid.columns = 2
	# 创建具体的按钮
	if datas.size()>1:
		var btns = datas[1].split("||")
		for bt in btns:
			var btn = button(bt)
			btn.size_flags_horizontal=Control.SIZE_EXPAND_FILL
			## 按钮点击处理
			btn.connect("pressed",func():
				emit_signal("button_clicked",gup_name,bt)
			)
			grid.add_child(btn)
	vbox.add_child(grid)
	root.add_child(vbox)

# ============================ 控件生成函数 ============================
# ============== 说明:以下函数仅用于生成控件或容器,用于简化代码 
# 创建并返回一个VBoxContainer实例,并添加child为子节点
func vbox(child:Control = null) -> VBoxContainer:
	var v_box = VBoxContainer.new()
	if child:
		v_box.add_child(child)
	return v_box
	
# 创建并返回一个GridContainer实例,并添加child为子节点
func grid(child:Control = null) -> GridContainer:
	var g = GridContainer.new()
	if child:
		g.add_child(child)
	return g

# 创建并返回一个按钮实例
func button(title:String) -> Button:
	var btn = Button.new()
	btn.text = title
	return btn

# 创建并返回一个分组标题按钮实例
func group_button(gup_name:String) -> Button:
	var gup_btn = button(gup_name)
	gup_btn.icon = fold_icon
	gup_btn.expand_icon = true
	gup_btn.icon_alignment=HORIZONTAL_ALIGNMENT_RIGHT
	gup_btn.flat = true
	# 分组按钮点击处理
	gup_btn.connect("pressed",func():
		var parent = gup_btn.get_parent()
		if parent is VBoxContainer:
			var grid = parent.get_child(1)
			if grid is GridContainer:
				grid.visible = not grid.visible
				if gup_btn.icon == fold_icon:
					gup_btn.icon = expand_icon
				else:
					gup_btn.icon = fold_icon
	)
	return gup_btn

使用方法

添加自定义控件实例

将脚本拷贝和创建到项目中后,在具体场景中添加GroupButtons控件实例。

在这里插入图片描述

设定data快速生成分组和分组下按钮

将控件放大至合适大小,在检视器面板设定参数,其中data属性采用如下自定义形式:

分组标题==按钮名称||按钮名称...
分组标题==按钮名称||按钮名称...
...

其中:

  • 每一行描述一个分组
  • ==之前是分组标题,==之后是分组下的按钮标题,每个按钮标题之间用||作为分隔

在这里插入图片描述

设定折叠或展开图标

  • expand_iconfold_icon用于在分组标题的最右侧显示图标,表示分组发热折叠或展开状态。
    在这里插入图片描述

自定义控件样式

因为本质上GroupButtons的根节点是PanelContainer类型,所以它本身就继承自PanelContainer。因此你可以用自定义的StyleBox资源灯修改它的样式。通过自定义背景颜色等,获得更好的样式:
在这里插入图片描述
以下是调整后的样式:
在这里插入图片描述

  • 在制作编辑器插件时,我更倾向于不去调整原始的控件和容器样式,因为一切都可以直接跟随编辑器的样式发生变化。

处理按钮点击

  • 通过连接自定义信号button_clicked,可以获取每个按钮的分组标题及其自身的标题,通过match之类的分支结构,可以进行具体的逻辑处理。
    在这里插入图片描述

信号处理代码如下:

func _on_group_button_button_clicked(group_title, title):
	print(group_title,":",title)
	pass

它将打印出点击的按钮所在的分组的标题及其自身的标题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

巽星石

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

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

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

打赏作者

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

抵扣说明:

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

余额充值