2 个版本

使用旧的 Rust 2015

0.1.1 2018年11月25日
0.1.0 2018年11月24日

#886GUI

MIT/Apache

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"
        }
    }
}

样式

样式用于定义节点的行为。这可能包括节点如何渲染或如何响应用件。

样式通过匹配规则应用,以找到它们将应用于哪些节点。规则可以指定节点的层次结构以及节点应具有哪些属性及其值。这使得例如,一个 titlealert 内的行为可以与一个 titlewindow 内的行为不同。

一旦找到匹配项,样式规则就会应用于节点。规则可以是简单的常量值或表达式。表达式执行基本的数学(+-/*%)和布尔运算(|| && <= 等),引用已匹配的属性并执行函数。函数可用于复杂属性,而不是在多个规则中分割它们。

变量和类型

变量是有类型的,浮点数和整数被视为不同的类型,不会自动进行类型转换,这包括样式规则中的常量。对于定义为 5 的常量将是一个整数,而 5.0 将是一个浮点数。对于变量,你可以使用 int(val)float(val) 进行类型转换。

特殊变量

存在两个特殊变量,可以在不将它们用于匹配规则的情况下使用:parent_widthparent_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 中,这些属性包括用于渲染的 imagebackground_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