# 12. 附录二:AWTK 可裁剪的功能模块

# 12.1 窗口动画模块

AWTK 提供窗口动画功能,在窗口打开或关闭时,可以引入一个过渡动画,让用户感觉这个过程是流畅的。其基本原理很简单:在打开或关闭窗口时,把前后两个窗口预先绘制到两张内存图片上,按照指定规则显示两张图片,形成动画效果。

AWTK 默认启动窗口动画模块,其占用资源详见本文第九章,对于资源紧缺的低端平台,如果不使用窗口动画,编译时定义下面的宏即可:

#define WITHOUT_WINDOW_ANIMATORS 1

以上宏定义以及本文中介绍的 AWTK 功能模块相关的宏定义如果没有特别说明,一般情况下,在 PC 上修改 awtk_config.py 文件,在嵌入式系统上修改 awtk_config.h 文件。

此外,启用窗口动画时,默认情况下,需要对前后两个窗口进行截图,以获得更好的性能,但是这需要两个 Framebuffer 大小的内存,如果内存不够,可以选择关闭截图缓存,直接进行绘制。编译时定义下面的宏即可:

/**
 * 通常在以下情况,关闭窗口动画截图缓存:
 *  1. 窗口界面简单;
 *  2. 内存资源紧缺,但 CPU 速度较快。
 *
 * 限制条件:
 *  1.不支持缩放窗口动画。
 *  2.不支持对话框高亮策略。
 *
 * 备注:如果绘制速度慢,而且内存紧缺,建议关闭窗口动画。
 */
#define WITHOUT_WINDOW_ANIMATOR_CACHE 1

AWTK 1.6.1 不支持上述宏定义,如需关闭窗口动画缓存,请使用 1.6.1 版本以上的 AWTK。

# 12.2 控件动画模块

AWTK 提供控件动画功能,常用于入场动画、离场动画、装饰用户界面和吸引用户注意力等,其主要特色和使用方法详见:awtk/docs/widget_animator.md。

AWTK 默认启动控件动画模块,其占用资源详见本文第九章,对于资源紧缺的低端平台,如果不使用控件动画,编译时定义下面的宏即可:

#define WITHOUT_WIDGET_ANIMATORS 1

控件动画中的缩放与旋转动画需要矢量画布 vgcanvas 的支持,其介绍详见下文矢量图画布模块。

# 12.3 图片解码模块

AWTK 采用第三方的 STB 类库实现 jpg、png 和 gif 格式图片资源的软解码,其占用资源详见本文第九章

需要注意的是 STB 类库在解码 jpg 图片时,所需内存约为三个位图大小+ 18456B,而解码 png 图片时,所需内存约为两个位图大小,以上皆为解码时的内存峰值,解码完成后会这些内存会被释放,若 STB 在解码时申请不到这么大的内存,将解码失败无法显示图片,但不影响程序正常运行。

如果希望启动图片解码模块,即支持 jpg/png/gif 图片,编译时定义下面的宏即可:

#define WITH_STB_IMAGE 1

如果希望将图片解码成 BGRA8888 格式的位图,请定义下面的宏,否则将解码成 RGBA8888 格式的位图:

#define WITH_BITMAP_BGRA 1

如果希望将不透明的 PNG 图片解码成 BGR565 格式的位图,请定义下面的宏:

#define WITH_BITMAP_BGR565 1

如果希望将不透明的 PNG 图片解码成 RGB565 格式的位图,请定义下面的宏:

#define WITH_BITMAP_RGB565 1

解码出来的位图格式与 LCD 的格式保存一致,可以大幅度提高性能。

此外,AWTK 的图片解码模块为提高效率,存在缓存机制,通常在第一次显示图片时将其解码成位图并缓存到图片管理器(image_manager)中,下一次再显示这张图片时就直接到缓存拿就行了,当内存不足时 AWTK 会自动清除长时间不用的图片缓存,用户也可以调用 image_manager_unload_unused 接口清除指定时间内没有使用的图片缓存。

  1. AWTK 中用于图片解码的 STB 类库详见:awtk/3rd/stb/stb_image.h。
  2. AWTK 中的图片解码器详见:awtk/src/image_loader_stb.h。

# 12.4 字体解码模块

