2 个版本
使用旧的 Rust 2015
0.1.1 | 2018年11月25日 |
---|---|
0.1.0 | 2018年11月24日 |
#886 在 GUI 中
470KB
3.5K SLoC
FunGUI
一个将界面描述和样式/布局分离的 UI 布局系统。这个系统旨在用于游戏,目前被用于 UniverCity。
lib.rs
:
FunGUI 是一个将界面描述和样式/布局分离的 UI 布局系统。
在 FunGUI 中,有两个主要的系统起作用,其余都是围绕这两个系统构建的:节点和样式。
节点
节点用于描述用户界面,而不包含任何关于其外观的信息,只有结构。有两种类型的节点:元素和文本。
元素只是一个名称,可以是任何东西,没有特殊名称,因为一切都是由样式规则控制的。元素可以包含子节点。
文本如名称所示,仅仅是文本。与元素不同,文本不能有任何子节点。
任何节点都可以在其上设置属性。属性用于向节点提供配置,这在您多次使用相同的节点类型时非常有用。例如,可以在文本节点上使用 url
属性,允许样式规则将其着色或使其可点击。
示例
节点格式的示例
alert(level="warning") {
title {
"This is an alert"
}
content {
"If you would like more info click "
"here"(url="http://....")
"."
}
buttons {
button(focused=true) {
"Accept"
}
button {
"Ignore"
}
}
}
样式
样式用于定义节点的行为。这可能包括节点如何渲染或如何响应用件。
样式通过匹配规则应用,以找到它们将应用于哪些节点。规则可以指定节点的层次结构以及节点应具有哪些属性及其值。这使得例如,一个 title
在 alert
内的行为可以与一个 title
在 window
内的行为不同。
一旦找到匹配项,样式规则就会应用于节点。规则可以是简单的常量值或表达式。表达式执行基本的数学(+-/*%
)和布尔运算(|| && <=
等),引用已匹配的属性并执行函数。函数可用于复杂属性,而不是在多个规则中分割它们。
变量和类型
变量是有类型的,浮点数和整数被视为不同的类型,不会自动进行类型转换,这包括样式规则中的常量。对于定义为 5
的常量将是一个整数,而 5.0
将是一个浮点数。对于变量,你可以使用 int(val)
或 float(val)
进行类型转换。
特殊变量
存在两个特殊变量,可以在不将它们用于匹配规则的情况下使用:parent_width
和 parent_height
。这些变量允许你相对于父元素的大小来设置元素的大小,而无需自定义布局来处理。虽然这些变量在某些情况下很有用,但它们也带来了一定的代价。为了处理这个问题,接口可能需要多次重新运行布局系统来解析变量,这会导致速度变慢,但这种情况下通常只会发生在节点布局计算的第一次。
示例
样式格式的示例
alert {
center = true,
layout = "rows",
width = 500,
height = 400,
}
alert(level="warning") {
background_color = rgb(255, 255, 0),
}
alert > title {
layout = "lined",
width = parent_width,
}
alert > title > @text {
font_color = rgb(0, 0, 0),
font_size = 24,
}
alert > content {
layout = "lined",
width = parent_width,
}
alert > content > @text {
font_color = rgb(0, 0, 0),
font_size = 16,
}
alert > content > @text(url=url) {
font_color = rgb(0, 120, 0),
on_mouse_up = action("visit", url),
}
布局
布局使用一些样式规则来定位和调整节点的大小。这些布局可以通过 add_layout_engine
添加,并通过 layout
样式属性进行选择。
扩展
Extension
特性和 RenderVisitor
特性是用户界面实际执行操作的主要方式。仅凭 FunGUI 只做布局,扩展特性可以通过在样式规则中使用自己的属性来添加事件和渲染。在 UniverCity 中,这些属性包括用于渲染的 image
和 background_color
,以及用于事件的 on_mouse_down
,其中事件是直接在样式内定义的 Lua 代码。
button {
border_width = border_width(15.0),
border = border_image("ui/button", 15, 15, true),
shadow = shadow(2.0, 2.0, rgba(0, 0, 0, 0.3), 3.0, 0.0, "outset"),
layout = "center",
can_hover = true,
}
button(theme="blueprint") {
border_width = border_width(15.0),
border = border_image("ui/button", 15, 15, true),
tint = rgba(0, 255, 255, 0.4),
}
button(on_click=click) {
on_mouse_up = list(click, "init#
audio.play_sound('click')
return true
"),
}
依赖项
~1.5MB
~25K SLoC