crui_lvgl 一个LVGL的DSL辅助工具的设想
设想
Target以LVGL为目标,语法以CSS为Reference。
CSS 规范
略
CSS规范最强大的属于CSS自身的属性很多,可以通过class和伪属性选择器对UI进行直接控制。
QML规范
ApplicationWindow {
visible: true
width: Constants.width
height: Constants.height
title: qsTr("Coffee")
ApplicationFlowForm {
id: applicationFlow
state: "initial"
property int animationDuration: 400
choosingCoffee.brewButtonSelection.onClicked: {
applicationFlow.state = "settings"
}
}
Image {
id: root
source: "images/icons/coffees/cappucino.png"
signal clicked
property int duration: 250
property alias text: label.text
MouseArea {
anchors.fill: parent
onClicked: root.clicked()
onPressed: {
glow.visible = true
animation1.start()
animation2.start()
}
}
Rectangle {
id: glow
visible: false
width: 250
height: 250
color: "#00000000"
radius: 125
scale: 1.05
border.color: "#ffffff"
}
Label {
id: label
x: 292
y: 252
text: qsTr("Label")
anchors.horizontalCenter: parent.horizontalCenter
color: "#443224"
font.family: Constants.fontFamily
font.pixelSize: 28
}
}
}
Slint Demo
Slint本身来源于QML, flutter 等项目,吸收优化得到的Design。
import { Button } from "std-widgets.slint";
export component MainWindow inherits Window {
height: 720px;
width: 1200px;
title: "Button!";
Button {
height: 66px;
width: 310px;
icon: @image-url("../../imgs/rust.png");
text: "I am a Button";
clicked => {
self.text = "Clicked!";
self.width = 360px;
}
}
GridLayout {
spacing: 10px;
padding: 4px;
//使用Row进行行声明
Row{
Rectangle { background: red; }
Rectangle { background: yellow;}
Rectangle { background: pink; }
}
Row{
Rectangle { background: white; colspan: 2; }
Rectangle { background: green; colspan: 1; col: 2;}
}
Rectangle { background: violet; colspan: 3;row:3;}
Rectangle { background: orange; colspan: 3;row:2;}
}
}
QML和Slint是将CSS的属性选择等能力,作为Object的属性存在,单独设定。虽然一定程度上解决了UI复用问题,但是不灵活。
QML胜在周边成熟,与Qt Object高度绑定,代码融合比较简单。Slint反而优点不伦不类,没有生态支撑,但是IDE配套做的不错,比LVGL好太多。
LVGL规范
- Demos https://docs.lvgl.io/master/examples.html
- Object基础属性 https://docs.lvgl.io/master/widgets/obj.html#overview
- Theme和定制 https://docs.lvgl.io/master/overview/style.html#themes
# demo1, label
screen
*color
label
*text
*color
# demo2, button
screen
button
*pos
*size
*event # <== 这里进行事件绑定
label
*text
*align
# demo3, flex
screen
object1
*size
*align
*flex
button*N
*size
label
*text
*algin
object2
*size
*align
*flex
button*N
*size
label
*text
*algin
# demo4, grid
screen
object
*grid
*size
*algin
*layout_grid
button*N
label
*text
*align
# style, == class
style
*radius
*bg_opa
*bg_color
*border_width
*border_color
# ...
screen
object
*style
image
*algin
# theme
default_theme
theme2
style
screen
button
*align
label
*text
button(theme2) # change theme
*align
label
*text
总结:
- Screen为root, 但是可以有多个,每次选一个作为default。
- 每个Screen有2个Layer层,但是用户一般只用top layer。(一般coding时,不用在乎这个问题)
- Layer(screen)内部可以自由组合 Object/Widgets, 每个Object/Widget 可以自由设定Layout为Grid/Flex/Absolute(默认)
- 每个Object/Widget都有默认的style(来源于默认的theme),可以自己custom style给object/widget使用。
- Theme是各种style的集合,也可以继承或者自己custom.
- 字体和图片需要转换后才能使用。中文支持需要添加中文字体。屏幕键盘默认不支持中文。
与QML/Slint比,没有DSL部分,全是C/C++ Code生成,也没有Nodejs/Go/Rust等binding部分(部分有,但不成熟)。有theme和style部分,很接近CSS的味道,但是没有DSL的加持,写起来很痛苦。
一句话:LVGL是个灵活的胖子!
想法
Idea Target
鉴于Slint和QML的授权协议,在嵌入式设备上收费,还有Rust/Qt的依赖问题,如果能有一个DSL和对应的C code tool, LVGL应该回是一个不错的选择。
所以,向借鉴Slint的VS Code插件,能不能仿照Vue、React一类的用法,将CSS和template一起渲染为C Code, 并绑定event,还支持UI的preview in design?
如果能做这样一个插件,并且提供LVGL工具库,支持UI动态Load, 这将会是一个非常不错的主意,并且对Coding有很大的帮助。
如果这个工具支持的DSL语法类似QML更好,不支持也尽量类似。
以上,于2023年11月28日。
Design
- [v] Kotlin DSL有类似的感觉
- 自己做解析,难以支持语法检查和扩展
- [?] 不知道QML的那种解析怎么实现的
- [v] template 模拟vue/json那种
参考:Groovy => Gradle
使用:Kotlin native + kts + ffi(DSL+LVGL)
- 先实现PC平台的调用
- 然后做一个
xxx.lvgl
的实时预览和代码生成 - 然后做一个开源库,LVGL辅助库函数
deadline: 2024/06/28, name: crui_lvgl