AWTK 支持矢量(TrueType)字体解码,可以将矢量字体解码成位图显示到界面上,目前提供 STB 类库和 FreeType 类库两种实现的字体解码器。FreeType 类库虽然功能强大,但与 STB 类库相比,项目代码量大,占用较多 ROM 资源,因此 AWTK 通常使用 STB 类库解码矢量字体,编译时定义下面的宏即可,STB字体解码器占用资源详见本文第九章

#define WITH_STB_FONT 1

如果仍然希望使用 FreeType 类库解析矢量字体,则可以定义下面的宏:

#define WITH_FT_FONT 1

如果以上两个宏同时定义,则优先使用 STB 类库。

此外,AWTK 的字体解码模块为提高效率,存在缓存机制,通常在第一次显示字体时将其解码成字模并缓存到 glyph_cache_t 中,下一次再显示这个字体时就直接到缓存拿就行了,当缓存的字模个数达到上限或内存不足时 AWTK 会自动清除最长时间不用的字模缓存,用户也可以调用 font_manager_shrink_cache 接口清除字模缓存。

AWTK 在嵌入式平台上默认字模缓存的最大个数为 256 个,用户可以通过定义宏 TK_GLYPH_CACHE_NR 来设置字模缓存的容量:

#ifndef TK_GLYPH_CACHE_NR
#ifdef WITH_SDL
#define TK_GLYPH_CACHE_NR 4096
#else
#define TK_GLYPH_CACHE_NR 256   /* 设置最多缓存 256 个字模 */
#endif /*WITH_SDL*/
  1. STB 类库实现的字体解码器详见:awtk/src/font_loader/font_loader_stb.h。
  2. TrueType 类库实现的字体解码器详见:awtk/src/font_loader/font_loader_ft.h。

# 12.5 输入法模块

AWTK 提供输入法模块功能,它的实现不是特别复杂,但涉及的组件较多,理解起来比较困难,这里简单介绍一下 AWTK 中输入法模块的内部实现框架,详见下图:

图12.1 输入法模块实现框架
图12.1 输入法模块实现框架
  • input_method_default 提供 AWTK 输入法模块的缺省实现,负责软键盘的开关和输入法引擎的创建,通常用于嵌入式平台。
  • input_method_sdl 包装了 SDL 的原生输入法,使用平台自身的输入引擎,通常用于桌面 Linux、MacOS、Windows、Android和 iOS 等平台。
  • input_method_null 提供了空的输入法实现,在不启用输入法时使用。

AWTK 默认启用输入法模块,其占用资源详见本文第九章,对于资源紧缺的低端平台,如果不使用输入法功能,编译时定义下面的宏即可:

#define WITH_NULL_IM 1

启用 AWTK 输入法模块时,需添加 awtk/src/input_methods/input_method_creator.c 文件。

输入法引擎主要负责将用户的按键转换成一组候选字,这些候选字将在软键盘上的候选字控件上显示出来。输入法引擎有很多,不同的语言也有不同的输入法引擎。目前 AWTK 只支持英文和中文输入,提供多种输入法引擎,具体详见:awtk/src/input_engines/README.md 文档。

如果不启用输入法,可以不用加任何输入法引擎。

在嵌入式平台上,常用的输入法引擎如下:

输入法引擎 适用场景 宏定义 需要添加的源文件
null 输入法引擎 用于启用软键盘,但无需输入法引擎的情况,比如只需软键盘输入英文 WITH_IME_NULL input_engine_null.c
Goole 拼音输入引擎 用于需要中文拼音输入的情况,要求 ROM 不小于 4M WITH_IME_PINYIN input_engine_pinyin.c
带触摸屏的 T9 输入法引擎 T9 输入法又称九宫格输入法,常用于 Android和 iOS 等平台 WITH_IME_T9 input_engine_t9.c
外接键盘 T9 输入法引擎 需要使用 T9 输入法,但又没有触摸屏时,使用外部硬键盘,请使用本引擎 WITH_IME_T9EXT input_engine_t9ext.c
  1. 以上输入法引擎不能同时使用,其所需源文件均放在 awtk/src/input_engines 目录。
  2. 如果希望使用 Goole 拼音输入引擎加入中文输入法,还需要加入 gpinyin 类库,即 awtk/3rd/gpinyin/src 目录下的源码文件,加入中文输入法的步骤请参考:awtk/docs/chinese_ime.md。
  3. 如果使用 Goole 拼音输入引擎,并希望自定义拼音输入法字典和联想字库,请参考:awtk/docs/how_to_update_gpinyin_data.md。
  4. T9 输入法引擎的使用方法详见:awtk/docs/t9_notes.md。

