Godot自定义控件样式语法解析

前言

本篇原始文章写于2023年8月7日,存储在我的语雀文档中。但是语雀分享有诸多不便,为了让更多Godoter更轻松的搜到和看到,就转过来了。
这个项目我上传了Github,后续会贴上链接。

概述

Godot控件体系存在的问题之一就是样式无法用纯文本形式简洁而清晰的定义,一切都要靠主题编辑器或检视器面板那一套手动的东西。4.x提供了一些样式属性和方法,但仍然算不上简洁。

在样式定义方面,前端的CSS样式表可谓是最佳实践之一。

如果能够以类似CSS一样的纯文本形式解析和控制Godot的控件样式,那么样式定义就能更轻松。

基于这样的想法,笔者尝试建立了一个类CSS样式的样式书写和解析机制。让使用者可以基于一个简单的导出变量,用纯文本的方式定义控件的样式。

样式解析函数库

ConfigFile提供了一个名叫parse() 的方法,可以将符合ConfigFile风格和书写规则的字符串直接解析到ConfigFile实例。进而可以使用其提供的方法便捷的遍历节、键和值。

基于此我创建了一个名为Sty的静态函数库。
下面是初期的一个效果,已经可以解析按钮多个状态下的一些简单样式。

# ========================================================
# 名称:Sty
# 类型:静态函数库
# 简介:用于解析和应用控件样式
# 作者:巽星石
# Godot版本:4.1.1-stable (official)
# 创建时间:2023-08-07 23:11:57
# 最后修改时间:2023-08-07 23:11:57
# ========================================================
class_name Sty# 样式解析
static func parse_style(ctl:Control,style_str:String):var cfg = ConfigFile.new()var err = cfg.parse(style_str.replace(":","=\"").replace(";","\""))if err == OK: # 解析成功for section in cfg.get_sections():for key in cfg.get_section_keys(section):var val = cfg.get_value(section,key)match key:"font_size":pass"color":match section:"normal":ctl.add_theme_color_override("font_color",Color(val))"hover","pressed","disabled","focus":ctl.add_theme_color_override("font_%s_color" % section,Color(val))"bg_color":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)stylebox.bg_color = Color(val)"radius":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.corner_radius_top_left = int(vals[0])stylebox.corner_radius_top_right = int(vals[1])stylebox.corner_radius_bottom_left = int(vals[2])stylebox.corner_radius_bottom_right = int(vals[3])"border_width":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.border_width_left = int(vals[0])stylebox.border_width_top = int(vals[1])stylebox.border_width_right = int(vals[2])stylebox.border_width_bottom = int(vals[3])"border_color":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)stylebox.border_color = Color(val)"padding":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.content_margin_left = int(vals[0])stylebox.content_margin_top = int(vals[1])stylebox.content_margin_right = int(vals[2])stylebox.content_margin_bottom = int(vals[3])"margin":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.expand_margin_left = int(vals[0])stylebox.expand_margin_top = int(vals[1])stylebox.expand_margin_right = int(vals[2])stylebox.expand_margin_bottom = int(vals[3])"shadow_color":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)stylebox.shadow_color = Color(val)"shadow_size":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)stylebox.shadow_size = int(val)"shadow_offset":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.shadow_offset = Vector2(float(vals[0]),float(vals[1]))"skew":match section:"normal","hover","pressed","disabled","focus":var stylebox:StyleBoxFlat = get_stylebox(ctl,section)var vals = val.split(",")stylebox.skew = Vector2(float(vals[0]),float(vals[1]))# 获取控件对应名称的样式盒
static func get_stylebox(ctl:Control,name:String) -> StyleBoxFlat:var stylebox:StyleBoxFlatif ctl.has_theme_stylebox_override(name):stylebox = ctl.get_theme_stylebox(name)else:stylebox= StyleBoxFlat.new()ctl.add_theme_stylebox_override(name, stylebox)return stylebox

实际使用

为普通节点添加style属性

我们创建一个UI场景,添加一个Button
在这里插入图片描述

Button添加如下代码:

@tool
extends Button@export_multiline var style:String = "":set(val):style = valSty.parse_style(self,val)

接着我们在检视器面板的style变量中,定义如下的样式:

[normal]
font_size :64;
color:#FF4400;
bg_color:yellow;
radius:55,5,56,45;
skew:0.1,0;
border_width:5,2,5,2;
border_color:#444;
[disable]
color:#00FF00;
[hover]
color:#00FF00;
bg_color:#ccc;
radius:55,5,5,45;

关于语法

