提示:本博客作为学习笔记,有错误的地方希望指正
一、Roller 简介
1.1概述 Overview
滚动允许你简单地选择一个选项从更多滚动。
1.2部分和风格 Parts and Styles
• LV_PART_MAIN 使用所有典型背景属性和文本样式属性的滚筒的背景。Style_text_line_space调整选
项之间的空格。当滚轮滚动时,它不会在某个选项上完全停止,它会自动滚动到最近的有效选项,以
anim_time毫秒为单位,因为它在样式中指定了。
• LV_PART_SELECTED中间选择的选项。除了典型的背景属性外,它还使用文本样式属性来改变选定
区域中的文本的外观。
1.3使用 Usage
1.3.1设置选项 Set options
这些选项作为带有lv_roller_set_options(Roller, options, LV_ROLLER_MODE_NORMAL/INFINITE)的字符串传递给Roller。这些选项应该用\n分隔。例如:“第一\ nSecond \ nThird”。
LV_ROLLER_MODE_INFINITE使滚轮呈圆形。
可以使用lv_roller_set_selected手动选择一个选项(roller, id, LV_ANIM_ON/OFF),其中id是一个选项的索引。
1.3.2得到选中的选项 Get selected option
获取当前选择的选项使用lv_roller_get_selected(roller),它将返回所选选项的索引。
lv_roller_get_selected_str (roller, buf, buf_size)将所选选项的名称复制到buf。.
1.3.3可见的行 Visible rows
可见行数可以通过lv_roller_set_visible_row_count(roller, num)来调整。这个函数计算当前样式的高度。如果字体、行间距、边框宽度等辊子发生变化,则需要再次调用该函数。
1.4事件 Events
• LV_EVENT_VALUE_CHANGED当选择新选项时发送。
1.5按键 Keys
• LV_KEY_RIGHT/DOWN选择下一个选项
• LV_KEY_LEFT/UP选择前面的选项
• LY_KEY_ENTER应用所选选项(发送LV_EVENT_VALUE_CHANGED事件)
二、Roller API
lv_obj_t * lv_roller_create(lv_obj_t * parent); //创建一个滚轮对象
void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_t mode);//设置滚轮上的选项
void lv_roller_set_selected(lv_obj_t * obj, uint16_t sel_opt, lv_anim_enable_t anim); //设置所选选项
void lv_roller_set_visible_row_count(lv_obj_t * obj, uint8_t row_cnt); //设置高度以显示给定的行数(选项)
uint16_t lv_roller_get_selected(const lv_obj_t * obj); //获取所选选项的索引
void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); //获取当前选择的选项作为一个字符串。
const char * lv_roller_get_options(const lv_obj_t * obj); //获得一个滚轮的选项
uint16_t lv_roller_get_option_cnt(const lv_obj_t * obj); //获取选项的总数
三、示例
3.1Roller 基本显示
/*************************************************
* 函数名称 : roller_event_handler
* 参 数 : e
* 函数功能 : 滚动回调显示
*************************************************/
static void roller_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); //获取回调值
lv_obj_t * obj = lv_event_get_target(e); //获取对象
if(code == LV_EVENT_VALUE_CHANGED){ //判断当前事件
char buf[32];
lv_roller_get_selected_str(obj,buf,sizeof(buf)); //获取选项的str
LV_LOG_USER("Selected ID:%d Month:%s\n",lv_roller_get_selected(obj),buf);
}
}
/*************************************************
* 函数名称 : roller_show1_event_hander
* 参 数 : 无
* 函数功能 : 滚动回调显示
*************************************************/
void roller_show_1()
{
lv_obj_t * roller1 = lv_roller_create(lv_scr_act()); //创建滚动对象
lv_roller_set_options( roller1, //设置滚动轮上的选项
"January\n"
"February\n"
"March\n"
"April\n"
"May\n"
"June\n"
"July\n"
"August\n"
"September\n"
"October\n"
"November\n"
"December",
LV_ROLLER_MODE_INFINITE);
lv_roller_set_visible_row_count(roller1,4); //设置显示的高度
lv_obj_center(roller1); //居中显示
lv_obj_add_event_cb(roller1,roller_event_handler,LV_EVENT_ALL,NULL); //添加回调函数
}
3.2Roller的字体显示位置
/*************************************************
* 函数名称 : roller_show2_event_hander
* 参 数 : e
* 函数功能 : 滚动回调显示
*************************************************/
static void roller_show2_event_hander(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); //获取对象值
lv_obj_t * obj = lv_event_get_target(e); //获取事件
if(code == LV_EVENT_CHILD_CHANGED){ //判断事件
char buf[32];
lv_roller_get_selected_str(obj,buf,sizeof(buf));//设置选项值
LV_LOG_USER("Selected value:%s",buf);
}
}
/*************************************************
* 函数名称 : roller_show_2
* 参 数 : 无
* 函数功能 : 滚动显示
*************************************************/
void roller_show_2()
{
static lv_style_t style_sel; //创建样式
lv_style_init(&style_sel); //初始化样式
lv_style_set_text_font(&style_sel,&lv_font_montserrat_16); //初始字体
const char * opts = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10"; //初始化选项
lv_obj_t * roller; //初始化滚动对象
roller = lv_roller_create(lv_scr_act()); //创建滚动对象
lv_roller_set_options(roller,opts,LV_ROLLER_MODE_NORMAL); //设置选项
lv_roller_set_visible_row_count(roller,2); //设置滚动的宽度
lv_obj_set_width(roller,100); //设置对象的宽度
lv_obj_add_style(roller,&style_sel,LV_PART_SELECTED); //设置宽度
lv_obj_set_style_text_align(roller,LV_TEXT_ALIGN_LEFT,0); //设置字体居中
lv_obj_align(roller,LV_ALIGN_LEFT_MID,10,0); //设置位置
lv_obj_add_event_cb(roller,roller_show2_event_hander,LV_EVENT_ALL,NULL);//添加回调
lv_roller_set_selected(roller,2,LV_ANIM_OFF); //设置初始选项
roller = lv_roller_create(lv_scr_act()); //创建对象
lv_roller_set_options(roller,opts,LV_ROLLER_MODE_NORMAL); //初始化选项
lv_roller_set_visible_row_count(roller,3); //设置宽度距离
lv_obj_add_style(roller,&style_sel,LV_PART_SELECTED); //添加样式
lv_obj_align(roller,LV_ALIGN_CENTER,0,0); //设置位置
lv_obj_add_event_cb(roller,roller_show2_event_hander,LV_EVENT_ALL,NULL);//设置回调
lv_roller_set_selected(roller,5,LV_ANIM_OFF); //设置初始化选择
roller = lv_roller_create(lv_scr_act()); //创建对象
lv_roller_set_options(roller,opts,LV_ROLLER_MODE_NORMAL); //初始化选项
lv_roller_set_visible_row_count(roller,4); //设置宽度距离
lv_obj_set_width(roller,80); //设置对象的宽度
lv_obj_add_style(roller,&style_sel,LV_PART_SELECTED); //添加样式
lv_obj_set_style_text_align(roller,LV_TEXT_ALIGN_RIGHT,0); //设置样式字体居中
lv_obj_align(roller,LV_ALIGN_RIGHT_MID,-10,0); //设置位置
lv_obj_add_event_cb(roller,roller_show2_event_hander,LV_EVENT_ALL,NULL);//添加回调
lv_roller_set_selected(roller,8,LV_ANIM_OFF); //设置初始化选择值
}
3.3使用蒙版功能实现滑动被选项的放大
值得注意的是这里使用了之前没有见过的东西,蒙版,字体重绘之前在进度条中有了解到,下面是对于蒙版的几个API的参数如下
/**
* 初始化一个淡出遮罩。
* @param初始化lv_draw_mask_param_t的参数指针
* @param坐标的区域影响(绝对坐标)
* @param opa_top顶部的不透明度
* @param y_top在哪个坐标开始改变透明度为' opa_bottom '
* @param opa_bottom底部的不透明度
* @param y_bottom where coordinate reach ' opa_bottom '。
*/
Void lv_draw_mask_fade_init(lv_draw_mask_fade_param_t * param, const lv_area_t * cods,lv_opa_t opa_top,lv_coord_t y_top,lv_opa_t opa_bottom, lv_coord_t y_bottom)
/**
* 添加一个绘制蒙版。在它之后绘制的所有东西(直到移除蒙版)都会受到蒙版的影响。
* 初始化掩码参数。只保存指针。
* @param custom_id一个自定义指针来识别掩码。用于“lv_draw_mask_remove_custom”。
* @返回一个整数,掩码的ID。可以在' lv_draw_mask_remove_id '中使用。
*/
Int16_t lv_draw_mask_add(void * param, void * custom_id)
例子Code
/*************************************************
* 函数名称 : mask_event_cb
* 参 数 : e
* 函数功能 : 滚动回调显示
*************************************************/
static void mask_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); //获取事件
lv_obj_t * obj = lv_event_get_target(e); //获取当前事件
static int16_t mask_top_id = -1; //定义顶部遮罩
static int16_t mask_bottom_id = -1; //定义底部遮罩
if (code == LV_EVENT_COVER_CHECK) { //事件覆盖检查
lv_event_set_cover_res(e, LV_COVER_RES_MASKED); //设置封面检查结果
} else if (code == LV_EVENT_DRAW_MAIN_BEGIN) { //执行主绘图
/* add mask */
const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); //获取对象字体
lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN);//获取对象字体行间距
lv_coord_t font_h = lv_font_get_line_height(font); //获取行高
lv_area_t roller_coords; //设置绘制区域变量
lv_obj_get_coords(obj, &roller_coords); //复制一个对象的坐标到一个区域
lv_area_t rect_area; //设置绘制区域变量
rect_area.x1 = roller_coords.x1; //获取到x1的值
rect_area.x2 = roller_coords.x2; //获取到x2的值
rect_area.y1 = roller_coords.y1; //获取到y1的值
rect_area.y2 = roller_coords.y1 + (lv_obj_get_height(obj) - font_h - line_space) / 2; //获取到y2的值
lv_draw_mask_fade_param_t * fade_mask_top = lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t)); //绘制蒙版褪色参数 顶部
lv_draw_mask_fade_init(fade_mask_top, &rect_area, LV_OPA_TRANSP, rect_area.y1, LV_OPA_COVER, rect_area.y2); //初始化一个淡出遮罩。
mask_top_id = lv_draw_mask_add(fade_mask_top, NULL); //添加一个顶部绘制蒙版
rect_area.y1 = rect_area.y2 + font_h + line_space - 1; //获取y1坐标
rect_area.y2 = roller_coords.y2; //获取y2坐标
lv_draw_mask_fade_param_t * fade_mask_bottom =lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t));//绘制蒙版褪色参数 底部
lv_draw_mask_fade_init(fade_mask_bottom, &rect_area, LV_OPA_COVER, rect_area.y1, LV_OPA_TRANSP, rect_area.y2); //初始化一个淡出遮罩。
mask_bottom_id = lv_draw_mask_add(fade_mask_bottom, NULL); //添加一个顶部绘制蒙版
} else if (code == LV_EVENT_DRAW_POST_END) { //完成post绘制阶段(当所有子元素都绘制时)
lv_draw_mask_fade_param_t * fade_mask_top = lv_draw_mask_remove_id(mask_top_id); //移除蒙版
lv_draw_mask_fade_param_t * fade_mask_bottom = lv_draw_mask_remove_id(mask_bottom_id); //移除蒙版
lv_draw_mask_free_param(fade_mask_top); //释放参数中的数据。
lv_draw_mask_free_param(fade_mask_bottom); //释放参数中的数据。
lv_mem_buf_release(fade_mask_top); //手动释放内存
lv_mem_buf_release(fade_mask_bottom); //手动释放内存
mask_top_id = -1;
mask_bottom_id = -1;
}
}
/*************************************************
* 函数名称 : roller_show_3
* 参 数 : e
* 函数功能 : 滚动回调显示
*************************************************/
void roller_show_3(void)
{
static lv_style_t style; //创建样式变量
lv_style_init(&style); //初始化样式
lv_style_set_bg_color(&style, lv_color_black()); //设置背景颜色
lv_style_set_text_color(&style, lv_color_white()); //设置字体颜色
lv_style_set_border_width(&style, 0); //设置边框宽度
lv_style_set_pad_all(&style, 0); //设置边距
lv_obj_add_style(lv_scr_act(), &style, 0); //添加样式
lv_obj_t *roller1 = lv_roller_create(lv_scr_act()); //创建roller对象
lv_obj_add_style(roller1, &style, 0); //添加样式
lv_obj_set_style_bg_opa(roller1, LV_OPA_TRANSP, LV_PART_SELECTED); //设置对象的透明度
#if LV_FONT_MONTSERRAT_22
lv_obj_set_style_text_font(roller1, &lv_font_montserrat_22, LV_PART_SELECTED); //设置对象字体
#endif
lv_roller_set_options(roller1, //设置对象选项
"January\n"
"February\n"
"March\n"
"April\n"
"May\n"
"June\n"
"July\n"
"August\n"
"September\n"
"October\n"
"November\n"
"December",
LV_ROLLER_MODE_NORMAL);
lv_obj_center(roller1); //居中对象
lv_roller_set_visible_row_count(roller1, 3); //设置对象间距
lv_obj_add_event_cb(roller1, mask_event_cb, LV_EVENT_ALL, NULL); //设置回调
}
四、初识Drawing
4.1Drawing 概述
使用LVGL,你不需要手动绘制任何东西。只要创建对象(如按钮、标签、弧线等),移动并改变它们,
LVGL就会刷新并重新绘制所需的内容。
但是,如果你对绘制在LVGL中是如何进行的有一个基本的了解,那么你便能够更好地添加自定义,从而更容易地找到漏洞或者只是出于好奇。
基本的概念是不要直接在屏幕上绘制,而是先在内部绘制缓冲区上绘制。当绘图(渲染)就绪时,将缓冲区复制到屏幕上。
绘制缓冲区可以小于屏幕的大小。LVGL将简单地渲染适合给定绘制缓冲区的“贴图”。
与直接绘制到屏幕上相比,这种方法有两个主要优势:
- 它避免了在绘制UI层时闪烁。例如,如果将LVGL直接绘制到显示器中,当绘制背景+按钮+文本时,
每个“阶段”都将在短时间内可见。. - 在内部RAM中修改缓冲区,最后只写一个像素比在每个像素访问上直接读/写显示更快。(例如通过带
有SPI接口的显示控制器)。.
注意,这个概念不同于“传统”的双缓冲区,其中有两个屏幕大小的帧缓冲区:一个保存当前图像显示在显示器上,渲染发生在另一个(非活动的)帧缓冲区,当渲染完成时,它们被交换。主要的区别是,使用LVGL你不需要存储2帧缓冲区(通常需要外部RAM),但只需要更小的绘制缓冲区(s),可以很容易地放入内部RAM。
4.2筛网刷新机理 Mechanism of screen refreshing
一定要先熟悉LVGL的缓冲模式。
LVGL按以下步骤刷新屏幕:
- UI上发生了一些需要重新绘制的事情。例如,一个按钮被按下,一个图表被改变或一个动画发生,等等。
- LVGL将更改对象的新旧区域保存到一个缓冲区中,称为无效区域缓冲区。为了优化,在某些情况下,对象不被添加到缓冲区:
不添加隐藏对象。
完全脱离其父级的对象不会被添加
部分超出父级的区域被裁剪到父级的区域。
不添加其他画面上的对象。 - 在每个LV_DISP_DEF_REFR_PERIOD(set in lv_conf.h) 中发生以下情况:
•LVGL 检查无效区域并连接相邻或相交的区域
获取第一个连接区域,如果它小于绘制缓冲区,则只需将该区域的内容渲染到绘制缓冲区中。如果
区域不适合缓冲区,画一样多的行可能将绘图缓冲器。渲染区域后,flush_cb从显示驱动程序调用以刷新显示。如果该区域大于缓冲区,也渲染其余部分。对所有连接的区域执行相同操作。当一个区域被重绘时,库搜索覆盖该区域的最上面的对象,并从该对象开始绘制。例如,如果一个按钮的标签发生了变化,库会看到在文本下绘制按钮就足够了,并且不需要在按钮下绘制屏幕。
关于绘图机制的缓冲模式之间的区别如下: - One buffer - LVGL在开始重绘下一部分之前需要等待lv_disp_flush_ready()(从 调用flush_cb)。
- Two buffers -当第一个缓冲区发送到第二个缓冲区时,LVGL 可以立即绘制到第二个缓冲区,flush_cb因为刷新应该由 DMA(或类似硬件)在后台完成.
- Double buffering - flush_cb应该只交换帧缓冲区的地址.
4.3遮罩 Masking
遮罩是 LVGL 绘图引擎的基本概念。要使用 LVGL,不需要了解此处描述的机制,您可能会发现了解绘图在幕后如何工作会很有趣。如果您想自定义绘图,了解蒙版会派上用场。要学习遮罩,让我们先学习绘图的步骤。LVGL 执行以下步骤来渲染任何形状、图像或文本。它可以被认为是一个绘图管道。
- Prepare the draw descriptors根据对象的样式(例如lv_draw_rect_dsc_t)创建绘制描述符。它告诉绘图的参数,例如颜色、宽度、不透明度、字体、半径等.
- Call the draw function 使用绘图描述符和一些其他参数(例如lv_draw_rect())调用绘图函数。它将原始形状渲染到当前绘制缓冲区.
- Create masks如果形状非常简单且不需要遮罩,请转到 #5。否则创建所需的蒙版(例如圆角矩形蒙版)
- Calculate all the added mask.它将 0…255 个值创建到具有创建的掩码的“形状”的掩码缓冲区中。例如,在根据掩码参数的“线掩码”的情况下,保持缓冲区的一侧原样(默认为 255)并将其余部分设置为 0 以指示应删除该侧.
- Blend a color or image在混合蒙版(使一些像素透明或不透明)、混合模式(加法、减法等)、不透明度被处理.
LVGL 具有以下可以实时计算和应用的内置掩码类型:
• LV_DRAW_MASK_TYPE_LINE 从一行中删除一侧(顶部、底部、左侧或右侧)。lv_draw_line使用其中的 4 个。本质上,每条(倾斜)线都通过形成一个矩形以 4 个线掩模为界.
• LV_DRAW_MASK_TYPE_RADIUS删除具有半径的矩形的内部或外部部分。它还用于通过将半径设置为大值 ( LV_RADIUS_CIRCLE)来创建圆
• LV_DRAW_MASK_TYPE_ANGLE 删除一个圆形扇区。它用于lv_draw_arc删除“空”扇区
• LV_DRAW_MASK_TYPE_FADE创建垂直淡入淡出(更改不透明度)
• LV_DRAW_MASK_TYPE_MAP掩码存储在一个数组中并应用必要的部分掩码
用于创建几乎所有基本图元:
• letters从字母创建一个蒙版,并根据蒙版用字母的颜色绘制一个矩形
• line由 4 个“线遮罩”创建,用于遮住线的左、右、上和下部分,以获得完美垂直的线尾
• rounded rectangle 实时创建遮罩以向角添加半径
• clip corner 为了剪裁到圆角上的溢出内容(通常是子类们),还应用了圆角矩形蒙版.
• rectangle border与圆角矩形相同,但内部部分也被屏蔽了
• arc drawing 圆形边框,但也应用了弧形遮罩.
• ARGB images将 alpha 通道分离成一个蒙版,并将图像绘制为普通的 RGB 图像.
4.4绘画钩子 Hook drawing
尽管小部件可以通过样式很好地自定义,但在某些情况下可能需要真正自定义。为了确保高度的灵活性,LVGL 在绘制过程中发送了很多事件,并带有告诉 LVGL 将要绘制什么的参数。可以修改这些参数的某些字段以绘制其他内容,或者可以手动添加任何自定义绘图。
一个很好的用例是按钮矩阵小部件。默认情况下,它的按钮可以在不同状态下设置样式,但您不能一个一个地设置按钮样式。然而,一个事件会被发送到永远按钮,你可以告诉 LVGL 例如在特定按钮上使用不同的颜色或在一些按钮上手动绘制图像。
下面对每个相关事件进行详细说明。
4.4.1主绘画 Main drawing
这些事件与对象的实际绘制有关。例如,按钮、文本等的绘制发生在这里。
lv_event_get_clip_area(event)可用于获取当前剪辑区域。绘制函数中需要剪辑区域,以使它们仅在有限的区域上绘制。
LV_EVENT_DRAW_MAIN_BEGIN
在开始绘制对象之前发送。这是手动添加蒙版的好地方。例如,添加一个“删除”对象右侧的线蒙版。
LV_EVENT_DRAW_MAIN
对象的实际绘制发生在此事件中。例如,这里绘制了一个按钮的矩形。首先,调用小部件的内部事件来执行绘图,然后您可以在它们之上绘制任何内容。例如,您可以添加自定义文本或图像。
LV_EVENT_DRAW_MAIN_END
在主绘图完成时调用。你也可以在这里画任何东西,它也是删除LV_EVENT_DRAW_MAIN_BEGIN.
4.4.2发布绘制 Post drawing
当绘制对象的所有子项时,会调用绘制后事件。例如,LVGL 使用后期绘制阶段来绘制滚动条,因为它
们应该位于所有子项之上。
lv_event_get_clip_area(event) 可用于获取当前剪辑区域。
LV_EVENT_DRAW_POST_BEGIN
在开始绘制后阶段之前发送。也可以在此处添加遮罩以遮蔽后期绘制的内容。
LV_EVENT_DRAW_POST
实际绘图应该发生在这里。
LV_EVENT_DRAW_POST_END
当后期绘制完成时调用。如果口罩没有在里面取下,LV_EVENT_DRAW_MAIN_END则应在此处取下。
4.4.3部件绘制 Part drawing
当 LVGL 绘制对象的一部分(例如滑块的指示器、表格的单元格或按钮矩阵的按钮)时,它会在绘
制该部分之前和之后使用绘图的某些上下文发送事件。它允许使用蒙版、额外绘图或更改 LVGL 计划用
于绘图的参数在非常低的级别上更改零件。
在这些事件中,使用lv_obj_draw_part_t结构来描述绘图的上下文。并非为每个部件和小部件设置所
有字段。要查看为小部件设置了哪些字段,请参阅小部件的文档。
lv_obj_draw_part_t 具有以下字段:
Const lv_area_t * clip_area; //当前剪辑区域,如果你需要在事件中绘制一些东西
uint32_t part; //发送事件的当前部分
uint32_t id; //部件的索引。例如,按钮矩阵或表格单元格索引上的按钮索引。
//绘制描述符,仅当相关时设置
lv_draw_rect_dsc_t * rect_dsc; //一个绘图描述符,可以修改LVGL将绘制的内容。仅为矩形部分设置
lv_draw_label_dsc_t * label_dsc;//一个绘图描述符,可以修改LVGL将绘制的内容。仅为类似文本的部分设置
lv_draw_line_dsc_t * line_dsc; //一个绘图描述符,可以修改LVGL将绘制的内容。仅为线形零件设置
lv_draw_img_dsc_t * img_dsc; //一个绘图描述符,可以修改LVGL将绘制的内容。仅为类似于图像的部分设置
lv_draw_arc_dsc_t * arc_dsc; //一个绘图描述符,可以修改LVGL将绘制的内容。只设置为弧形部分
//其他的目的
lv_area_t * draw_area; //被绘制部分的面积
Const lv_point_t * p1; //绘图时计算的一个点。例如图表上的一点或圆弧的中心。
Const lv_point_t * p2; //绘图时计算的一个点。例如,图表的一个点。
char text[[16]; //绘图时计算的文本。可以修改。例如,在图表轴上标出标签。
lv_coord_t radius; //例如,一个圆弧的半径(不是角的半径)。
int32_t value; //绘图时计算的值。例:图表的划线值。
Const void * sub_part_ptr; //一个指针标识部分中的某物。如图表系列。
lv_event_get_draw_part_dsc(event)可用于获取指向lv_obj_draw_part_t.
LV_EVENT_DRAW_PART_BEGIN
开始绘制零件。这是修改绘制描述符(例如rect_dsc)或添加蒙版的好地方。
LV_EVENT_DRAW_PART_END
完成零件的绘制。这是在零件上绘制额外内容的好地方,或删除添加到LV_EVENT_DRAW_PART_BEGIN.
4.4.4其他 Others
LV_EVENT_COVER_CHECK
此事件用于检查对象是否完全覆盖一个区域。
lv_event_get_cover_area(event)返回一个指向要检查的区域的指针,可用于设置以下结果之一:
lv_event_set_cover_res(event, res)
• LV_COVER_RES_COVER 这些区域被物体完全覆盖
• LV_COVER_RES_NOT_COVER该区域未被对象覆盖
• LV_COVER_RES_MASKED物体上有一个面具,所以它不能掩盖该区域
以下是物体不能完全覆盖区域的一些情况:
• 它根本不完全在那个区域
• 它有半径
• 它没有 100% 的背景不透明度
• 这是一个 ARGB 或色度键控图像
• 它没有正常的混合模式。在这种情况下,LVGL 需要知道对象下的颜色才能正确混合
• 这是一个文本等
简而言之,如果由于某种原因,对象下方的区域是可见的,而不是它不覆盖该区域。在发送此事件之前,LVGL 检查至少小部件的坐标是否完全覆盖该区域。如果不是,则不会调用该事件。您只需要检查您添加的图纸。小部件已知的现有属性在小部件的内部事件中处理。例如,如果一个小部件具有 > 0 半径,它可能不会覆盖一个区域,但radius只有当您修改它并且小部件无法知道它时,您才需要处理。
LV_EVENT_REFR_EXT_DRAW_SIZE
如果您需要在小部件之外绘制,LVGL 需要了解它以提供额外的绘制空间。假设您创建了一个事件,将滑块的当前值写入其旋钮上方。在这种情况下,LVGL 需要知道滑块的绘制区域应该与文本所需的大小相
同。
您可以使用 简单设置所需的绘图区域。lv_event_set_ext_draw_size(e, size)