如果启用输入法模块,但不想启用联想功能,请定义本下面的宏:

#define WITHOUT_SUGGEST_WORDS 1

联想功能是指输入某个汉字或词组后,输入法会根据该汉字或词组提供其常用的组词,例如输入汉字 "我" 后,输入法会根据"我们"、"我国"、"我省"等常用组词,提供"们"、"国"、"省"等汉字。

此外,AWTK 的输入法引擎默认候选字个数为 255 个,即候选字缓冲区大小为 255 字节,用户可以通过定义下面的宏来设置候选字缓冲区的大小:

#define TK_IM_DEFAULT_MAX_CANDIDATE_CHARS 255 

#ifndef TK_IM_MAX_CANDIDATE_CHARS
#define TK_IM_MAX_CANDIDATE_CHARS TK_IM_DEFAULT_MAX_CANDIDATE_CHARS
#endif

# 12.6 矢量图画布模块

AWTK 支持矢量图画布,主要用于绘制矢量图形(比如图片的旋转与缩放,控件圆角等,但是填充圆角矩形和边框为1的圆角矩形不受影响),其抽象基类接口详见:awtk/src/base/vgcanvas.h,目前 AWTK 提供了基于 nanovg 的实现,由于原生 nanovg 只支持 OpenGL 硬件渲染,因此我们对它进行了一些改进,使用 agg/agge 作为 nanovg 图形渲染后端,实现软件渲染;:

nanovg 是第三方开源的矢量图形库(Vector graphics library),GitHub 地址:https://github.com/memononen/nanovg。

经过改进后,AWTK 的矢量图画布模块共有以下四类实现:

矢量图画布的实现 说明 适用场景 后端实现
vgcanvas_nanovg_soft 纯软件实现 适合大多数嵌入式平台 其后端有 agg 和 agge 两种实现
vgcanvas_nanovg_gl OpenGL 实现 适合有 GPU 且支持 OpenGL 的平台 其后端有 OpenGL3、OpenGLES2 和 OpenGLES3 三种实现
vgcanvas_cairo cairo 实现 cairo 也是软件矢量库,速度快功能全,但代码体积大,请酌情使用
vgcanvas_null 空实现 适合资源极其有限的低端平台,不支持矢量图画布模块时使用本实现

以上矢量图画布的实现源码均放在 awtk/src/vgcanvas 目录。

AWTK 中控制矢量图画布模块的宏较多,此处统一列出,具体用法详见注释。

需要注意的是,在嵌入式平台上,通常采用 agge 软件渲染模式支持矢量画布,此时只需定义宏 WITH_NANOVG_AGGE 即可,AWTK 会自行定义宏 WITH_VGCANVAS、WITH_NANOVG 和 WITH_NANOVG_SOFT。

采用 agge 软件渲染模式支持矢量画布会占用约 30 KB 内存和 20 KB 的 ROM,具体详见本文第九章

/**
 * 如果启用矢量图画布,请定义本宏
 */
#define WITH_VGCANVAS 1

/**
 * 如果希望使用基于 nanovg 实现的矢量图画布,请定义本宏
 */
#define WITH_NANOVG 1

/**
 * 在有 GPU 时,如果希望使用硬件 OpenGL 渲染矢量画布,请定义本宏
 * > 备注:定义本宏时,AWTK 会自动定义宏 WITH_VGCANVAS 和 WITH_NANOVG。
 */
#define WITH_NANOVG_GPU 1

/**
 * 在没有 GPU 时,如果希望使用软件渲染矢量画布,请定义本宏
 * > 备注:定义本宏时,AWTK 会自动定义宏 WITH_VGCANVAS 和 WITH_NANOVG。
 */
#define WITH_NANOVG_SOFT 1

/**
 * 如果希望使用软件渲染矢量画布,且启用 agge 作为 nanovg 的后端,请定义本宏
 * > 备注:agge 相较于 agg,代码量小,速度快,但图像质量稍差。
 * > 备注:定义本宏时,AWTK 会自动定义宏 WITH_VGCANVAS、WITH_NANOVG 和 WITH_NANOVG_SOFT。
 */