因为我是以Button控件为模板进行初期的样式语法测试,所以以Button为例的话,我们可以看到一个按钮的样式其实是可以分为几个状态的:正常(normal),禁用(disable),鼠标经过(hover),按下(pressed),获得焦点(focus)。

所以我采用了状态优先,属性名称简化和重用的设计,并且采用了Godot的ConfigFile格式。

将按钮的不同状态作为配置文件的section,但是为了简化书写,让其更像是CSS风格,所以采用了冒号和封号,而不是等号来设定键值对。在解析时冒号和封号会被替换。

然后对应的按钮样式被定义为如下图:
在这里插入图片描述

因为加了@tool关键字,所以在normal状态中定义的样式都会被实时的显示在编辑器中,而其他的诸如hover等需要在运行后查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/504729.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人值守,24小时水质在线检测系统,助力信息化平台建设

水质在线监测系统主要由在线自动检测系统、通信网络和监控中心三部分组成,可以在无人值守的情况下自动完成水样的采集、水质分析、数据的采集和通信传输。 主要功能:监测水厂出口,输水管线和终端的水质情况。具体要求:地图显示。…

elegentbook模板不生成目录的解决方法

这里只有目录两个字、却没有生成目录 在json里面修改 "latex-workshop.latex.autoClean.run": "onBuilt",把onBuilt改为onFailed即可 "latex-workshop.latex.autoClean.run": "onFailed",

正压式采样器——气体采样器

不管路有多远,只要你不停步,总会在你的脚下。无论志向有多高,只要你不放弃,总会在你的胸怀。不要等待机会,而是创造机会。只有走出来的美丽,没有等出来的辉煌。 正压采样器的用途: 该正压采样器…

php连接hdfs初步探索

一、phdfs拓展 结果:暂时舍弃 安装此拓展时,无法make成功,因为缺少hdfs.n文件。 换了其他版本的拓展包,并编译都没有找到此文件。 后搜到官网的相关资料,此hdfs.h的文件路径的地址是$HADOOP_HDFS_HOME/include/hdfs…

【计算机网络_应用层】协议定制序列化反序列化

文章目录 1. TCP协议的通信流程2. 应用层协议定制3. 通过“网络计算器”的实现来实现应用层协议定制和序列化3.1 protocol3.2 序列化和反序列化3.2.1 手写序列化和反序列化3.2.2 使用Json库 3.3 数据包读取3.4 服务端设计3.5 最后的源代码和运行结果 1. TCP协议的通信流程 在之…

安装OPC报1603错误的处理

因为本电脑调试过OPC Client软件,设置过DCOM,待安装OPC Server时报1603错误: 研究颇久,后来发现修改一下dcom配置就好了: 运行 dcomcnfg,将“我的电脑”属性修改如下:

自注意力机制(Self-Attention)

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站(【http://www.aideeplearning.cn】) Transformer模型中最关键部分就是自注意力(Self-Attention)机制,正如 Transformer 的论文的标题是“…

⭐每天一道leetcode:13.罗马数字转整数(简单)

⭐今日份题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 100…

拒绝机械风,让ChatGPT像真人一样对话

拒绝机械风,让ChatGPT像真人一样对话 在这个信息爆炸的时代,人工智能技术的快速发展让我们的生活变得更加便捷。 特别是在自然语言处理领域,ChatGPT的出现无疑是一次革命性的进步。 然而,虽然ChatGPT在很多方面表现出了惊人的能…

【VSCODE修改代码行间距】解决方案

在我们编码的过程中,由于显示字体和显示器的不同,会需要调整行间距,在vscode默认的选项中没有看到设定行间距的选项,不过,可以手动修改配置档达到目的。 1.打开设置 2.打开配置档,手动进行设定 3.在选项中添…

永磁同步电机无感FOC(龙伯格观测器)算法技术总结-实战篇

文章目录 1、ST龙伯格算法分析(定点数)1.1 符号说明1.2 最大感应电动势计算1.3 系数计算1.4 龙伯格观测器计算1.5 锁相环计算1.6 观测器增益计算1.7 锁相环PI计算(ST)1.8 平均速度的用意 2、启动策略2.1 V/F压频比控制2.2 I/F压频…

【全局异常处理记录】⭐️通过自定义全局处理器有效统一各种异常并记录

目录 前言 方案 示例 测试 总结 前言 朋友们大家好啊,随着项目的进行,接口也是越来越多了,每个接口无论调用成功与否,都要有相应的应对措施,总不能出错的时候返回一堆异常信息给调用者,所以每个接口都…