注解
本文档不是逐字翻译的 Conrod 文档,大多是意译,但内容大致完整。
文档内的链接直接跳转到官方的英文文档,除非我有新的翻译或找到他人的翻译。
英文原文:Conrod Guide
API 文档(英文):Piston Conrod
简介¶
Conrod 是一个使用 Rust 语言编写的便携式 2D GUI 库。
它提供了一组立即模式(immediate mode)的应用程序编程接口(API), 包装了保留模式(retained mode)的小部件状态图。这允许我们在性能接近传统的保留式 GUI 框架的同时,暴露一组简单、健壮和响应式的接口。
Conrod 提供了一组原始的和常用的小部件(widgets,下简称“挂件”),以及可以自定义拥有单独逻辑的、能和其他挂件组合的成新挂件的 Widget API。
挂件在更新循环中通过 Builder 模式 实例化,也称为“方法链(Method Chaining)”模式,很灵活。
功能概览¶
- 响应式(reactive)和立即式的 API。使用存储在单一地方的状态集绘制 UI,而不是到处回调。
- 使用挂件特性(Widget trait)简化挂件的设计和组合。
- 可选的滚动(Scrolling),简单好用。在一个挂件上调用 .scroll_kids(true) 它就会变成可滚动的容器。
- 厉害的布局和定位:
- Placement - .middle(), .top_left_of(CANVAS), .mid_right_with_margin(20.0)
- Alignment - .align_left(), .``align_top_of(LABEL)``
- Relative - .down(20.0), .right_from(BUTTON, 40.0), .x_y_relative(20.0, 42.0)
- Absolute - .x_y(6.0, 7.0)
- Draggable pop-up / floating canvasses - .floating(true)
- WidgetMatrix and PositionMatrix for instantiating a grid of widgets.
- 可设置默认的风格(Themes)。
- widget_ids! 宏可以方便和安全地生成挂件 ID。
- 通用的图形和事件后端:
- glutin, sdl2 and glfw Window backends。
- gfx, glium and raw opengl Graphics backends。
- 提供一组常用的挂件。
可用挂件¶
包含原始的(primitive)和常用的(common use)。
原始挂件¶
最基本的图形挂件接口,用于组成其他挂件。比如按钮是用矩形和文本挂件组合而成。
在渲染的时候,Conrod 只渲染原始挂件,这使得挂件的设计者可以通过组合这些基本的原始挂件来创建自己的挂件,而不用通过自己编写底层代码绘制图形。这还简化了状态缓存,比如文本、定位、样式,它们都自动搞定。
原始部件包括:
- Line
- PointPath
- Shapes:
- Circle
- Rectangle
- Oval
- Polygon
- Text - automatic line-wrapping, line spacing, etc.
- Image
如果需要其他原始挂件,可以向官方提出。当前有计划允许用户自己设计原始挂件,但这个在有需求前优先级可能比较低。
常用挂件¶
这些挂件完全可以由用户自己实现,只是很常用所以直接包含在 Conrod 里了。
- BorderedRectangle
- Button
- Canvas - a container-like widget
- DropDownList
- EnvelopeEditor
- Matrix
- NumberDialer
- PlotPath
- Scrollbar - emits scroll events to some target scroll widget
- Slider
- Tabs - for easily switching between multiple Canvasses with ease
- TextBox - an editable one-line text field
- TextEdit - an editable block of text
- TitleBar
- Toggle
- XYPad
下面这些是有计划实现,但尚未完成的:
- Menu Bar / Tool Bar
- Right-click Context Menu
- Graph / Chart
- File/Directory Navigator
- Advanced graph visualisation and control
如果你有补充,到 Conrod at Github 上提 issue 或 pull request,通过“widget”的 label 搜索相关信息。
立即模式¶
什么是立即模式¶
立即模式描述了一种用户接口风格。
在立即模式里,挂件通过一个更新或绘制循环来实例化。而传统的“保留模式”是在创建阶段(setup stage)构建挂件。
立即模式鼓励无状态、数据驱动,应用程序每一帧或更新都实例化用户界面。而保留模式通过在用户交互时发送事件或触发回调函数来驱动应用程序。
为什么使用立即模式¶
立即模式适合用于程序界面和状态数据频繁同步的场景下。这是因为立即模式使用同一套状态数据集来实例化、更新、绘制。相比传统的保留模式区分实例化、更新、绘制、事件处理,立即模式尽量在同一个地方合并所有的 UI 相关逻辑。用起来很方便。
保留模式虽然用起来麻烦,不过在不需要频繁变化界面的程序中,占用的 CPU 资源更少。
Conrod 是立即模式的还是保留模式的¶
用起来 Conrod 像是立即模式的,但其实它在内部像保留模式一样,缓存了状态,这样用起来方便,性能也好,两全其美。
注解
应该跟 Facebook 的 React 差不多的原理,类似 Visual DOM。
Builder 模式¶
实例化一个挂件,传统的方式可能是使用:
这种形式,如果参数很多,且包含可选参数的情况下,就很麻烦。其他语言可以用关键词参数的方式来省略一些默认参数:
Rust 不支持关键词参数,但可以用链式调用来配置可选的参数,像这样:
大体上就是这么用,有几点需要注意的:
- 为每个参数实施一个方法。
- Button::new() 返回一个可选参数集合的数据类型,这个类型的数据可以从一个 builder 方法传递给另一个 builder 方法。
- 在这个 building 链中,必须有一个结尾 builder 方法来实例化这个挂件。
我们尽可能简化开发人员的工作:
- 我们提供一个 builder_methods! 宏来简化 builder 方法的编写。
- 挂件只作为一个状态参数集,而不是它们包含自己的状态。这样挂件状态就是隐式的,存储在 Ui 里。
- 所有的 Conrod 挂件必须有一个唯一的标识符(button_id)和连向 Ui 的可变引用(ui),我们合成一个单一的 .set(id: Id, ui_cell: &'a mut UiCell<'b>) 用作表明停止 building 并实例化挂件的方法。
更详细的说明在手册的“挂件实施”部分。(译注:目录里跟 widget 有关的是第三节和第五节,翻译这篇的时候官方手册只写了前两节。)