#define WITH_NANOVG_AGGE 1

/**
 * 如果希望使用软件渲染矢量画布,且启用 agg 作为 nanovg 的后端,请定义本宏
 * > 备注:agg 相较于 agge,代码量大,速度慢,但图像质量较好,且 agg 是以 GPL 协议开源,
 如果在商业软件中使用,需要与原作者协商:http://www.antigrain.com。
 * > 备注:定义本宏时,AWTK 会自动定义宏 WITH_VGCANVAS、WITH_NANOVG 和 WITH_NANOVG_SOFT。
 */
#define WITH_NANOVG_AGG 1

此外,在嵌入式平台上定义宏 WITH_NANOVG_AGGE,支持矢量图画布时,需要加到工程中的文件详见下表:

目录 说明
awtk/src/svg 支持矢量图画布时全部加入
awtk/src/vgcanvas 使用软件渲染支持矢量画布请加入 vgcanvas_nanovg_soft.c,不支持矢量画布则加入 vgcanvas_null.c
awtk/3rd/agge 启用 agge 作为 nanovg 的后端实现软件渲染时加入
awtk/3rd/nanovg/base 支持矢量图画布时全部加入

# 12.7 对话框高亮模块

AWTK 支持对话框高亮策略,即打开对话框时,将背景窗口变暗或变模糊,以突出当前对话框的重要性,其占用资源详见本文第九章。AWTK 把对话框高亮策略抽象成接口(awtk/src/base/dialog_highlighter),用户可以自己实现特殊效果的高亮策略,也可以使用缺省的高亮策略。

AWTK 对话框高亮策略的使用方法和自定义高亮策略的步骤请参考:awtk/docs/dialog_highlight.md。

缺省的对话框高亮策略是让背景窗口变暗,其原理与窗口动画类似,打开对话框时,把前后两个窗口预先绘制到两张内存图片上(会在背景上画一层半透明的蒙版来突出对话框),按照指定规则显示两张图片,形成动画效果。它可以是静态的,即透明度(alpha)固定不变,也可以是动态的,即透明度(alpha)在打开对话框的过程中是不断变化的。

动态的高亮策略在对话框打开的动画过程中,背景窗口逐渐变暗,有更好的视觉效果,但也需要更多的计算开销。对于计算性能不高的低端平台建议使用静态的高亮策略,即将 start_alpha 和 end_alpha 属性设为相同值。

对于低端平台,如果不使用对话框高亮策略,请定义下面的宏:

#define WITHOUT_DIALOG_HIGHLIGHTER 1

# 12.8 剪切板模块

AWTK 提供了剪切板功能,抽象接口详见:awtk/src/clip_board.h,目前有以下两种实现:

  • clip_board_sdl 包装了 SDL 的原生剪切板,使用平台自身的剪切板功能,通常用于桌面 Linux、MacOS、Windows、Android和 iOS 等平台。
  • clip_board_default 提供 AWTK 剪切板的缺省实现,通常用于嵌入式平台。

以上剪切板的实现文件均放在 awtk/src/clip_board 目录。

AWTK 默认启用剪切板,其占用资源详见本文第九章,对于低端平台,如果不使用剪切板功能,请定义下面的宏:

#define WITHOUT_CLIPBOARD 1

# 12.9 布局模块

如果界面上的控件是预先知道的,而且窗口大小固定不变,那么此时创建界面非常简单,直接设置控件的位置和大小即可。但在以下情况中,使用布局参数是更好的选择:

  • 窗口的大小是可以动态调整的;
  • 需要适应不同分辨率的 LCD;
  • 界面上的控件是动态生成的,需要在程序运行中创建界面;

AWTK 提供了控件布局管理器(layouter),其中包含对控件自身进行布局的 self_layouter 以及对子控件进行布局的 children_layouter,它们的介绍和详细用法请参考:awtk/docs/layout.md。

除了 AWTK 默认支持的布局参数(比如百分比、位置居左/中/右、浮动布局、网格布局等)之外,AWTK 还提供了灵活的扩展机制,self_layouter 和 children_layouter 都是抽象接口,用户可以自行实现新的布局方式。

