页次: 1
AWTK 在全志 tina linux 上支持 2D 图形加速: https://gitee.com/zlgopen/awtk-tina-g2d
之前有些朋友在全志 TinaLinux 上运行AWTK,遇到一些问题,主要是输入设备的问题,虽然不是什么大问题,如果不太熟悉 AWTK,解决起来还是比较费劲的。最近买了一个板子,把整个流程跑了一下,把遇到的坑填了(需更新最新代码),这里做个笔记,希望对大家有些帮助。
啥时候设计器能生成awtk的html5页面啊,一套界面屏和web同时用
可以生成 web app :https://gitee.com/zlgopen/awtk-web
在WEB上, 基于浏览器做设计?
不是。在 AWTK 应用程序中,有时可以用来显示地图和在线文档之类的网页。
已更新,谢谢。
webview 提供了一个跨平台的 webview 接口(是一个非常优秀的开源项目,在此对原作者表示感谢),
awtk-widget-web-view 是基于 webview 实现的浏览器控件。
@xfdr0805
AWSTUDIO 一直是免费的,只要信息完整,可以一直续下去。
* 优化编译脚本,加快编译速度。
* 优化代码生成,大幅减小wasm文件体积。
* 增加模拟器外壳。
我想用这个,但是许可把我挡在了门外,还是用LVGL吧
我当时选择 LGPL 的目的是希望修改了 AWTK 本身,能够把修改的部分开源,大家一起来完善 AWTK。其实不管使用动态库、静态库或者源码编译,应用程序都无需开源,ZLG 绝不会要求你开源,如果那样做,无疑会得罪所有 AWTK 使用者,所以我相信公司不会那样做。
如果贵公司非要严格遵循 LGPL 条款,可以和 ZLG 签免费商用协议,但是在 AWTK 宣传文章中,有权引用贵司的名称。
LVGL 有它的优势,想用 LVGL,我也不劝你用 AWTK。
HarmonyOS NEXT 是华为公司自研操作系统,2023 年 8 月 4 日发布,该系统是鸿蒙抛弃 Linux 内核及安卓开放源代码项目(AOSP)等代码的首个大版本,该系统仅支持鸿蒙内核和鸿蒙系统的应用,不再兼容安卓应用。10 月 22 日,华为原生鸿蒙 HarmonyOS NEXT 正式发布。
HarmonyOS 是全球第三大移动操作系统,有巨大的市场潜力,除了在手机、平板、电视、汽车广泛使用,可能也会给传统嵌入式行业注入新的活力。在国产替代的背景下,机会多多,将 AWTK 移植到 HarmonyOS 上,可以让 AWTK 开发者也能享受到 HarmonyOS 生态的红利。
举个例子吧,假设要做一个天气预报的功能:
AWTK: 从网络上下载数据,解析JSON数据,设置到界面上。界面很容易和逻辑耦合,看个人水平。
AWTK-MVVM: 将“从网络上下载数据,解析JSON数据”放到模型中,通过绑定规则关联到界面,工作量并没有减少,好处是分离界面和逻辑,逻辑可以编写单元测试,界面可以独立变化。
AWTK-HMI:内置常见模型,很多情况无需编写代码,这里只需要在界面上指定URL和数据绑定规则即可。
不错,辛苦啦。linux下可以用mmap加载大的资源,速度会快一些。
谢谢支持,前段时间还有人在问,如何在全智的芯片跑 AWTK 呢
主要特色:
开放源码,免费商用,从底层到应用程序全程可控。
强大的界面设计器 AWStudio。
基于 AWTK 实现强大的 GUI 功能(多窗口、输入法、动画和各种控件)。
基于 AWTK-MVVM 实现低代码开发(编写绑定规则即可实现常见应用程序)。
支持在 PC 上模拟运行,并提供 MCU 模拟器模拟与串口屏的交互。
支持 串口/TCP通讯。
MCU 端提供简单易用的 API,无需了解通信协议,无需记忆变量地址
界面修改数据,自动通知 MCU。
MCU 修改数据,自动更新界面。
要用C开发android的APP,当然是选AWTK啦:),常见的插件都有,自定义插件也很简单:
https://github.com/zlgopen/awtk-android
https://github.com/zlgopen/awtk-mobile-plugins
这个板子有移植AWTK吗,有个朋友想用它跑AWTK。
没见过。在PC上可以重现不,要不你做一个最小的demo放上吧(放到gitee上也可以)。
把button的enable_long_press属性设置为true即可。另外,遇到问题建议先看看一下文档和demoui中的例子。
AWTK Go 语言绑定来了,欢迎使用:https://github.com/zlgopen/awtk-go
import (
"fmt"
"github.com/zlgopen/awtk-go/awtk"
)
func onCancel(ctx interface{}, e awtk.TEvent) awtk.TRet {
fmt.Println("Cancel is clicked")
return awtk.RET_OK
}
func appInit() {
win := awtk.TWindowCreateDefault()
ok := awtk.TButtonCreate(win, 10, 10, 80, 30)
ok.SetPropStr(awtk.WIDGET_PROP_TEXT, "OK")
ok.SetSelfLayout("default(x=c,y=m,w=80,h=40)")
ok.On(awtk.EVT_CLICK, func(ctx interface{}, e awtk.TEvent) awtk.TRet {
fmt.Println("OK is clicked")
return awtk.RET_OK
}, win)
cancel := awtk.TButtonCreate(win, 10, 10, 80, 30)
cancel.SetPropStr(awtk.WIDGET_PROP_TEXT, "Cancel")
cancel.SetSelfLayout("default(x=c,y=m:-60,w=80,h=40)")
cancel.On(awtk.EVT_CLICK, onCancel, win)
quit := awtk.TButtonCreate(win, 10, 10, 80, 30)
quit.SetPropStr(awtk.WIDGET_PROP_TEXT, "Quit")
quit.SetSelfLayout("default(x=c,y=m:60,w=80,h=40)")
quit.SetPropStr("on:click", "quit()")
}
func main() {
awtk.Init(320, 480, awtk.APP_DESKTOP, "demo", "res")
awtk.InitAssets()
appInit()
awtk.Run()
}
图片格式和LCD格式一样,理论上存粹内存拷贝。你用调试器进去看看,另外测试一下memcpy的速度。
lcd 什么格式?
AWTK是免费开源的。awtk designer基本功能(目前所有功能)也是免费的,但是需要注册才能使用。不排除以后一些高级功能只对客户开放,只要免费开放过的功能,应该就不会收费。
参考一下awtk-hello: https://github.com/zlgopen/awtk-hello
widget_get_text取出来的是wchar_t*,强制转换为(char*),只能取得第一个字符,你需要再转换成UTF-8。或者直接调用下面这个函数:
/**
* @method widget_get_text_utf8
* 获取控件的文本。
* 只是对widget\_get\_prop的包装,文本的意义由子类控件决定。
* @param {widget_t*} widget 控件对象。
* @param {char*} text 用于返回文本。
* @param {uint32_t} size text内存长度。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
ret_t widget_get_text_utf8(widget_t* widget, char* text, uint32_t size);
AWTK 全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。
AWTK 1.5 发布: https://www.oschina.net/news/118180/awtk-1-5-released
基本功能无需付费,请参考:https://github.com/zlgopen/awtk/blob/master/docs/how_to_renewal_awtk_designer.md
可以。用函数window_open_and_close打开新窗口,同时关闭指定窗口(当前窗口)。
AWTK 的 ListView 是一个非常强大的控件,在列表项目中可以放比如文本、图片、编辑器、进度条、滑块和下拉框等各种控件。
但是 ListView 最大的问题是,每个列表项都必须事先创建好,这就导致 ListView 显示大量数据时,存在下列问题:
1.加载速度慢。
3.比较耗内存。
所以 ListView 在 PC 可以用于显示少于 10K 的数据,而在嵌入式平台上,只能用于显示少于 500 条记录的数据。
TableView 控件就是为了解决 ListView 控件的不足,具有如下特点:
1.列表项无需事先创建。
2.数据无需全部加载到内存。
3.轻松支持数千万条数据记录。
4.表格中可以放文本、图片、编辑器、进度条、滑块和下拉框等各种控件。
目前使用 32 位数据表示虚拟高度,最大记录数限制为 5000 万条记录。
厉害了,T9确实不容易搞。
AWTK 也支持中文输入法(Google 拼音和T9输入法)了,而且T9输入法支持词组输入和联想字输入。欢迎使用:https://github.com/zlgopen/awtk/blob/master/src/input_engines/README.md
用AWTK吧,在AWTK里,加个自定义的软键盘非常简单,用designers生成一个XML文件放进去就好了,一行代码不用写。内置支持Google Pinyin和T9(包括软键盘和实体键盘)中文输入法。https://github.com/zlgopen/awtk
AWTK Designer 0.1.5正式发布: https://mp.weixin.qq.com/s/Lx9AhDgHxcc59vzjvfkwmg
# 输入事件记录与重放
## 1. 用途
输入事件记录与重放的常见用途有:
* 自动演示功能。
* 长时间运行进行压力测试。
* 辅助手工测试。有时出现崩溃的 BUG 时,往往忘记之前是如何操作的了,输入事件记录与重放可以精确重现问题。同时也可以减轻手工测试的工作量。
## 2.API
/**
* @method event_recorder_player_start_record
* 开始事件记录。
* @annotation ["static"]
* @param {const char*} filename 用于保存事件的文件名。
*
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
*/
ret_t event_recorder_player_start_record(const char* filename);
/**
* @method event_recorder_player_start_play
* 开始事件重放。
* @annotation ["static"]
* @param {const char*} filename 存放事件的文件名。
* @param {uint32_t} times 循环播放的次数。
*
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
*/
ret_t event_recorder_player_start_play(const char* filename, uint32_t times);
/**
* @method event_recorder_player_stop_record
* 停止事件记录。
* @annotation ["static"]
*
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
*/
ret_t event_recorder_player_stop_record(void);
/**
* @method event_recorder_player_stop_play
* 停止事件重放。
* @annotation ["static"]
*
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
*/
ret_t event_recorder_player_stop_play(void);
## 3. 用法
一般有两种方式启用输入事件记录与重放:
* 通过命令行参数启动记录或重放功能(目前没有提供示例)。
* 通过快捷键启动记录和重放功能。这种方法更为灵活,可以随时启用和停止,可以随时记录和播放。
要定义宏 WITH_EVENT_RECORDER_PLAYER 才能启用事件记录与重放功能,PC 版本缺省是定义了该宏的。
demoui 中演示了通过快捷键启动记录和重放功能:
#include "base/event_recorder_player.h"
...
static ret_t on_key_record_play_events(void* ctx, event_t* e) {
key_event_t* evt = (key_event_t*)e;
#ifdef WITH_EVENT_RECORDER_PLAYER
if (evt->key == TK_KEY_F5) {
event_recorder_player_start_record("event_log.bin");
return RET_STOP;
} else if (evt->key == TK_KEY_F6) {
event_recorder_player_stop_record();
return RET_STOP;
} else if (evt->key == TK_KEY_F7) {
event_recorder_player_start_play("event_log.bin", 0xffff);
return RET_STOP;
} else if (evt->key == TK_KEY_F8) {
event_recorder_player_stop_play();
return RET_STOP;
}
#endif /*WITH_EVENT_RECORDER_PLAYER*/
return RET_OK;
}
...
widget_on(wm, EVT_KEY_UP, on_key_record_play_events, wm);
在以上代码中:
* F5 键开始记录。
* F6 键停止记录。
* F7 键开始播放。
* F8 键停止播放。
## 4.已知问题
* 如果想重复播放记录的事件,确保记录事件时,回到初始界面后才停止记录。
* 目前平台原生输入法的输入事件没有记录。
我preview下面的xml时,第二个label是可以显示的。我猜是你的style有问题:
<window name="main" x="0" y="0" w="320" h="480" style="Green_bg">
<label name="" x="10" y="40" w="80" h="30" text="Left" opacity="0"/>
<label name="" x="10" y="80" w="80" h="30" text="Right" />
</window>
好的
MEM2_MAX_SIZE 这个要8M那么多? 请问最小需要多少? 怎么计算?
最低RAM需求64K,低端平台移植请参考: https://github.com/zlgopen/awtk-lpc1768-raw/blob/master/docs/lpc1768_port.md
内存需求评估请参考: https://github.com/zlgopen/awtk/blob/master/docs/hardware_req.md
除了实现基本功能的移植外,还提供了如下功能:
1.集成实时操作系统 (RTOS)(腾讯的 TinyOS)
2.集成 FATFS 文件系统,访问 SD 卡的数据。
3.实现从文件系统加载应用程序的资源。
4.使用 Sqlite 存储数据。
5.支持 google 拼音输入法。
https://github.com/zlgopen/awtk-stm32h743iitx-tencentos/blob/master/docs/stm32h743iitx_port.md
> 因此不能打包和裁剪字体文件到awtk的应用中
designer应该可以放完整字体吧。如果真的不行,打包之后,用完整字体覆盖default.ttf也应该可以。
请参考这个文档:https://github.com/zlgopen/awtk-stm32h743iitx-tencentos/blob/master/docs/stm32h743iitx_port.md
本项目除了实现基本功能的移植外,还提供了如下功能:
1.集成实时操作系统 (RTOS)(腾讯的 TinyOS)
2.集成 FATFS 文件系统,访问 SD 卡的数据。
3.实现从文件系统加载应用程序的资源。
4.使用 Sqlite 存储数据。
5.支持 google 拼音输入法。
我做有H750的板子,需要的话可以送你一块测试AWTK
不用了,谢谢你。我有正点的429/767的板子,应该差不多。
LGPL理论上不能静态链接吧?那单片机上基本不能商用了,除非上Linux,以动态链接库的方式链接。
其实不管怎么用,我们都不会追究法律责任,我们不靠这个赚钱。
如果移植到新的平台,我们希望能把移植部分的代码,放到github供其他朋友参考。当然你不开源,我们也不知道,知道了也不会追究法律责任。
对于大公司,如果希望完全合规,特别是要出口的企业,可以加入AWTK合作生态,签一个免费商用许可就行了。免费商用许可的基本条件是允许ZLG在宣传AWTK时,可以提到贵公司使用了AWTK。
百度云盘里最新是1.3 rc3,还没有1.4呢。
https://gitee.com/zlgopen/awtk 取1.4分支。
可以免费商用吗?
可以
如果资源配置信息比较大就可能需要跟代码分离储存(比如放SD卡、SPI 闪存等),已经出货的设备想单独升级固件就很容易会出兼容性问题。
升级固件的同时要求升级工程(UI描述数据),多数客户是不肯干的。
谢谢你的建议,你说的情况确实存在。此时可以只升级变化的部分,如果资源没有变,就不用升级资源文件,也可以只更新变化的资源。
资源文件的变化,原因也有多种,格式变化只是其中一种(而且很少发生),有时资源本身就是需要更新的,比如界面重新设计了,用户禁止升级资源貌似不太合理。
资源文件是只读的,所以不用考虑之前的格式,直接覆盖就行了。我倒不觉得会『焦头烂额』。
AWTK的UI 描述文件和主题文件,在开发时都是使用的XML格式,由XML文件生成二进制文件,供运行时使用。以后我们会根据客户的需求提供多种选择,比如直接加载XML文件。
STM32 的实例能不能基于官方的板子?
都是野火这类的高价板子,
相信大部分人都用的官方的板子,看了讨论组,很难移植到官方的板子上面,而且都是STACK不够这类很难debug的问题
ZLG 是 NXP 的代理商,不太方便去大力支持ST的芯片。STM32几个平台的移植,可以看作是我个人行为,板子都是我自己掏钱买的,主要是验证AWTK的可移植性,并给需要的朋友一个参考。个人精力有限,希望大家一起完善。
xynth刚出来的时候,很多人都看好它,我当时也仔细研究过,其实它真的很弱。不过它刚开始就结束了,一时兴趣而已,就像我以前写FTK一样,过了那个劲头就不想搞了。
“UI 描述文件和主题文件使用高效的二进制格式,解析在瞬间完成。”
随着版本迭代,直接使用二进制格式导致的版本兼容性问题会让你焦头烂额,维护成本大大增加。
是的,相信很多人都吃过这个苦头。但是要具体情况具体分析,如果在运行时需要修改并保存的,就会存在你说的情况,因为新的代码需要兼容老版本的数据。
在 AWTK 中,这些资源都是只读的,资源数据每次都随代码同步更新,就不会有问题。
ZLG AWTK 1.4 Release Notes
一、介绍
AWTK 全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。
欢迎广大开发者一起参与开发:[生态共建计划](docs/awtk_ecology.md)。
AWTK 寓意有两个方面:
Toolkit AnyWhere。
ZLG 物联网操作系统 AWorksOS 内置 GUI。
AWTK 源码仓库:
稳定版整合包:https://pan.baidu.com/s/1_oRgj67M-I4kivk-YzwFWA 提取码:1cmi
AWTK Designer 界面设计工具:
不再需要手写 XML
拖拽方式设计界面,所见即所得
快速预览,一键打包资源
注册及下载地址:https://awtk.zlg.cn
二、最终目标:
支持开发嵌入式应用程序。✔
支持开发 Linux 应用程序。✔
支持开发 MacOS 应用程序。✔
支持开发 Windows 应用程序。✔
支持开发 Web APP。✔
支持开发 Android 应用程序。✔
支持开发 iOS 应用程序。✔
支持开发微信小程序。
支持开发支付宝小程序。
支持开发百度小程序。
支持开发 2D 小游戏。
三、主要特色
1. 跨平台
AWTK 是跨平台的,这有两个方面的意思:
AWTK 本身是跨平台的。目前支持的平台有 ZLG AWorksOS、Windows、Linux、MacOS、嵌入式 Linux、Android、iOS、Web 和嵌入式裸系统,可以轻松的移植到各种 RTOS 上。AWTK 以后也可以运行在各种小程序平台上运行。
AWTK 同时还提供了一套跨平台的基础工具库。其中包括链表、数组、字符串 (UTF8 和 widechar),事件发射器、值、对象、文件系统、互斥锁和线程、表达式和字符串解析等等,让你用 AWTK 开发的应用程序可以真正跨平台运行。
2. 高效
AWTK 通过一系列的手段保证 AWTK 应用程序高效运行:
通过脏矩算法只更新变化的部分。
支持 3 FrameBuffer 让界面以最高帧率运行 (可选)。
UI 描述文件和主题文件使用高效的二进制格式,解析在瞬间完成。
支持各种 GPU 加速接口。如 OpenGL、DirectX、Vulkan 和 Metal 等。
支持嵌入式平台的各种 2D 加速接口。目前 STM32 的 DMA2D 和 NXP 的 PXP 接口,厂家可以轻松扩展自己的加速接口。
3. 稳定
AWTK 通过下列方式极力让代码稳定可靠:
使用 cppcheck 和 facebook infer 进行静态检查。
使用 valgrind 进行动态内存检查。
近两万行的单元测试代码。
ZLG 强大 GUI 团队的支持。
经过多个实际项目验证。
多平台 / 多编译器验证。
优秀的架构设计。
Code Review。
手工测试。
4. 强大
丰富的控件 (持续增加中)。
支持各种图片格式 (png/jpg/gif/svg)。
支持各种字体格式 (点阵和矢量)。
支持窗口动画
支持控件动画
支持高清屏。
支持界面描述文件。
支持主题描述文件。
主题切换实时生效。
支持控件布局策略。
支持对话框高亮策略。
丰富的辅助工具。
支持从低端的 Cortex M3 到各种高端 CPU。
支持无文件系统和自定义的文件系统。
支持裸系统和 RTOS。
5. 易用
大量的示例代码。
完善的 API 文档和使用文档。
ZLG 强大的技术支持团队。
用 AWTK 本身开发的 界面编辑器。
声明式的界面描述语言。一行代码启用控件动画,启用窗口动画,显示图片 (png/jpg/svg/gif)。
6. 高度扩展性
可以扩展自己的控件。
可以扩展自己的动画。
可以实现自己的主循环。
可以扩展自己的软键盘。
可以扩展自己的图片加载器。
可以扩展自己的字体加载器。
可以扩展自己的输入法引擎。
可以扩展自己的控件布局算法。
可以扩展自己的对话框高亮策略。
可以实现自己的 LCD 接口。
可以扩展自己的矢量引擎 (如使用 skia/cairo)。
所有扩展组件和内置组件具有相同的待遇。
7. 多种开发语言
AWTK 本身是用 C 语言开发的,可以通过 IDL 生成各种脚本语言的绑定。生成的绑定代码不是简单的把 C 语言的 API 映射到脚本语言,而是生成脚本语言原生代码风格的 API。目前支持以下语言 (以后根据需要增加):
C
C++
lua
java
python
Javascript on jerryscript
Javascript on nodejs
Javascript on quickjs
8. 国际化
支持 Unicode。
支持输入法。
支持字符串翻译 (实时生效)。
支持图片翻译 (实时生效)。
文字双向排版 (计划中)。
9. 为嵌入式软件定制的 MVVM 框架,彻底分离用户界面和业务逻辑。
性能高。
内存开销小。
隔离更彻底。
可移植到其它 GUI。
代码小 (~5000 行)。
无需学习 AWTK 控件本身的 API。
支持多种编程语言(目前支持 C/JS)。
详情请参考:https://github.com/zlgopen/awtk-mvvm
10. 开放源码,免费商用 (LGPL)。
四、1.4 版本更新
1. 细节完善
完善 fs 接口。
完善工具支持多主题。
list view 支持上下键滚动。
完善窗口切换时焦点恢复的问题。
完善 combobox,选择之后重新打开输入法。
progress circle 支持 line cap 属性。
增加 vgcanvas_line_join_t 定义。
增加 vgcanvas_line_cap_t 定义。
修改 android resume 后界面黑屏的问题。
slide view/pages 每个页面支持独立的初始焦点。
增加函数 widget_set_child_text_utf8。
增加函数 widget_set_child_text_with_double。
keyboard 在 grab_keys 时,keyboard 处理 key 事件后,应用窗口不再处理。
完善 image value,支持点击时加上一个增量,增加到最大值后回到最小值。
3. 新增特性
无文件系统是支持多主题。
opengles 支持 snapshot。
dit/mledit 支持自己指定软键盘名称。
点击鼠标右键触发 context menu 事件。
使用 event_source_manager 实现主循环。
增加 awtk_main.inc,用于标准程序的主函数。
用 SDL 重新实现 PC 版本的线程和同步相关函数 。
edit 增加 input type "custom_password"类型。
4. 新增控件
5. 新增重要 API
增加 action thread。
增加 action thread pool。
增加动态链接库的接口 dl.h。
增加 waitable ring buffer。
增加 widget_close_window。
增加 waitable_action_queue。
增加 path_replace_extname 函数。
增加 async.c/.h 用于实现函数异步调用。
增加 path_replace_extname 函数。
增加 async.c/.h 用于实现函数异步调用。
增加 data reader 接口和 data writer,用于抽象外部 flash 等设备。
增加函数 fs_get_user_storage_path 用于统一 PC 和 android 平台保存数据的目录。
6. 新增平台
7. 新增语言绑定
8. 新增相关项目
欢迎广大开发者一起参与开发:[生态共建计划](../awtk_ecology.md)。
你可以试试这个例子:https://github.com/zlgopen/awtk-hello
这个例子是我写的,有任何问题,可以直接找我。
如果用的designer,最好在designer中修改,然后重新导出,导出的时候会自动更新资源。
# awtk-linux-fb 使用 double framebuffer 闪烁的问题
有朋友说 awtk-linux-fb 在某某平台闪烁很厉害,log 显示该平台使用的双帧缓冲。从代码和网上查的资料来看,目前的处理方法没有问题:无非就是通过 FBIOPUT\_VSCREENINFO 或 FBIOPAN\_DISPLAY 去修改 fb\_var\_screeninfo 的 yoffset。如:
vi.yoffset = i * fb_height(fb);
if (ioctl(fb->fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
百思不得其解,前几天找了一台 android 手机,把 zygote 进程停掉了,直接运行 AWTK 的程序,发现只要程序在刷新的时候,屏幕就有显示,停下来了屏幕就黑了。
所以怀疑不管 GUI 有没有变化,都必须不停的调用 FBIOPUT_VSCREENINFO 向显卡提交显示请求。
于是就开了一个独立的线程,来做这件事情:
static void* display_thread(void* ctx) {
uint32_t i = 0;
uint32_t index = 0;
fb_info_t* fb = &s_fb;
int fb_nr = fb_number(fb);
uint32_t size = fb_size(fb);
lcd_mem_t* lcd = (lcd_mem_t*)ctx;
struct fb_var_screeninfo vi = (fb->var);
log_info("display_thread start\n");
while (!s_app_quited) {
uint8_t* buff = fb->fbmem0 + size * i;
uint32_t start = time_now_ms();
vi.yoffset = i * fb_height(fb);
pthread_mutex_lock(&s_mutex);
memcpy(buff, lcd->offline_fb, size);
pthread_mutex_unlock(&s_mutex);
if (ioctl(fb->fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
index++;
i = index % fb_nr;
}
log_info("display_thread end\n");
return NULL;
在 android 设备上测试 2fb/3fb 的情况,显示均正常了。
以前一直认为:提交一次之后,显卡自动使用该数据显示,直到有新的数据提交为止。而实际情况是需要不停的提交,否则屏幕就黑了。
遇到闪烁的朋友,请用最新代码验证一下。
挺好,有配套的屏链接吗?我想买块测试AWTK。
在 awtk-port/fb_info.h 中,把FBIO_WAITFORVSYNC的执行结果打印出来看看:
static inline void fb_sync(fb_info_t* info) {
int ret = 0;
int zero = 0;
ret = ioctl(info->fd, FBIO_WAITFORVSYNC, &zero);
log_debug("FBIO_WAITFORVSYNC: %d %d\n", ret, zero);
return;
}
一、启用焦点停留 (tab stop)
除了 edit 控件外,其它控件如果需要焦点停留功能,可以指定控件的 focusable 属性为 true 来实现。
在 XML 中,可以这样指定:
<button ... focusable="true"/>
在 C 代码中,可以这样指定:
widget_set_prop_bool(widget, WIDGET_PROP_FOCUSABLE, TRUE);
如果指定了 fucusable 属性为 true,请确保控件的 style 中定义了 focused 状态的数据,否则会因为 focused 状态没有 style 数据而无法显示。如:
<style name="default" border_color="#a0a0a0" text_color="black">
<normal bg_color="#f0f0f0" />
<pressed bg_color="#c0c0c0" x_offset="1" y_offset="1"/>
<over bg_color="#e0e0e0" />
<focused bg_color="#e0e0e0" />
<disable bg_color="gray" text_color="#d0d0d0" />
</style> <focused bg_color="#e0e0e0" />
二、前后切换焦点的按键
1. 缺省用 tab 键循环切换焦点。
#ifndef TK_KEY_MOVE_FOCUS_NEXT
#define TK_KEY_MOVE_FOCUS_NEXT "tab"
#endif /*TK_KEY_MOVE_FOCUS_NEXT*/
2. 可以为当前窗口指定的向前和向后移动焦点的键值。
* move_focus_prev_key 指定向前移动焦点的键值。
* move_focus_next_key 指定向后移动焦点的键值。
<window anim_hint="htranslate" move_focus_prev_key="up" move_focus_next_key="down">
在这个例子中,方向键 up 移动到前一个焦点控件,方向键 down 移动到下一个焦点控件。
三、上下左右切换焦点的按键
在一些特殊的硬件设备上,没有触摸屏,只有上、下、左、右、确定和取消六个键。
为了快速切换焦点,AWTK 支持通过左右键切换水平焦点,通过上下键切换垂直焦点。可以通过窗口的下列属性来设置:
* move_focus_up_key 向上移动焦点的键。
* move_focus_down_key 向下移动焦点的键。
* move_focus_left_key 向左移动焦点的键。
* move_focus_right_key 向右移动焦点的键。
示例:
<window text="Custom Soft Keyboard" anim_hint="htranslate"
move_focus_up_key="up" move_focus_down_key="down" move_focus_left_key="left" move_focus_right_key="right">
<edit name="edit" x="c" y="10" w="90%" h="30" focused="true" input_type="custom" text="" tips="custom"/>
<view y="60" x="c" w="90%" h="-60" is_keyboard="true" grab_keys="true"
children_layout="default(r=4,c=4,m=5,s=5)" >
<button focusable="true" name="key0" text="0" />
<button focusable="true" name="key1" text="1" />
<button focusable="true" name="key2" text="2" />
<button focusable="true" name="key3" text="3" />
<button focusable="true" name="key4" text="4" />
<button focusable="true" name="key5" text="5" />
<button focusable="true" name="key6" text="6" />
<button focusable="true" name="key7" text="7" />
<button focusable="true" name="key8" text="8" />
<button focusable="true" name="key9" text="9" />
<button focusable="true" name="key#" text="#" />
<button focusable="true" name="backspace" text="<=" />
</view>
</window>
在这个例子中,方向键 up 移动到上方的焦点控件,方向键 down 移动到下方的焦点控件。
方向键 left 移动到左方的焦点控件,方向键 right 移动到右方的焦点控件。
软键盘本身不能得到焦点,为了收到按键消息,需要指定属性 grab_keys="true"。
四、设置初始焦点
可以指定控件的 focused 属性为 true 将控件设置为初始焦点控件。
在 XML 中,可以这样指定:
<button ... focused="true"/>
在 C 中,可以这样指定:
widget_set_prop_bool(widget, WIDGET_PROP_FOCUSED, TRUE);
五、参考
* 键名的定义:https://github.com/zlgopen/awtk/blob/master/src/base/enums.c。
* 键值映射:https://github.com/zlgopen/awtk/blob/master/docs/map_key.md
是的。
在 AWTK 中 如何让文本滚动起来
在很多时候,特别是在小屏幕的硬件上,控件比较小而要显示的文本比较长。
此时,我们需要在控件获得焦点时/或点击时,让文本滚动起来,以便让用户看到完整的信息。
AWTK 提供了 hscroll_label_t 控件,可以轻松满足文本滚动的需求。
一、基本用法
示例:
<window anim_hint="htranslate" text="hscroll_label" children_layout="default(c=1,h=30,xm=10,s=5)">
<hscroll_label text="炫酷的 GUI 引擎。" />
<hscroll_label text="炫酷的 GUI 引擎。" style="right"/>
<hscroll_label
lull="1000"
loop="true"
yoyo="true"
ellipses="true"
focusable="true"
text="(always ellipses loop yoyo) 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
<hscroll_label
focusable="true"
only_focus="true"
text="(only_focus noloop) 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
<hscroll_label
loop="true"
ellipses="true"
focusable="true"
only_focus="true"
text="(only_focus ellipses loop) 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
<hscroll_label
style="green"
loop="true"
yoyo="true"
ellipses="true"
focusable="true"
only_focus="true"
text="(only_focus ellipses loop yoyo) 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
</window>
二、扩展用法
但有时用的不是单纯的文本控件,而是列表项、多选按钮、单选按钮或其它功能的控件,那该怎么办呢?
其实也很简单,把 hscroll_label 作为该控件的子控件,并指定 only_parent_focus 属性为 true 即可。
示例:
<window anim_hint="htranslate" move_focus_prev_key="up" move_focus_next_key="down" text="Basic Controls">
<row x="0" y="180" w="-50" h="90" children_layout="default(r=1,c=2,m=2)">
<column children_layout="default(r=3,c=1,ym=2,s=10)" >
<check_button name="r1" focusable="true" >
<hscroll_label only_parent_focus="true" x="right" y="middle" w="-30" h="100%"
text="1.AWTK 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
</check_button>
<check_button name="r2" focusable="true">
<hscroll_label only_parent_focus="true" x="right" y="middle" w="-30" h="100%"
text="2.AWTK 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
</check_button>
<check_button name="r3" value="true" focusable="true">
<hscroll_label only_parent_focus="true" x="right" y="middle" w="-30" h="100%"
text="3.AWTK 为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。" />
</check_button>
</column>
</row>
</window>
AWTK 也支持 3 FB,3FB直接切换显存地址,可以避免画面撕裂。2FB应该可以通过中断同步(这个我不熟),感觉即使不同步,效果也还可以。
AWTK 中 LCD 接口的四种实现方式
LCD 是对显示设备的抽象,提供了基本的绘图函数。自己去实现 LCD 接口虽然不难,但是需要花费不少功夫,AWTK 提供了几种缺省的实现,利用这些缺省的实现,在移植到新的平台时,一般只需要很少的代码就行了。
下面我们介绍一下几种常见的 LCD 实现方式:
一、基于寄存器实现的 LCD
在低端的嵌入式平台上,内存只有几十 KB,没有足够的内存使用 framebuffer,通常直接向寄存器中写入坐标和颜色数据。lcd_reg.inc 提供了基于寄存器实现的 LCD,用它实现不同平台的 LCD 时,只需要提供两个宏即可:
set_window_func 设置要写入颜色数据的区域,相对于每次设置坐标而言,可以极大提高工作效率。
write_data_func 写入颜色数据。
下面是 STMF103ze 上 LCD 的实现,这里把 set_window_func 定义为 TFT_SetWindow,把 write_data_func 定义为 TFT_WriteData:
#include "tftlcd.h"
#include "tkc/mem.h"
#include "lcd/lcd_reg.h"
typedef uint16_t pixel_t;
#define LCD_FORMAT BITMAP_FMT_BGR565
#define pixel_from_rgb(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define pixel_to_rgba(p) \
{ (0xff & ((p >> 11) << 3)), (0xff & ((p >> 5) << 2)), (0xff & (p << 3)) }
#define set_window_func LCD_Set_Window
#define write_data_func LCD_WriteData_Color
#include "base/pixel.h"
#include "blend/pixel_ops.inc"
#include "lcd/lcd_reg.inc"
基于寄存器实现的实现有几个限制:
由于内存和 CPU 性能的问题,不提供任何类型的动画。
由于读取 LCD 当前内容速度很慢,所以需要与底色进行混合时,由 GUI 自己处理 (APP 无需关心)。
屏幕大时会出现闪烁。
在 AWTK 中,不再推荐此方法,基于片段帧缓冲实现的 LCD 是更好的选择。
二、基于片段帧缓冲实现的 LCD
在低端的嵌入式平台上,内存只有几十 KB,没有足够的内存创建一屏的帧缓冲,而使用基于寄存器的方式屏幕容易闪烁。
比较好的办法是,创建一小块帧缓冲,把屏幕分成很多小块,一次只绘制一小块。由于有脏矩形机制,除了打开新窗口时,在正常情况下,绘制速度仍然很快,可以有效的解决闪速问题。
lcd_mem_fragment.inc 提供了基于片段帧缓冲实现的 LCD,用它实现不同平台的 LCD 时,只需要提供两个宏即可:
set_window_func 设置要写入颜色数据的区域,相对于每次设置坐标而言,可以极大提高工作效率。
write_data_func 写入颜色数据。
下面是 STMF103ze 上 LCD 的实现,这里把 set_window_func 定义为 TFT_SetWindow,把 write_data_func 定义为 TFT_WriteData:
#include "tftlcd.h"
#include "tkc/mem.h"
#include "lcd/lcd_mem_fragment.h"
typedef uint16_t pixel_t;
#define LCD_FORMAT BITMAP_FMT_BGR565
#define pixel_from_rgb(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define pixel_to_rgba(p) \
{ (0xff & ((p >> 11) << 3)), (0xff & ((p >> 5) << 2)), (0xff & (p << 3)) }
#define set_window_func LCD_Set_Window
#define write_data_func LCD_WriteData_Color
#include "base/pixel.h"
#include "blend/pixel_ops.inc"
#include "lcd/lcd_mem_fragment.inc"
三、基于 framebuffer 实现的 LCD
这是在嵌入式平台上最常见的方式。一般有两个 framebuffer,一个称为 online framebuffer,一个称为 offline framebuffer。online framebuffer 是当前现实的内容,offline framebuffer 是 GUI 当前正在绘制的内容。lcd_mem_rgb565 提供了 rgb565 格式的 LCD 实现,lcd_mem_rgba8888 提供了 rgba8888 格式的 LCD 实现,它们都是在 lcd_mem.inc 基础上实现的,要增加新的格式也是很方便的。
下面是 STMF429 上 LCD 的实现:
extern u32 *ltdc_framebuf[2];
#define online_fb_addr (uint8_t*)ltdc_framebuf[0]
#define offline_fb_addr (uint8_t*)ltdc_framebuf[1]
lcd_t* platform_create_lcd(wh_t w, wh_t h) {
return lcd_mem_rgb565_create_double_fb(w, h, online_fb_addr, offline_fb_addr);
}
四、基于 vgcanvas 实现的 LCD
在支持 OpenGL 3D 硬件加速的平台上(如 PC 和手机),我们使用 nanovg 把 OpenGL 封装成 vgcanvas 的接口,在 vgcanvas 基础之上实现 LCD。lcd_vgcanvas.inc 将 vgcanvas 封装成 LCD 的接口,这里出于可移植性考虑,并没有直接基于 nanovg 的函数,而是基于 vgcanvas 的接口,所以在没有 GPU 时,如果 CPU 够强大,也是可以基于 agg/picasso 去实现的 LCD。
这种方式实现,一般不会在嵌入平台上使用,读者不需要关注它。
总结
以上几种实现方式,基本上涵盖了最常用的场景,所以在移植 AWTK 到新的平台时,并不需要在实现 LCD 接口上费多少功夫。
AWTK 在腾讯 TOS 上的移植笔记
本文以 STM32f103ze 为例,介绍了 AWTK 在 RTOS 上移植的经验。与其说移植,倒不如说是集成。因为 RTOS 通常没有提供标准的 LCD 驱动接口,显示部分并不需要特别的改动。所做的事情不过是把 AWTK 放到 RTOS 的一个线程中执行而已。
1. 加入 TOS 相关文件。
AWTK 已经移植到 STM32f103ze 裸系统上,为了简单起见,直接在 awtk-stm32f103ze-raw 基础上加入 TOS 支持。
在 Keil 中增加下列文件:
TencentOS/kernel/core/tos_event.c
TencentOS/kernel/core/tos_fifo.c
TencentOS/kernel/core/tos_global.c
TencentOS/kernel/core/tos_mmblk.c
TencentOS/kernel/core/tos_mmheap.c
TencentOS/kernel/core/tos_msg.c
TencentOS/kernel/core/tos_mutex.c
TencentOS/kernel/core/tos_pend.c
TencentOS/kernel/core/tos_queue.c
TencentOS/kernel/core/tos_robin.c
TencentOS/kernel/core/tos_sched.c
TencentOS/kernel/core/tos_sem.c
TencentOS/kernel/core/tos_sys.c
TencentOS/kernel/core/tos_task.c
TencentOS/kernel/core/tos_tick.c
TencentOS/kernel/core/tos_time.c
TencentOS/kernel/core/tos_timer.c
TencentOS/kernel/pm/tos_pm.c
TencentOS/kernel/pm/tos_tickless.c
TencentOS/arch/arm/arm-v7m/common/tos_cpu.c
TencentOS/arch/arm/arm-v7m/common/tos_fault.c
TencentOS/arch/arm/arm-v7m/cortex-m3/armcc/port_c.c
TencentOS/arch/arm/arm-v7m/cortex-m3/armcc/port_s.S
增加 include 的路径
TencentOS/arch/arm/arm-v7m/common/include
TencentOS/arch/arm/arm-v7m/cortex-m3/armcc
TencentOS/kernel/core/include
TencentOS/kernel/hal/include
TencentOS/kernel/pm/include
TencentOS/TOS-CONFIG
修改配置文件
根据自己的需要修改配置 TencentOS/TOS-CONFIG/tos_config.h:
一般来说不需要修改,使用官方提供的即可。我用的是 TencentOS-Demo 项目中的。
2. 加入针对 TOS 实现的线程和同步的函数。
src/platforms/tos/mutex.c
src/platforms/tos/semaphore.c
src/platforms/tos/thread.c
src/platforms/common/sys_tick.c
3. 实现 rtos.c
主要就是 SysTick 中断的实现,从 TencentOS-Demo 中拷贝过来就行了。
ret_t rtos_init(void) {
tos_knl_init();
tos_robin_config(TOS_ROBIN_STATE_ENABLED, (k_timeslice_t)500u);
return RET_OK;
}
ret_t rtos_start(void) {
tos_knl_start();
return RET_OK;
}
void rtos_tick(void) {
if (tos_knl_is_running()) {
tos_knl_irq_enter();
tos_tick_handler();
tos_knl_irq_leave();
}
}
void rtos_delay(uint32_t ms) {
tos_task_delay(ms);
}
4. 在线程中启动 AWTK
void* awtk_thread(void* args) {
gui_app_start(320, 480);
return NULL;
}
static ret_t awtk_start_ui_thread(void) {
tk_thread_t* ui_thread = tk_thread_create(awtk_thread, NULL);
return_value_if_fail(ui_thread != NULL, RET_BAD_PARAMS);
tk_thread_set_priority(ui_thread, 3);
tk_thread_set_name(ui_thread, "awtk");
tk_thread_set_stack_size(ui_thread, 2048);
return tk_thread_start(ui_thread);
}
int main() {
hardware_prepare();
platform_prepare();
rtos_init();
awtk_start_ui_thread();
rtos_start();
return 0;
}
这里与裸系统不同的地方,主要有两个:
在线程中启动 AWTK。
要提前调用 platform_prepare,platform_prepare 负责初始化内存,放在 tk_init 中就有些晚,需要单独提出来调用。
为此 platform_prepare 函数做了防重复调用的处理。
static bool_t s_inited = FALSE;
static uint32_t s_heam_mem[4096];
ret_t platform_prepare(void) {
if(!s_inited) {
s_inited = TRUE;
tk_mem_init(s_heam_mem, sizeof(s_heam_mem));
}
return RET_OK;
}
本文以 STM32f103ze 为例,介绍了 AWTK 在 RTOS 上移植的经验。与其说移植,倒不如说是集成。所做的事情不过是把 AWTK 放到 RTOS 的一个线程中执行而已。
1. 加入 RT-Thread 相关文件。
AWTK 已经移植到 STM32f103ze 裸系统上,为了简单起见,直接在 awtk-stm32f103ze-raw 基础上加入 RT-Thread 支持。
在 Keil 中增加下列文件:
rtthread/
rtthread/bsp
rtthread/cortex-m3
rtthread/cortex-m3/context_gcc.S
rtthread/cortex-m3/context_iar.S
rtthread/cortex-m3/context_rvds.S
rtthread/cortex-m3/cpuport.c
rtthread/cortex-m3/SConscript
rtthread/include
rtthread/include/libc
rtthread/include/libc/libc_dirent.h
rtthread/include/libc/libc_errno.h
rtthread/include/libc/libc_fcntl.h
rtthread/include/libc/libc_fdset.h
rtthread/include/libc/libc_ioctl.h
rtthread/include/libc/libc_signal.h
rtthread/include/libc/libc_stat.h
rtthread/include/rtdbg.h
rtthread/include/rtdebug.h
rtthread/include/rtdef.h
rtthread/include/rthw.h
rtthread/include/rtlibc.h
rtthread/include/rtm.h
rtthread/include/rtservice.h
rtthread/include/rtthread.h
rtthread/rtconfig.h
rtthread/src
rtthread/src/clock.c
rtthread/src/components.c
rtthread/src/cpu.c
rtthread/src/device.c
rtthread/src/idle.c
rtthread/src/ipc.c
rtthread/src/irq.c
rtthread/src/Kconfig
rtthread/src/kservice.c
rtthread/src/mem.c
rtthread/src/memheap.c
rtthread/src/mempool.c
rtthread/src/object.c
rtthread/src/scheduler.c
rtthread/src/SConscript
rtthread/src/signal.c
rtthread/src/slab.c
rtthread/src/thread.c
rtthread/src/timer.c
增加 include 的路径
rtthread
rtthread/include
修改配置文件
根据自己的需要修改配置 rtthread/rtconfig.h
一般来说不需要修改,使用官方提供的即可。我用的是 stm32f103-mini-system 项目中的。
2. 加入针对 RT-Thread 实现的线程和同步的函数。
src/platforms/rtt/mutex.c
src/platforms/rtt/semaphore.c
src/platforms/rtt/sys_tick.c
src/platforms/rtt/thread.c
主要就是 SysTick 中断的实现, 参考stm32/libraries/HAL_Drivers/drv_common.c修改的。
非 arm 平台 SysTick 函数的名称可能不一样,根据自己的需要调整。
static volatile uint64_t g_sys_tick;
void rtos_tick(void) {
if (rtos_is_inited()) {
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
}
void SysTick_Handler(void) {
g_sys_tick++;
rtos_tick();
}
3. 在线程中启动 AWTK
void* awtk_thread(void* args) {
gui_app_start(320, 480);
return NULL;
}
static ret_t awtk_start_ui_thread(void) {
tk_thread_t* ui_thread = tk_thread_create(awtk_thread, NULL);
return_value_if_fail(ui_thread != NULL, RET_BAD_PARAMS);
tk_thread_set_priority(ui_thread, 3);
tk_thread_set_name(ui_thread, "awtk");
tk_thread_set_stack_size(ui_thread, 2048);
return tk_thread_start(ui_thread);
}
static void hardware_prepare(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
systick_init();
led_init();
button_init();
TFT_Init();
TFT_ClearScreen(BLACK);
FLASH_Init();
TOUCH_Init();
TIM3_Init(50, 7199);
rtc_init();
}
int main() {
hardware_prepare();
platform_prepare();
rtos_init();
awtk_start_ui_thread();
rtos_start();
}
这里与裸系统不同的地方,主要有两个:
1) 在线程中启动 AWTK。
2) 要提前调用 platform_prepare,platform_prepare 负责初始化内存,放在 tk_init 中就有些晚,需要单独提出来调用。
为此 platform_prepare 函数做了防重复调用的处理。
static bool_t s_inited = FALSE;
static uint32_t s_heam_mem[4096];
ret_t platform_prepare(void) {
if(!s_inited) {
s_inited = TRUE;
tk_mem_init(s_heam_mem, sizeof(s_heam_mem));
}
return RET_OK;
}
AWTK 集成 RTOS 是非常简单的,以上过程大概花了 2 个小时吧。只要 RTOS 本身好移植,集成 AWTK 和 RTOS 只是分分钟的问题。
这里有个文档:https://github.com/zlgopen/awtk/blob/master/docs/how_to_support_mono_lcd.md
我知道的有3家公司在AWTK开发单色屏的产品,但是我自己没单色屏的硬件,所以只在PC上模拟测试过。
是吗?https://github.com/zlgopen/awtk/blob/master/src/base/widget.c 里有widget_off_by_tag函数,你确认本地文件有这个函数吗?
对了,AWTK更新之后,AWTK本身要编译一下。
AWTK也支持单色屏,虽然体积大点,不过可以让单色屏和彩色屏公用同一套代码。
AWTK + TOS 在STM32F103上的demo1大小:
```
Program Size: Code=183778 RO-data=229094 RW-data=1120 ZI-data=55056
```
有兴趣的朋友可以试试。
用最新的AWTK。
API 太丑了,用AWTK: https://github.com/zlgopen/awtk 吧:)
别的且不说,这个函数名看得太费劲了:
gui_widget_setxpositionpercent(h, 1);
gui_widget_setyposition(h, 10);
gui_widget_setsizepercent(h, 48, 8);
楼主大神, widget_set_text_utf8 (btn, "打开"); 显示不出来,
widget_set_text_utf8 (btn, "Open"); 能显示,这个可能是什么情况?可以了,结贴,xx为strings.xml中定义过的串就行了,
widget_set_tr_text(btn, "xx");
1. 用vscode把源文件转换程UTF8-BOM格式。
2. 确认字体中包含中文字库。
lixianjing 说:谢谢支持。我们会持续完善文档。
想问一下大神,串口收到的数据想显示到ATWK界面中,如何操作比较好呢?
能否直接修改win_main.c文件,但是这样感觉软件架构就乱了。。
有没有其他好的方法?
这个话题很有意思。有空可以玩玩AWTK-MVVM: https://github.com/zlgopen/awtk-mvvm
楼主,有个新问题请教, 想把中文字符传到strings.xml里面的%s, 要用什么办法呢?
locale设置的中文,但传中文字符串就不行了, 传strings.xml里面定义过的英文串也不行,还是显示的英文,若传中文串过去则不会显示出来
中文需要用UTF8编码。
谢谢支持。我们会持续完善文档。
辛苦了, 谢谢支持。
https://github.com/zlgopen/awtk-linux-fb 的README里有写啊,三者并列放到同一个目录。
arm-linux-gnueabi-strip build/bin/demoui
arm-linux-gnueabi-strip:build/bin/demoui: 不可识别的文件格式不可识别怎么解决
要用工具链配套的strip,如果你编译的PC版本,直接用strip即可。
STM32F103用keil编译的代码约170K。
Program Size: Code=173094 RO-data=228930 RW-data=1040 ZI-data=24808
strip是必备技能:
ls -l build/bin/demoui
-rwxr-xr-x 1 l 6870909 Nov 5 01:35 build/bin/demoui
arm-linux-strip build/bin/demoui
ls -l build/bin/demoui
-rwxr-xr-x 1 2063712 Nov 5 01:36 build/bin/demoui
好的,谢谢支持。
我测试没问题啊,你参考一下:https://github.com/zlgopen/awtk-c-demos/blob/master/demos/image_value.c
你设置控件的名称了吗?上面的代码没看到。设置名称之后才能用widget_lookup查找:
```
widget_set_name(image_value, "image_temper11");
```
image_value应该可以啊。遇到什么问题?
辛苦了,是我的疏忽。
新版本隐藏了text cursor,麻烦更新一下awtk-linux-fb
不好意思,麻烦更新一下AWTK和awtk-linux-fb。
前几天加了多主题实时切换功能,资源加了一级目录,release.sh忘记更新了。
不好意思,麻烦更新一下AWTK和awtk-linux-fb。
前几天加了多主题实时切换功能,资源加了一级目录,release.sh忘记更新了。
3. 现在最后一个问题: 如何隐藏界面的光标(cursor)呢?
谢谢大家支持,这个我还不知道,等我研究一下。
点击触摸屏是有log输出的
就是屏幕一片黑 啥也不显示晕哥 说:从 log 上面看, 没有相关的日志输出.
我在 S3 上面跑过, 一切正常。
还直接支持USB鼠标。
貌似资源文件没找到。是用release.sh生成的zip包吗?
lixianjing 说:ffplay 说:请教楼主,可以用scons命令转为 msvc 工程吗?
因为我还是不习惯命令行编程
scons没这个功能。scons + VSCode挺好用的,你可试试。
VSCode是导入一个文件夹编辑对吧?可以单步调试吗?
在AWTK目录,右键打开“Open With Code”。
在launch.json加入:
{
"name": "(Windows) demoui.exe",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/demoui.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false
},
我这里没问题啊。你用的最新代码吗?难道是 python2.7的问题?
@k455619
rf 说:商业使用收费吗?
看授权是LGPL,但是嵌入式环境都是静态编译居多,那么按理说就不能商业使用了,除非跑Linux然后动态加载
使用LGPL,我的本意是修改了AWTK本身,希望能分享出来。这样大家一起来完善AWTK,做出最好的GUI。
如果你不放心,可以联系我们,我们可以提供免费的商业授权。
请教楼主,可以用scons命令转为 msvc 工程吗?
因为我还是不习惯命令行编程
scons没这个功能。scons + VSCode挺好用的,你可试试。
我在全志V3s上,直接运行 demoui, 插入USB鼠标就能点击,这个确实很人性化,不需要任何设置。
但是问题来了,按下鼠标不能左右滑动,而电容触摸屏可以,请教楼主, 是我的操作姿势有问题,还是本来就不行呢?
Windows/Ubuntu 模拟器鼠标操作是可以的.
可能是移植层的问题,貌似没收到鼠标移动的事件,把它打印出来看看。
谢谢支持,有问题@我:)
谢谢晕哥支持!
AWTK 针对 quickjs 绑定完成: https://github.com/zlgopen/awtk-quickjs
AWTK 全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。
QuickJS是一个小型并且可嵌入的Javascript引擎,它支持ES2020规范,包括模块,异步生成器和代理器。
AWTK的问题尽管找我。
nanovg能不能用在没有GPU的设备上?
本来是不行的,我改造了一下,使用agge进行软件渲染。详情可以参考AWTK的代码。
[size=150]# NanoVG 优化笔记[/size]
[nanovg](https://github.com/memononen/nanovg)正如其名称所示的那样,是一个非常小巧的矢量绘图函数库。相比cairo和skia的数十万行代码,nanovg不足5000行的C语言代码,称为nano也是名副其实了。nanovg的设计、接口和代码质量都堪称典范,唯一美中不足的就是性能不太理想。特别是在Android的低端机型和大屏幕的机型上,一个简单的界面每秒只能画十几帧。最近我把AWTK移植到Android上时,就碰到了这个尴尬的问题。
经过优化之后,AWTK在低端机型上,整体渲染性能有了3到5倍的提升。这里做个笔记,供有需要的朋友参考。
nanovg的性能瓶颈在于片段着色器(fragment shader),片段着色器可以认为是为GPU提供的一个回调函数,该回调函数在处理每个像素时被调用,在每一帧绘制时都会执行数百万次,可见该函数的对性能的影响是很大的。
我们先看看nanovg的片段着色器(fragment shader)代码:
static const char* fillFragShader =
"#ifdef GL_ES\n"
"#if defined(GL_FRAGMENT_PRECISION_HIGH) || defined(NANOVG_GL3)\n"
" precision highp float;\n"
"#else\n"
" precision mediump float;\n"
"#endif\n"
"#endif\n"
"#ifdef NANOVG_GL3\n"
"#ifdef USE_UNIFORMBUFFER\n"
" layout(std140) uniform frag {\n"
" mat3 scissorMat;\n"
" mat3 paintMat;\n"
" vec4 innerCol;\n"
" vec4 outerCol;\n"
" vec2 scissorExt;\n"
" vec2 scissorScale;\n"
" vec2 extent;\n"
" float radius;\n"
" float feather;\n"
" float strokeMult;\n"
" float strokeThr;\n"
" int texType;\n"
" int type;\n"
" };\n"
"#else\n" // NANOVG_GL3 && !USE_UNIFORMBUFFER
" uniform vec4 frag[UNIFORMARRAY_SIZE];\n"
"#endif\n"
" uniform sampler2D tex;\n"
" in vec2 ftcoord;\n"
" in vec2 fpos;\n"
" out vec4 outColor;\n"
"#else\n" // !NANOVG_GL3
" uniform vec4 frag[UNIFORMARRAY_SIZE];\n"
" uniform sampler2D tex;\n"
" varying vec2 ftcoord;\n"
" varying vec2 fpos;\n"
"#endif\n"
"#ifndef USE_UNIFORMBUFFER\n"
" #define scissorMat mat3(frag[0].xyz, frag[1].xyz, frag[2].xyz)\n"
" #define paintMat mat3(frag[3].xyz, frag[4].xyz, frag[5].xyz)\n"
" #define innerCol frag[6]\n"
" #define outerCol frag[7]\n"
" #define scissorExt frag[8].xy\n"
" #define scissorScale frag[8].zw\n"
" #define extent frag[9].xy\n"
" #define radius frag[9].z\n"
" #define feather frag[9].w\n"
" #define strokeMult frag[10].x\n"
" #define strokeThr frag[10].y\n"
" #define texType int(frag[10].z)\n"
" #define type int(frag[10].w)\n"
"#endif\n"
"\n"
"float sdroundrect(vec2 pt, vec2 ext, float rad) {\n"
" vec2 ext2 = ext - vec2(rad,rad);\n"
" vec2 d = abs(pt) - ext2;\n"
" return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rad;\n"
"}\n"
"\n"
"// Scissoring\n"
"float scissorMask(vec2 p) {\n"
" vec2 sc = (abs((scissorMat * vec3(p,1.0)).xy) - scissorExt);\n"
" sc = vec2(0.5,0.5) - sc * scissorScale;\n"
" return clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n"
"}\n"
"#ifdef EDGE_AA\n"
"// Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n"
"float strokeMask() {\n"
" return min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * min(1.0, ftcoord.y);\n"
"}\n"
"#endif\n"
"\n"
"void main(void) {\n"
" vec4 result;\n"
" float scissor = scissorMask(fpos);\n"
"#ifdef EDGE_AA\n"
" float strokeAlpha = strokeMask();\n"
" if (strokeAlpha < strokeThr) discard;\n"
"#else\n"
" float strokeAlpha = 1.0;\n"
"#endif\n"
" if (type == 0) { // Gradient\n"
" // Calculate gradient color using box gradient\n"
" vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n"
" float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n"
" vec4 color = mix(innerCol,outerCol,d);\n"
" // Combine alpha\n"
" color *= strokeAlpha * scissor;\n"
" result = color;\n"
" } else if (type == 1) { // Image\n"
" // Calculate color fron texture\n"
" vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n"
"#ifdef NANOVG_GL3\n"
" vec4 color = texture(tex, pt);\n"
"#else\n"
" vec4 color = texture2D(tex, pt);\n"
"#endif\n"
" if (texType == 1) color = vec4(color.xyz*color.w,color.w);"
" if (texType == 2) color = vec4(color.x);"
" // Apply color tint and alpha.\n"
" color *= innerCol;\n"
" // Combine alpha\n"
" color *= strokeAlpha * scissor;\n"
" result = color;\n"
" } else if (type == 2) { // Stencil fill\n"
" result = vec4(1,1,1,1);\n"
" } else if (type == 3) { // Textured tris\n"
"#ifdef NANOVG_GL3\n"
" vec4 color = texture(tex, ftcoord);\n"
"#else\n"
" vec4 color = texture2D(tex, ftcoord);\n"
"#endif\n"
" if (texType == 1) color = vec4(color.xyz*color.w,color.w);"
" if (texType == 2) color = vec4(color.x);"
" color *= scissor;\n"
" result = color * innerCol;\n"
" }\n"
"#ifdef NANOVG_GL3\n"
" outColor = result;\n"
"#else\n"
" gl_FragColor = result;\n"
"#endif\n"
"}\n";
它的功能很完整也很复杂,裁剪和反走样都做了处理。仔细分析之后,我发现了几个性能问题:
### 一、颜色填充的问题
简单颜色填充和渐变颜色填充使用了相同的代码:
" if (type == 0) { // Gradient\n"
" // Calculate gradient color using box gradient\n"
" vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n"
" float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n"
" vec4 color = mix(innerCol,outerCol,d);\n"
" // Combine alpha\n"
" color *= strokeAlpha * scissor;\n"
" result = color;\n"
#### 问题
简单颜色填充只需一条指令,而渐变颜色填充则需要数十条指令。这两种情况重用一段代码,会让简单颜色填充慢10倍以上。
#### 方案
把颜色填充分成以下几种情况,分别进行优化:
* 矩形简单颜色填充。
对于无需裁剪的矩形(这是最常见的情况),直接赋值即可,性能提高20倍以上。
" if (type == 5) { //fast fill color\n"
" result = innerCol;\n"
* 通用多边形简单颜色填充。
去掉渐变的采样函数,性能会提高一倍以上:
" } else if(type == 7) { // fill color\n"
" strokeAlpha = strokeMask();\n"
" if (strokeAlpha < strokeThr) discard;\n"
" float scissor = scissorMask(fpos);\n"
" vec4 color = innerCol;\n"
" color *= strokeAlpha * scissor;\n"
" result = color;\n"
* 渐变颜色填充(只占极小的部分)。
这种情况非常少见,还是使用之前的代码。
#### 效果:
平均情况,填充性能提高10倍以上!
### 二、字体的问题
对于文字而言,需要显示的像素和不显示的像素,平均算下来在1:1左右。
" } else if (type == 3) { // Textured tris\n"
"#ifdef NANOVG_GL3\n"
" vec4 color = texture(tex, ftcoord);\n"
"#else\n"
" vec4 color = texture2D(tex, ftcoord);\n"
"#endif\n"
" if (texType == 1) color = vec4(color.xyz*color.w,color.w);"
" if (texType == 2) color = vec4(color.x);"
" color *= scissor;\n"
" result = color * innerCol;\n"
" }\n"
#### 问题:
如果显示的像素和不显示的像素都走完整的流程,会浪费调一半的时间。
#### 方案:
* 当color.x < 0.02时直接跳过。
* 裁剪和反走样放到判断语句之后。
" } else if (type == 3) { // Textured tris\n"
"#ifdef NANOVG_GL3\n"
" vec4 color = texture(tex, ftcoord);\n"
"#else\n"
" vec4 color = texture2D(tex, ftcoord);\n"
"#endif\n"
" if(color.x < 0.02) discard;\n"
" strokeAlpha = strokeMask();\n"
" if (strokeAlpha < strokeThr) discard;\n"
" float scissor = scissorMask(fpos);\n"
" color = vec4(color.x);"
" color *= scissor;\n"
" result = color * innerCol;\n"
" }\n"
#### 效果:
字体渲染性能提高一倍!
### 三、反走样的问题
反走样的实现函数如下(其实我也不懂):
"float strokeMask() {\n"
" return min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * min(1.0, ftcoord.y);\n"
"}\n"
#### 问题:
与简单的赋值操作相比,加上反走样功能,性能会下降5-10倍。但是不加反走样功能,绘制多边形时边缘效果比较差。不加不好看,加了又太慢,看起来是个两难的选择。
#### 方案:
矩形填充是可以不用反走样功能的。而90%以上的情况都是矩形填充。矩形填充单独处理,一条指令搞定,性能提高20倍以上:
" if (type == 5) { //fast fill color\n"
" result = innerCol;\n"
#### 效果:
配合裁剪和矩形的优化,性能提高10倍以上。
### 四、裁剪的问题
裁剪放到Shader中虽然合理,但是性能就要大大折扣了。
"// Scissoring\n"
"float scissorMask(vec2 p) {\n"
" vec2 sc = (abs((scissorMat * vec3(p,1.0)).xy) - scissorExt);\n"
" sc = vec2(0.5,0.5) - sc * scissorScale;\n"
" return clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n"
"}\n"
#### 问题:
与简单的赋值操作相比,加上裁剪功能,性能会下降10以上倍。但是不加裁剪功能,像滚动视图这样的控件就没法实现,这看起来也是个两难的选择。
#### 方案:
而90%以上的填充都是在裁剪区域的内部的,没有必要每个像素都去判断,放在Shader之外进行判断即可。
static int glnvg__pathInScissor(const NVGpath* path, NVGscissor* scissor) {
int32_t i = 0;
float cx = scissor->xform[4];
float cy = scissor->xform[5];
float hw = scissor->extent[0];
float hh = scissor->extent[1];
float l = cx - hw;
float t = cy - hh;
float r = l + 2 * hw - 1;
float b = t + 2 * hh - 1;
const NVGvertex* verts = path->fill;
for (i = 0; i < path->nfill; i++) {
const NVGvertex* iter = verts + i;
int x = iter->x;
int y = iter->y;
if (x < l || x > r || y < t || y > b) {
return 0;
}
}
return 1;
}
#### 效果:
配合裁剪和矩形的优化,性能提高10倍以上。
### 五、综合
综合裁剪、反走样和矩形,新增3个类型,进行特殊处理:
* 快速填充无需裁剪的矩形:NSVG\_SHADER\_FAST\_FILLCOLOR
* 快速填充无需裁剪的图片:NSVG\_SHADER\_FAST\_FILLIMG
* 快速用简单颜色填充多边形:NSVG\_SHADER\_FILLCOLOR
裁剪、反走样和矩形可以组合更多类型,进行更精细的优化。但即使只作这三种情况处理,[AWTK](https://github.com/zlgopen/awtk)在Android平台的整体性能已经有了3-5倍的提高,demoui在我们测试的机型上,都稳稳的保持在60FPS,没有必要为了性能增加它的复杂度了。
详细情况和完整代码请参考AWTK
谢谢晕哥支持:)
awtk-iotjs
一、介绍
关于 iotjs
iotjs 是三星开源的 javascript 物联网开发平台。它为 javascript 应用程序提供了访问硬件、网络、文件系统和异步化的能力,功能类似于 nodejs,但无论是代码体积还是内存需求,iotjs 都要小很多,是用 javascript 开发 iot 设备应用程序的首选。
关于 AWTK
AWTK 全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。
awtk-iotjs 将 awtk 和 iotjs 有机结合起来,用 javascript 打通 GUI、网络和硬件,完全采用 javascript 开发物联网应用程序。
二、编译
下载编译 iotjs
git clone https://github.com/pando-project/iotjs.git
cd iotjs
./tools/build.py
cd -
下载编译 awtk
git clone https://github.com/zlgopen/awtk.git
cd awtk
scons
cd -
下载编译 awtk-js
git clone https://github.com/zlgopen/awtk-js.git
cd awtk-js
git clone https://github.com/jerryscript-project/jerryscript.git 3rd/jerryscript
scons
cd -
下载编译 awtk-iotjs
准备工作:
目前我不知道如何在 module.json 中指定编译参数,所以只好修改 iotjs/CMakeLists.txt 了。请在倒数第二行增加下面这行代码。
include(../awtk-iotjs/awtk-module/awtk.cmake)
下载编译:
git clone https://github.com/zlgopen/awtk-iotjs.git
cd awtk-iotjs
./build.sh
请确认以上项目均在同一个目录。
三、运行 DEMO
./run.sh demos/buttons.js
四、开发
在开发时可以使用:
iotjs 提供的模块。
awtk-js 提供的 GUI 控件。
其它第三方模块。
与 awtk-js 主要差异是需要加载并初始化 awtk:
require('awtk').init(320, 480);
完整示例:
require('awtk').init(320, 480);
function applicationInit() {
var win = TWindow.create(null, 0, 0, 0, 0);
var ok = TButton.create(win, 0, 0, 0, 0);
ok.setText("ok");
ok.setSelfLayoutParams("center", "middle", "50%", "30");
ok.on(TEventType.CLICK, function(evt) {
var e = TPointerEvent.cast(evt);
console.log("on click: " + e.x + " " + e.y);
return TRet.OK;
});
win.layout();
}
applicationInit()
五、已知问题
只支持 Linux 系统 (Ubuntu >= 16)。
未 awtk-linux-fb 上验证,可能修改一下脚本。
理论上 Windows 平台也是可以的,但是 iotjs 没编译过。
六、内部实现文档
[为 iotjs 开发原生模块](docs/write[cur]iotjs[/cur]native_module.md)
[集成 GUI 到 iotjs](docs/integrate[cur]gui[/cur]with_iot.md)
看过视频,效果很好。李工,这个GUI有没有交流群?
谢谢关注。我在README的最下面加了一个微信群的二维码:https://github.com/zlgopen/awtk
关注这个GUI 很久了, 找机会试一试。
请问楼主是开发awtk 开发团队的吗?
是的。谢谢关注。
这不是FTK的作者嘛?久仰!
哈哈,遇到熟人了。
AWTK全称Toolkit AnyWhere,是ZLG开发的开源GUI引擎,旨在为嵌入式系统、WEB、各种小程序、手机和PC打造的通用GUI引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的GUI引擎。
AWTK寓意有两个方面:
Toolkit AnyWhere。
ZLG物联网操作系统AWorks内置GUI。
AWTK源码仓库:
运行效果截图:
支持开发嵌入式应用程序。
支持开发Linux应用程序。
支持开发MacOS应用程序。
支持开发Windows应用程序。
支持开发Web APP。
支持开发微信小程序。
支持开发支付宝小程序。
支持开发百度小程序。
支持开发Android应用程序。
支持开发iOS应用程序。
支持开发2D小游戏。
1.跨平台
AWTK是跨平台的,这有两个方面的意思:
AWTK本身是跨平台的。目前支持的平台有ZLG AWorks、Windows、Linux、MacOS、嵌入式Linux和嵌入式裸系统,可以轻松的移植到各种RTOS上。AWTK以后也可以运行在浏览器(即将公测)、各种小程序、Android和iOS等平台上运行。
AWTK同时还提供了一套跨平台的基础工具库。其中包括链表、数组、字符串(UTF8和widechar),事件发射器、值、对象、文件系统、互斥锁和线程、表达式和字符串解析等等,让你用AWTK开发的应用程序可以真正跨平台运行。
2.高效
AWTK通过一系列的手段保证AWTK应用程序高效运行:
通过脏矩算法只更新变化的部分。
支持3 FrameBuffer让界面以最高帧率运行(可选)。
UI描述文件和主题文件使用高效的二进制格式,解析在瞬间完成。
支持各种GPU加速接口。如OpenGL、DirectX、Vulman和Metal等。
支持嵌入式平台的各种2D加速接口。目前STM32的DMA2D和NXP的PXP接口,厂家可以轻松扩展自己的加速接口。
3.稳定
AWTK通过下列方式极力让代码稳定可靠:
使用cppcheck和facebook infer进行静态检查。
使用valgrind进行动态内存检查。
近两万行的单元测试代码。
ZLG强大GUI团队的支持。
经过多个实际项目验证。
多平台/多编译器验证。
优秀的架构设计。
Code Review。
手工测试。
4.强大
丰富的控件(持续增加中)。
支持各种图片格式(png/jpg/gif/svg)。
支持各种字体格式(点阵和矢量)。
支持窗口动画
支持控件动画
支持高清屏。
支持界面描述文件。
支持主题描述文件。
支持控件布局策略。
支持对话框高亮策略。
丰富的辅助工具。
支持从低端的Cortex M3到各种高端CPU。
支持无文件系统和自定义的文件系统。
支持裸系统和RTOS。
5.易用
大量的示例代码。
完善的API文档和使用文档。
ZLG 强大的技术支持团队。
用AWTK本身开发的界面编辑器(开发中)。
声明式的界面描述语言。一行代码启用控件动画,启用窗口动画,显示图片(png/jpg/svg/gif)。
6.高度扩展性
可以扩展自己的控件。
可以扩展自己的动画。
可以实现自己的主循环。
可以扩展自己的软键盘。
可以扩展自己的图片加载器。
可以扩展自己的字体加载器。
可以扩展自己的输入法引擎。
可以扩展自己的控件布局算法。
可以扩展自己的对话框高亮策略。
可以实现自己的LCD接口。
可以扩展自己的矢量引擎(如使用skia/cairo)。
所有扩展组件和内置组件具有相同的待遇。
7.多种开发语言
AWTK本身是用C语言开发的,可以通过IDL生成各种脚本语言的绑定。生成的绑定代码不是简单的把C语言的API映射到脚本语言,而是生成脚本语言原生代码风格的API。目前支持以下语言(以后根据需要增加):
C
Lua
Javascript on jerryscript
Javascript on nodejs
8.国际化
支持Unicode。
支持输入法。
支持字符串翻译(实时生效)。
支持图片翻译(实时生效)。
文字双向排版(计划中)。
9.开放源码,免费商用(LGPL)。
1.稳定性增强
多个实际项目验证。
新增数百个测试用例。
增加控件运行时类型检查。
使用infer静态检查,并修改发现的问题。
使用cppcheck静态检查,并修改发现的问题。
使用valgrind动态内存检查,并修改发现的问题。
2.优化性能
绘制半透明色矩形速度提高3倍。
缩放不透明图片快1倍(bgr565格式LCD)。
缩放半透明图片快30%(bgr565格式LCD)。
3.新增特性
窗口动画支持自定义。
新增4种内置窗口动画。
对话框高亮策略支持自定义。
内置动态和静态背景变暗的对话框高亮策略。
新增 object_t接口。
对话框支持非模态。
窗口支持全屏窗口。
增加toast/info/confirm等内置对话框。
slide view支持循环切换。
slide view增加更多切换动画。
数字时钟支持英文的星期和月份。
支持自定义软键盘。
增加lcd_profile用于对绘制函数进行profile。
data资源支持同文件名不同扩展名。
window manager支持paint事件。
UI XML文件支持简单表达式。
改进编译脚本和资源生成脚本。
4.新增控件
增加mutable image,用于实现camera和video时显示图像。
5.新增重要API
window_manager_back 返回上一级窗口。
window_manager_back_to_home 返回主窗口。
window_close_force 强制关闭窗口(忽略动画)。
ui_loader_load_widget 用于加载局部组件。
6.Bug修改和完善功能
详情请参考docs/changes.md。
下一个版本计划推出下列功能:
新增控件。
抽象音频接口。
桌面版本支持多原生窗口。
在sylixos和linux上支持多进程。
AWTK-WEB 让AWTK应用程序在浏览器中运行。
AWTK-MVVM 为嵌入式系统定制的MVVM框架。
需要什么功能,请在github上留言,我们会优先安排。
前段时间我研究了一下,本来打算让AWTK支持blend2d的,可惜没有arm版本的。
真是奇怪,有GPU的情况下,SIMD这些都是渣渣,而嵌入式平台才是真正需要软件渲染的,反而不支持。
ZLG开源 GUI 引擎 AWTK 1.1 发布: https://www.oschina.net/news/106208/awtk-1-1-released
谢谢大家支持
页次: 1