说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
内容来源:
官方的手册(免费获取)Pxx=该手册的对应页码xx
github-awtk
<<<学习篇2:awtk-examples工程搭建并运行示例 学习篇4: HelloWorld.Xml-Demo修改-自定义事件>>>
一、程序功能:
两个文本框:
①同步编辑框内容,初始内容:“hello world”
②同步按钮数值。
一个编辑框:编辑文本(可软键盘也可键盘输入)
两个按钮:分别用于递增和递减数字。
二、流程图:如下图所示:
工程文件组成:主函数文件,业务逻辑文件,UI界面文件,样式文件,脚本文件,awtk工程。
关键函数流程图:
根据HelloWorld.Xml-Demo示例,简单认识一下关于AWTK的相关知识点。
文件位置:/home/xsndz/awtk/awtk-examples/test/src/app_main.c
(删了其他情况的代码)
app_main.c
是main
函数入口,这个文件用户可以直接套用到自己的项目中,通常不需要修改,主要完成设置屏幕大小、资源的初始化以及 AWTK 框架的加载等。
#include "awtk.h" //该头文件包含所需其他头文件
#include "../res/assets.inc" //包含assets.inc文件
extern ret_t application_init(void); //申明外部变量
int main(void) {
int lcd_w = 800;
int lcd_h = 480;
char res_root[MAX_PATH + 1];
char app_root[MAX_PATH + 1];
path_app_root(app_root);
memset(res_root, 0x00, sizeof(res_root));
path_build(res_root, MAX_PATH, app_root, "res", NULL); //设置资源根目录为res,与上面assets.inc文件的上级目录相同
tk_init(lcd_w, lcd_h, APP_SIMULATOR, NULL, res_root);
/* 初始化资源 */
assets_init();
/* 初始化扩展控件 */
tk_ext_widgets_init();
/* 打开主屏幕 */
application_init();
/* 进入awtk事件循环 */
tk_run();
return 0;
}
文件位置:/home/xsndz/awtk/awtk-examples/test/src/window_main.c
#include "awtk.h"
extern ret_t application_init(void);
/**
* Label文本的数值 + offset
*/
static ret_t label_add(widget_t* label, int32_t offset) {
if (label) {
int32_t val = 0;
if (wstr_to_int(&(label->text), &val) == RET_OK) {
char text[32];
val += offset;
val = tk_max(-200, tk_min(val, 200));
tk_snprintf(text, sizeof(text), "%d", val);
widget_set_text_utf8(label, text);
return RET_OK;
}
}
return RET_FAIL;
}
/**
* 递增按钮事件
*/
static ret_t on_inc_click(void* ctx, event_t* e) {
widget_t* win = WIDGET(ctx);
widget_t* label = widget_lookup(win, "label_4_btn", TRUE);
label_add(label, 1);
return RET_OK;
}
/**
* 递减按钮事件
*/
static ret_t on_dec_click(void* ctx, event_t* e) {
widget_t* win = WIDGET(ctx);
widget_t* label = widget_lookup(win, "label_4_btn", TRUE);
label_add(label, -1);
return RET_OK;
}
/**
* 正在编辑事件
*/
static ret_t on_changing(void* ctx, event_t* evt) {
widget_t* target = WIDGET(evt->target);
widget_t* win = WIDGET(ctx);
widget_t* label = widget_lookup(win, "label_4_edit", TRUE);
widget_set_text(label, target->text.str);
return RET_OK;
}
/**
* 子控件初始化(主要是设置click回调、初始显示信息)
*/
static ret_t init_widget(void* ctx, const void* iter) {
(void)ctx;
widget_t* widget = WIDGET(iter);
widget_t* win = widget_get_window(widget);
if (widget->name != NULL) {
const char* name = widget->name;
if (tk_str_eq(name, "edit")) {
widget_on(widget, EVT_VALUE_CHANGING, on_changing, win); //注册EVT_VALUE_CHANGING文本正在改变事件(编辑的同时文本框内容随之变化),并注册回调函数:on_changing
} else if (tk_str_eq(name, "dec_btn")) {
widget_on(widget, EVT_CLICK, on_dec_click, win); //注册EVT_CLICK点击事件,并注册回调函数:on_dec_click
} else if (tk_str_eq(name, "inc_btn")) {
widget_on(widget, EVT_CLICK, on_inc_click, win); //注册EVT_CLICK点击事件,并注册回调函数:on_inc_click
}
}
return RET_OK;
}
/**
* 初始化窗口上的子控件
*/
static void init_children_widget(widget_t* widget) {
widget_foreach(widget, init_widget, widget);
}
/**
* 初始化
*/
ret_t application_init() {
widget_t* win = window_open("main"); //打开ui文件名(res\assets\default\raw\ui)
if (win) {
init_children_widget(win);
}
return RET_OK;
}
作用:定义界面上有哪些控件,为对应控件设置控制位置,取名等。
文件位置:/home/xsndz/awtk/awtk-examples/test/res/assets/default/raw/ui/main.xml
(main.xml文件)
<window anim_hint="htranslate" >
<image draw_type="icon" image="awtk_logo" x="right:10" y="10" w="100" h="26"/>
<label name="label_4_edit" x="c" y="20%" w="30%" h="40" text="hello world" />
<edit name="edit" x="c" y="40%" w="60%" h="40" text="hello world" input_type="email" />
<button name="dec_btn" x="20%" y="60%" w="20%" h="40" text="dec"/>
<label name="label_4_btn" x="c" y="60%" w="20%" h="40" text="88"/>
<button name="inc_btn" x="60%" y="60%" w="20%" h="40" text="inc"/>
window>
作用:
①可改变控件的背景颜色、边框颜色、字体颜色、字体、字体大小、背景图片、背景图片的显示方式和图标等属性.
②提供了一些主题重用的机制,让主题文件的开发和维护变得容易.
文件位置:/home/xsndz/awtk/awtk-examples/test/res/assets/default/raw/style/default.xml
(default.xml文件)
<window>
<style name="default">
"#f0f0f0" />
style>
window>
<button>
<style name="default" border_color="#a0a0a0" text_color="black">
"#f0f0f0" />
"#c0c0c0" x_offset="1" y_offset="1"/>
"#e0e0e0" />
"gray" text_color="#d0d0d0" />
style>
button>
<edit selected_fg_color="#020202" selected_text_color="#010101" selected_bg_color="#b5d7fd">
<style name="default" border_color="#a0a0a0" text_color="black" text_align_h="center">
"#f0f0f0" />
"#f0f0f0" border_color="black"/>
"gray" text_color="#d0d0d0" />
"#f0f0f0" text_color="red" />
"#f0f0f0" text_color="#a0a0a0" />
"#f0f0f0" text_color="#a0a0a0" border_color="black"/>
style>
edit>
<label>
<style name="default">
"black" />
style>
label>
主题属性设置:三种方式(P30),优先级从低到高,重复定义后者覆盖前者。
【可观察上面单行编辑器控件,三种方式均用到】
使用主题样式方法:①UI文件:style
属性,②C代码:widget_use_style()
函数
主题样式文件:①theme属性,②name属性。(建议窗口主题文件名和UI文件名相同,P33)
inline style 动态修改控件样式:P34
主题属性表 | 控件状态表 | ||||
---|---|---|---|---|---|
bg_color | 背景颜色 | font_name | 字体名称 | normal | 正常状态 |
g_color | 前景颜色 | font_size | 字体大小 | pressed | 指针按下状态 |
mask_color | 蒙版颜色 | text_align_h | 文本水平对齐的方式 | over | 指针悬浮状态 |
text_color | 文本颜色 | text_align_v | 文本水平对齐的方式 | disable | 禁用状态 |
tips_text_color | 提示文本颜色 | border_width | 边框线宽 | focused | 聚焦状态 |
border_color | 边框颜色 | border | 边框类型 | checked | 勾选状态 |
bg_image | 背景图片的名称 | bg_image_draw_type | 背景图片的显示方式 | unchecked | 没勾选状态 |
icon | 图标的名称 | spacer | 间距 | empty | 编辑器无内容状态 |
fg_image | 前景图片的名称 | margin | 边距 | empty_focus | 编辑器无内容同时聚焦的状态 |
fg_image_draw_type | 前景图片的显示方式 | margin_left | 左边距 | error | 输入错误状态 |
icon_at | 图标的位置 | margin_right | 右边距 | selected | 选中状态 |
active_icon | active 图标的名称 | margin_top | 顶边距 | normal_of_checked | 正常状态(选中项) |
x_offset | x 方向的偏移 | margin_bottom | 底边距 | pressed_of_checked | 指针按下状态(选中项) |
y_offset | y 方向的偏移 | round_radius | 圆角半径 | over_of_checked | 指针悬浮状态(选中项) |
selected_bg_color | 编辑器选中区域的背景颜色 | round_radius_top_left | 左上角圆角半径 | focused_of_checked | 焦点状态(选中项) |
selected_fg_color | 编辑器选中区域的前景颜色 | round_radius_top_right | 右上角圆角半径 | normal_of_active | 正常状态(当前项) |
selected_text_color | 编辑器选中区域的文本颜色 | round_radius_bottom_left | 左下角圆角半径 | pressed_of_active | 指针按下状态(当前项) |
round_radius_bottom_right | 右下角圆角半径 | over_of_active | 指针悬浮状态(当前项) | ||
focused_of_active | 焦点状态(当前项 |
好处:①大小可动态调整,②适应不同屏幕,③界面元素为动态
分类:①对控件自身布局:self_layout
②对子控件布局:children_layout
【均为接口】
①对自身布局:方式一:self_layout指定,方式二:默认参数(x,y,w,h,float)
方式(P37):1.像素,2.百分比,3水平,4.垂直,5.右边,6.底部,7.浮动
②对子控件布局:
使用方法(P37):1.默认,2.水平,3.垂直,4.列表,5.网格,6.浮动,7.高级
目的:①上层无需了解存储方式。②上层无需了解资源格式。③上层无需了解屏幕密度。④对资源进行内存缓存。
初始化过程:
①包含资源数据文件
②将资源添加到资源管理器(分有无文件系统)
使用方法:(P46)
①加载图片②使用UI数据③使用字体④使用主题
资源名称的用法,资源生成及其工具。(看书)
文件位置:/home/xsndz/awtk/awtk-examples/test/res/assets.inc
(删除了需要文件系统部分 )
#include "awtk.h"
#include "base/assets_manager.h"
#include "assets/default/inc/strings/en_US.data" //包含资源数据文件
#include "assets/default/inc/strings/zh_CN.data"
#include "assets/default/inc/styles/keyboard.data"
#include "assets/default/inc/styles/default.data"
#include "assets/default/inc/ui/main.data"
#include "assets/default/inc/ui/kb_ascii.data"
ret_t assets_init(void) { //没有文件系统,调用assets_manager_add()函数
assets_manager_t* rm = assets_manager(); //将资源添加到资源管理器中
assets_manager_add(rm, font_default);
assets_manager_add(rm, image_shift);
assets_manager_add(rm, image_earth);
assets_manager_add(rm, image_awtk_logo);
assets_manager_add(rm, image_backspace);
assets_manager_add(rm, image_shifton);
assets_manager_add(rm, style_keyboard);
assets_manager_add(rm, style_default);
assets_manager_add(rm, ui_main);
assets_manager_add(rm, ui_kb_ascii);
assets_manager_add(rm, strings_en_US);
assets_manager_add(rm, strings_zh_CN);
tk_init_assets();
return RET_OK;
}
事件一般用来响应各种行为(注册回调函数完成某些功能)。
在 AWTK 内部,AWTK 通过函数tk_run
启动的主事件循环不停的捕捉用户触发的事件和事件队列中的事件,然后将它们转换成对应的事件。【看开篇流程图,是位于main函数处】
如:当点击一个button
按钮会触发EVT_POINTER_DOWN
指针按下事件,主事件循环捕获到该消息,最终会将该消息发送给button
控件的button_on_event
函数处理
即:按下按键会触发事件==》 tk_run
捕捉事件 ==》widget_dispatch / main_loop_queue_event
分发事件 ==》调用回调函数(由widget_on
注册)进行事件处理
① widget_dispatch
:只用于分发一个事件,只用于GUI。(多线程使用:idle_queue / timer_queue
)
② main_loop_queue_event
:t用于非 GUI 线程(可用于多线程)增加一个事件,本函数向主循环事件队列中发送一个增加事件请求。
返回值 | |
---|---|
类型 | 功能 |
RET_OK | 可重复执行 |
RET_REMOVE | 只执行一次 |
RET_STOP | 停止后续操作 |
事件类型(P55):较多看书。
定时器回调函数返回值 | |
---|---|
类型 | 功能 |
RET_REPEAT | 可重复执行 |
RET_REMOVE | 只执行一次 |
idle 可以看作是 duration 为 0 的定时器,idle 可以用来实现一些异步处理
①函数:
②回调函数返回值:与上同