AWTK 默认启用布局模块,其占用资源详见本文第九章,如果不使用布局管理器的功能,请定义下面的宏:

#define WITHOUT_LAYOUT 1

# 12.10 通用文件系统模块

AWTK 提供了通用文件系统的抽象接口(awtk/src/tkc/fs.h),由于该功能与平台系统相关,目前 AWTK 仅内置了 Linux、MacOS、Windows、Android 和 iOS 平台上的实现,代码详见:awtk/src/platforms/pc/fs_os.c,如果需要在其他嵌入式平台上使用文件系统的功能请参考本文第六章进行移植。

在 AWTK 中,文件系统模块的功能主要用于支持文件系统时,从文件系统中加载项目资源(比如 UI 界面、图片、字库等),资源目录结构和加载方式详见 AWTK 开发实践

如果支持从文件系统加载资源,请定义下面的宏,AWTK 将使用项目 res/assets/default/raw 目录下的资源,其中 default 是主题名称:

#define WITH_FS_RES 1

AWTK 也支持自定义资源根目录,在某些嵌入式平台上,由于 ROM 有限,项目资源又比较多,通常会将代码(程序/固件)放在 ROM 中,而资源放在文件系统中,比如外接 SD 卡,此时可以定义下面的宏指定资源所在的路径:

#define APP_RES_ROOT "0://AwtkApplication/res/"

# 12.11 标准的 UNICODE 换行模块

AWTK 提供了标准的 UNICODE 换行算法,用于处理字符串的换行情况(比如遇到 "\r\n"、"\r"、"\n"等符号换行、英文单词不允许换行等情况),其需要约 50 KB 的 ROM 和 1.5 KB 的 RAM。

在嵌入式平台上,除非资源极为有限,否则建议定义下面的宏,启用 UNICODE 换行模块:

#define WITH_UNICODE_BREAK 1

# 12.12 半透窗口机制模块

AWTK 支持半透窗口机制,即支持窗口背景为透明色的刷新机制。在某些平台下,支持多个 LCD 的硬件图层(Framebuffer),这些图层可以在硬件绘制时做融合显示到 LCD 上,比软件合成要快得多,既然是要做图层融合,那么通常都会存在窗口背景为透明的情况,此时可以定义下面的宏,启用 AWTK 半透窗口机制:

AWTK 的半透窗口机制只适用于多个硬件图层融合的情况,比如一个硬件图层刷新 GUI,另一个硬件图层播放视频,二者融合在一起显示整个界面。

#define WITH_LCD_CLEAR_ALPHA 1

需要注意的是,启用半透窗口机制要求 AWTK 的 LCD 类型必须为 32 位色(RGBA 或 BGRA),并且会增加窗口绘制时的计算量(做透明色混合运算),降低 AWTK 的性能,用户请根据实际情况决定是否启用。

# 12.13 AWTK 内存管理模块

AWTK 提供了内存管理器,其接口详见:awtk/src/tkc/mem.h,它基于内存分配器(mem_alloactor_t)实现,目前 AWTK 提供的内存分配器详见下图:

图12.2 AWTK内存分配器
图12.2 AWTK内存分配器

AWTK 初始化时,会调用 tk_mem_init 函数初始化内存管理器(给内存管理器分配一大块内存),具体流程详见本文第一章

以上内存分配器有两个基础实现,它们的介绍和适用场景如下:

1、mem_alloactor_std 是基于标准的 malloc/free/calloc 等函数实现的内存分配器。在系统提供了 malloc/free/realloc 函数时,请定义下面的宏,使用本分配器:

#define HAS_STD_MALLOC 1

2、mem_alloactor_simple 是 AWTK 本身实现的一个简单的内存分配器,通常在系统没有提供标准的 malloc/free/calloc 等函数时使用,即没有定义宏 HAS_STD_MALLOC。

其中,使用 mem_alloactor_simple 作为内存分配器时,AWTK 基于装饰器设计模式对其进行了以下四层包装:

3、mem_alloactor_lock 对现有的 allocator 进行包装,提供互斥功能。由于标准内存分配器使用的 malloc/free/realloc 函数本身有互斥功能,所以本装饰器主要用于 mem_allocator_simple。

