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

GroupButtons

概述

读者朋友们好,我是巽星石,这是我的Godot4.2文件系统自定义控件系列文章。

在很多程序或插件设计中,都会用到一堆按钮的形式,好处是比较直观,用啥点啥,本质上相当于一个简化的二级树形导航结构。

这种结构我在自己编写的Godot插件myAdd中使用过,这次是基于Godot4.2重新编写,并通过解析自定义数据形式简化使用的版本。

【Godot4.2】文件系统自定义控件 - GroupButtons_第1张图片

代码

同样只需要拷贝下面的代码到你的插件或程序项目(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

使用方法

脚本拷贝和创建到项目中后,在具体场景中添加节点。

【Godot4.2】文件系统自定义控件 - GroupButtons_第2张图片
将控件放大至合适大小,在检视器面板设定参数,其中data属性采用的是我自定义的一种数据形式,格式如下:

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

也就是说:

  • 每一行描述一个分组
  • ==之前是分组标题,之后==之后是分组下的按钮标题,每个按钮标题之间用||作为分隔
    【Godot4.2】文件系统自定义控件 - GroupButtons_第3张图片
    expand_icon和fold_icon用于在分组折叠或展开时显示。
    【Godot4.2】文件系统自定义控件 - GroupButtons_第4张图片
    因为本质上GroupButtons是基于PanelContainer,因此你可以用自定义的StyleBox资源修饰它。
    通过自定义背景颜色,就可以获得更好的样式:
    【Godot4.2】文件系统自定义控件 - GroupButtons_第5张图片
    以下是调整后的样式:
    【Godot4.2】文件系统自定义控件 - GroupButtons_第6张图片

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

获取按钮点击信息

通过连接和处理自定义信号button_clicked,可以获取每个按钮的分组标题及其自身的标题,通过match之类的分支结构,可以进行具体的处理。
【Godot4.2】文件系统自定义控件 - GroupButtons_第7张图片

信号处理代码如下:

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

你可能感兴趣的:(Godot4.0,Godot自定义控件,godot)