awtk开发实践——学习篇3: HelloWorld.Xml-Demo应用示例

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  官方的手册(免费获取)Pxx=该手册的对应页码xx
  github-awtk

<<<学习篇2:awtk-examples工程搭建并运行示例               学习篇4: HelloWorld.Xml-Demo修改-自定义事件>>>

程序功能与流程图

  一、程序功能
    两个文本框
      ①同步编辑框内容,初始内容:“hello world”
      ②同步按钮数值。
    一个编辑框:编辑文本(可软键盘也可键盘输入)
    两个按钮:分别用于递增和递减数字。
  二、流程图:如下图所示:
awtk开发实践——学习篇3: HelloWorld.Xml-Demo应用示例_第1张图片
  工程文件组成:主函数文件,业务逻辑文件,UI界面文件,样式文件,脚本文件,awtk工程。
  关键函数流程图

  根据HelloWorld.Xml-Demo示例,简单认识一下关于AWTK的相关知识点。

主函数

  文件位置/home/xsndz/awtk/awtk-examples/test/src/app_main.c(删了其他情况的代码)
  app_main.cmain函数入口,这个文件用户可以直接套用到自己的项目中,通常不需要修改,主要完成设置屏幕大小、资源的初始化以及 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;
}

关于界面

UI设计界面(手动编写)

  作用:定义界面上有哪些控件,为对应控件设置控制位置,取名等。
  文件位置/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>
    
主题样式(P29)

  作用
    ①可改变控件的背景颜色、边框颜色、字体颜色、字体、字体大小、背景图片、背景图片的显示方式和图标等属性.
    ②提供了一些主题重用的机制,让主题文件的开发和维护变得容易.
  文件位置/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 焦点状态(当前项
布局管理器(P35)

  好处:①大小可动态调整,②适应不同屏幕,③界面元素为动态
  分类:①对控件自身布局: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.高级

资源管理器(P44)

  目的:①上层无需了解存储方式。②上层无需了解资源格式。③上层无需了解屏幕密度。④对资源进行内存缓存

  初始化过程
    ①包含资源数据文件
    ②将资源添加到资源管理器(分有无文件系统)
  使用方法:(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;
}

事件处理(P48)

  事件一般用来响应各种行为(注册回调函数完成某些功能)。
  在 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):较多看书。

定时器(P59)

  ①函数awtk开发实践——学习篇3: HelloWorld.Xml-Demo应用示例_第2张图片
  ②回调函数返回值

定时器回调函数返回值
类型 功能
RET_REPEAT 可重复执行
RET_REMOVE 只执行一次
idle定时器(P61)

  idle 可以看作是 duration 为 0 的定时器,idle 可以用来实现一些异步处理
  ①函数
awtk开发实践——学习篇3: HelloWorld.Xml-Demo应用示例_第3张图片
  ②回调函数返回值:与上同
  

  
  

你可能感兴趣的:(#,awtk,xml,嵌入式)