4、mem_alloactor_pool 对现有的 allocator 进行包装,预先分配一部分内存作为内存池,将其分割成多个小内存块,用于分配小块内存,可以避免内存碎片,内存池占用的资源和分割情况详见本文第九章,需要注意的是,在没有定义宏 HAS_STD_MALLOC 且 tk_mem_init 函数设置的内存大小大于 32KB 时才会分配内存池。

经测试,通常在程序运行中 80% 的情况都是小块内存,在内存池中分配,可以有效的防止内存碎片的产生,并且用户可以跟踪 mem_allocator_pool 的使用情况,根据实际情况调整预先分配的块数(详见 mem_allocator_pool_init 函数)。

5、mem_alloactor_debug 对现有的 allocator 进行包装,记录分配的内存,用于帮助分析内存的使用和泄露,在定义下面的宏后启动该功能,在程序中可以调用 tk_mem_dump 函数打印内存使用情况。

#define ENABLE_MEM_LEAK_CHECK 1

由于 mem_allocator_debug 本身会占用一部分内存,一般在只 PC 上使用。

6、mem_alloactor_oom 对现有的 allocator 进行包装,如果分配内存失败,调用预先设置的回调函数释放内存,然后再重试,AWTK 默认启用该功能,内存耗尽处理流程详见:awtk/docs/out_of_memory.md。

由于 AWTK 内置的内存耗尽处理使用了信号量,因此在多线程场景下调用调用内存管理器的接口,需要参考本文第六章内容移植互斥锁和信号量。

此时,调用 TKMEM_ALLOC 函数分配内存时的流程详见下图:

图12.3 内存管理器流程图
图12.3 内存管理器流程图
  1. 该流程图主要描述使用 mem_alloactor_simple 时的流程,如果使用的是 mem_alloactor_std,仅在 malloc 时有差别。
  2. 如果使用标准的内存分配器 mem_allocator_std ,那么上图虚线框内的流程即调用标准的 malloc 函数。
  3. AWTK 的内存耗尽处理流程请详见:awtk/docs/out_of_memory.md。

此外,为提高绘制性能,AWTK 默认使用内置 tk_memcpy16 函数和 tk_memcpy32 函数拷贝图像,如果平台有提供优化版本的 memcpy 函数,可以定义下面的宏,直接使用 memcpy 函数拷贝图像:

#define HAS_FAST_MEMCPY 1

在嵌入式系统中,可能有多块不连续的内存,AWTK 也支持多块不连续的内存块,请定义下面的宏指定内存块的数目,并使用 tk_mem_init_ex 函数代替 tk_mem_init 函数初始化内存,示例用法请参考:awtk/docs/how_to_support_multi_mem_block.md。

#define TK_MAX_MEM_BLOCK_NR 4

# 12.14 G2D 硬件加速模块

AWTK 支持 G2D 硬件加速,主要用于提高图像绘制的性能,其接口详见:awtk/src/base/g2d.h,只需要该文件中的相关接口,并定义下面的宏,即可启用 G2D 硬件加速:

#define WITH_G2D 1

目前,AWTK 内置了 STM32 系列平台 G2D 硬件加速的实现,代码详见:awtk/src/blend/stm32_g2d.c,只需定义下面的宏即可启用该功能:

#define WITH_STM32_G2D 1

此外,在 AWTK 针对 AWorks (RT1052)平台的 移植层 (opens new window) 中,提供了 NXP PXP 硬件加速的实现文件,代码详见:awtk-aworks-rt1052/awtk-port/rt1052_g2d.c,只需定义下面的宏即可启用该功能:

#define WITH_PXP_G2D 1

定义宏 WITH_STM32_G2D 或宏 WITH_PXP_G2D 后,AWTK 会自动定义宏 WITH_G2D 启用硬件加速,用户无需重复定义。

# 12.15 控件模块

AWTK 提供了丰富的内置控件,用户可以通过组合这些控件快速开发出复杂的 GUI 界面,这些控件分为两类:默认控件和扩展控件,它们的介绍详见下文。

# 12.15.1 默认控件模块

AWTK 的默认控件都放在 awtk/src/widgets 目录下,其中包括按钮(button)、编辑器(edit)、静态文本(label)等常用控件。AWTK 初始化时,会调用 tk_widgets_init 函数注册这些默认控件(将这些控件的构造函数添加到控件工厂管理器中)。

需要注意的是,启用 AWTK 的极简模式,即定义宏 AWTK_LITE 后,会将部分默认控件裁剪掉,被裁剪的控件较多,此处不逐一列出,具体详见 awtk/src/widgets/widgets.c 文件中的 tk_widgets_init 函数。

/**
 * 如果启用 AWTK 的极简模式,请定义本宏
 *
 * > 备注:启用该模式后,有以下限制:
 *  1.不支持输入法。
 *  2.不支持控件布局。
 *  3.不支持剪切板。
 *  4.不支持扩展控件。
 *  5.不支持圆角矩形。
 *  6.不支持窗口动画。
 *  7.不支持控件动画。
 *  8.不支持对话框高亮策略。
 *  9.不支持标准的 UNICODE 换行。
 *  10.不支持 fscript 脚本引擎。
 *  11.不支持图片缩放、旋转、平铺和九宫格显示功能。
 *  12.不支持离线画布。
 */
#define AWTK_LITE 1

# 12.15.2 扩展控件模块

AWTK 的扩展控件都放在 awtk/src/ext_widgets 目录下,其中包括多行编辑器(mledit)、表盘(gauge)、环形进度条(progress_circle)等复杂控件。AWTK 初始化时,会调用 tk_ext_widgets_init 函数注册这些扩展控件,具体流程详见本文第一章

由于扩展控件通常比较复杂,所以使用时请注意以下三点:

  1. 部分扩展控件不适合在低端平台使用。
  2. 部分扩展控件需要矢量画布 vgcanvas 的支持。
  3. 部分扩展控件需要与控件动画效果配合使用。

在低端平台上,除了启用默认控件模块中提到的极简模式时,会裁剪掉扩展控件,AWTK 还另外提供了下面的宏来控制是否支持扩展控件,如果不使用扩展控件,请定义下面的宏:

#define WITHOUT_EXT_WIDGETS 1

此外,针对扩展控件在低端平台的使用情况,我们做了以下测试:

  • 测试平台:STM32f103ze。
  • RAM:64 KB。
  • ROM:512 KB

由于 STM32f103ze 平台的内存不足以提供一屏的 LCD 的 Framebuffer,此处采用片段式 Framebuffer 方案来测试(该方案不支持矢量画布 vgcanvas)并且开启控件动画效果,由于如果控件刷新面积很大,会导致刷新次数变多和刷新效率减低,影响实际的效果,所以该测试不考虑实际效果,只确定扩展控件是否能正常工作,测试结果详见下表。

由于在低端平台上使用扩展控件需要注意比较多的问题,建议先了解该扩展控件的代码原理才使用,否则容易出现奇怪的问题,所以低端平台慎用扩展控件。

扩展控件名称 是否正常工作 注意事项
canvas_widget 需要注意平台是否支持 vgcanvas ,否则调用 vgcanvas 对应的接口会失效。
color_picker 需要注意平台的内存是否足够,color_component 控件需要开辟一块和该控件宽高一样的32位色的图片内存。
combo_box_ex
features
file_browser 需要文件系统支持。
gif_image 因为 imagegen 工具暂时不支持生成 gif 格式的资源。
gauge 因为需要 vgcanvas 支持。
image_animation
image_value
keyboard 需要注意内存是否足够,因为软键盘会创建大量的 button 控件。
mledit
mutable_image 但不支持旋转和缩放,因为它们需要 vgcanvas 支持。
progress_circle 因为需要 vgcanvas 支持。
rich_text 但是需要 widget 动画效果配合。
scroll_label 但是需要 widget 动画效果配合。
scroll_view 但是需要 widget 动画效果配合。
slide_menu 但是需要 widget 动画效果配合。
slide_view 但是需要 widget 动画效果配合, slide_indicator 控件只使用 stroke_rect 和 fill_rect 效果,不能使用画圆形的效果,因为画圆需要 vgcanvas 支持。
svg_image 因为需要 vgcanvas 支持。
switch 但是没有圆角的效果,因为圆角效果需要 vgcanvas 支持。
text_selector 但是需要 widget 动画效果配合。
time_clock 因为需要 vgcanvas 支持。

在低端平台中,通常会禁用控件动画和扩展控件,所以需要手动把取消宏 WITHOUT_WIDGET_ANIMATORS 和宏 WITHOUT_EXT_WIDGETS 宏定义才能正常使用。