mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
refactor(event) simplify cover check realted event functions
This commit is contained in:
parent
b7f875aba6
commit
94a47dc6d9
@ -177,37 +177,25 @@ Finish the drawing of a part. It's a good place to draw extra content on the par
|
|||||||
|
|
||||||
This event is used to check whether an object fully covers an area or not.
|
This event is used to check whether an object fully covers an area or not.
|
||||||
|
|
||||||
`lv_event_get_cover_check_info(event)` returns an pointer to an `lv_cover_check_info_t` variable. Its `res` field should be set to the following values considering the `area` field:
|
`lv_event_get_cover_area(event)` returns an pointer to an area to check and `lv_event_set_cover_res(event, res)` can be used to set one of these results:
|
||||||
- `LV_DRAW_RES_COVER` the areas is fully covered by the object
|
- `LV_COVER_RES_COVER` the areas is fully covered by the object
|
||||||
- `LV_DRAW_RES_NOT_COVER` the areas is not covered by the object
|
- `LV_COVER_RES_NOT_COVER` the areas is not covered by the object
|
||||||
- `LV_DRAW_RES_MASKED` there is a mask on the object so it can not covert the area
|
- `LV_COVER_RES_MASKED` there is a mask on the object so it can not covert the area
|
||||||
|
|
||||||
Here are some cases why can't an object fully cover an area:
|
Here are some cases why can't an object fully cover an area:
|
||||||
- It's simply not fully on the that area
|
- It's simply not fully on the that area
|
||||||
- It has radius
|
- It has radius
|
||||||
- It has not 100% background opacity
|
- It has not 100% background opacity
|
||||||
- It's an ARGB or chroma keyed image
|
- It's an ARGB or chroma keyed image
|
||||||
- It's a text
|
|
||||||
- It has not normal blending mode. In this case LVGL needs to know the colors under the object to make the blending properly
|
- It has not normal blending mode. In this case LVGL needs to know the colors under the object to make the blending properly
|
||||||
|
- It's a text, etc
|
||||||
|
|
||||||
In short if for any reason the the area below the object is visible than it doesn't cover that area.
|
In short if for any reason the the area below the object is visible than it doesn't cover that area.
|
||||||
|
|
||||||
Some guideline how to set the `res` field in `lv_cover_check_info_t`:
|
Before sending this event LVGL checks if at least the widget's coordinates fully cover the area or not. If not the event is not called.
|
||||||
- Before sending this event LVGL checks if at least the widget's coordinates fully cover the area or not. If not the event is not called.
|
|
||||||
- You need to check only the drawing you have added. The existing properties known by widget are handled in the widget's internal events.
|
You need to check only the drawing you have added. The existing properties known by widget are handled in the widget's internal events.
|
||||||
E.g. if a widget has > 0 radius it might not cover an area but you need to handle `radius` only if you will modify it and widget can't know about it.
|
E.g. if a widget has > 0 radius it might not cover an area but you need to handle `radius` only if you will modify it and widget can't know about it.
|
||||||
- If `res` is already set to `LV_DRAW_RES_MASKED` do nothing. In this case an other event already set it and it's the "strongest" state that shouldn't be overwritten.
|
|
||||||
- If you added a draw mask on the object set `res` to `LV_DRAW_RES_MASKED`
|
|
||||||
- If there is no draw masks but the object simply not covers the area for any reason set `LV_DRAW_RES_NOT_COVER`
|
|
||||||
- If the area is fully covered by the object leave `res` unchanged.
|
|
||||||
|
|
||||||
In the practice probably you need to set only `LV_DRAW_RES_MASKED`if you added masks in a MAIN or POST draw events because "normal" cover checks are handles by the widgets.
|
|
||||||
|
|
||||||
However, if you really added masks in MAIN or POST draw events you need to handle `LV_EVENT_COVER_CHECK` event and tell LVGL there are masks on this object.
|
|
||||||
|
|
||||||
If masks are added and removed in `LV_EVENT_DRAW_PART_BEGIN/END`, `LV_EVENT_COVER_CHECK` doesn't need to know about it except the masks affects `LV_PART_MAIN`.
|
|
||||||
It's because LVGL checks the main part to decide whether an object covers an area or not.
|
|
||||||
So it doesn't matter e.g. if a tabel's cell is masked because the tables background already covered the area or not.
|
|
||||||
|
|
||||||
#### LV_EVENT_REFR_EXT_DRAW_SIZE
|
#### LV_EVENT_REFR_EXT_DRAW_SIZE
|
||||||
|
|
||||||
|
@ -319,13 +319,25 @@ lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_cover_check_info_t * lv_event_get_cover_check_info(lv_event_t * e)
|
const lv_area_t * lv_event_get_cover_area(lv_event_t * e)
|
||||||
{
|
{
|
||||||
if(e->code == LV_EVENT_COVER_CHECK) {
|
if(e->code == LV_EVENT_COVER_CHECK) {
|
||||||
return lv_event_get_param(e);
|
lv_cover_check_info_t * p = lv_event_get_param(e);
|
||||||
|
return p->area;
|
||||||
|
} else {
|
||||||
|
LV_LOG_WARN("Not interpreted with this event code");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res)
|
||||||
|
{
|
||||||
|
if(e->code == LV_EVENT_COVER_CHECK) {
|
||||||
|
lv_cover_check_info_t * p = lv_event_get_param(e);
|
||||||
|
if(p->res == LV_COVER_RES_MASKED) return; /*Do not overwrite masked result*/
|
||||||
|
if(res == LV_COVER_RES_NOT_COVER) p->res = res;
|
||||||
} else {
|
} else {
|
||||||
LV_LOG_WARN("Not interpreted with this event code");
|
LV_LOG_WARN("Not interpreted with this event code");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,15 +113,12 @@ typedef struct {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not.
|
* Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not.
|
||||||
* `res` should be set like this:
|
* In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check
|
||||||
* - If already set to ::LV_DRAW_RES_MASKED do nothing
|
* and `lv_event_set_cover_res(e, res)` to set the result.
|
||||||
* - If there is a draw mask on the object set to ::LV_DRAW_RES_MASKED
|
|
||||||
* - If there is no draw mask but the object simply not covers the area set ::LV_DRAW_RES_NOT_COVER
|
|
||||||
* - If the area is fully covered by the object leave `res` unchanged.
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lv_draw_res_t res; /**< Set to ::LV_DRAW_RES_NOT_COVER or ::LV_DRAW_RES_MASKED. */
|
lv_cover_res_t res;
|
||||||
const lv_area_t * area; /**< The area to check */
|
const lv_area_t * area;
|
||||||
} lv_cover_check_info_t;
|
} lv_cover_check_info_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@ -290,12 +287,19 @@ lv_point_t * lv_event_get_self_size_info(lv_event_t * e);
|
|||||||
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e);
|
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pointer to an `lv_cover_check_info_t` variable in which the area cover information should be saved.
|
* Get a pointer to an area which should be examined whether the object fully covers it or not.
|
||||||
* Can be used in `LV_EVENT_COVER_CHECK`
|
* Can be used in `LV_EVENT_HIT_TEST`
|
||||||
* @param e pointer to an event
|
* @param e pointer to an event
|
||||||
* @return pointer to `lv_cover_check_info_t` or NULL if called on an unrelated event
|
* @return an area with absolute coordinates to check
|
||||||
*/
|
*/
|
||||||
lv_cover_check_info_t * lv_event_get_cover_check_info(lv_event_t * e);
|
const lv_area_t * lv_event_get_cover_area(lv_event_t * e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the result of cover checking. Can be used in `LV_EVENT_COVER_CHECK`
|
||||||
|
* @param e pointer to an event
|
||||||
|
* @param res an element of ::lv_cover_check_info_t
|
||||||
|
*/
|
||||||
|
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
@ -454,9 +454,9 @@ static void lv_obj_draw(lv_event_t * e)
|
|||||||
lv_obj_t * obj = lv_event_get_target(e);
|
lv_obj_t * obj = lv_event_get_target(e);
|
||||||
if(code == LV_EVENT_COVER_CHECK) {
|
if(code == LV_EVENT_COVER_CHECK) {
|
||||||
lv_cover_check_info_t * info = lv_event_get_param(e);
|
lv_cover_check_info_t * info = lv_event_get_param(e);
|
||||||
if(info->res == LV_DRAW_RES_MASKED) return;
|
if(info->res == LV_COVER_RES_MASKED) return;
|
||||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
||||||
info->res = LV_DRAW_RES_MASKED;
|
info->res = LV_COVER_RES_MASKED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,27 +472,27 @@ static void lv_obj_draw(lv_event_t * e)
|
|||||||
coords.y2 += h;
|
coords.y2 += h;
|
||||||
|
|
||||||
if(_lv_area_is_in(info->area, &coords, r) == false) {
|
if(_lv_area_is_in(info->area, &coords, r) == false) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lv_obj_get_style_bg_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) {
|
if(lv_obj_get_style_bg_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LV_DRAW_COMPLEX
|
#if LV_DRAW_COMPLEX
|
||||||
if(lv_obj_get_style_blend_mode(obj, LV_PART_MAIN) != LV_BLEND_MODE_NORMAL) {
|
if(lv_obj_get_style_blend_mode(obj, LV_PART_MAIN) != LV_BLEND_MODE_NORMAL) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) {
|
if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->res = LV_DRAW_RES_COVER;
|
info->res = LV_COVER_RES_COVER;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(code == LV_EVENT_DRAW_MAIN) {
|
else if(code == LV_EVENT_DRAW_MAIN) {
|
||||||
|
@ -25,12 +25,12 @@ extern "C" {
|
|||||||
|
|
||||||
struct _lv_obj_t;
|
struct _lv_obj_t;
|
||||||
|
|
||||||
/** Design results*/
|
/** Cover check results*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LV_DRAW_RES_COVER, /**< Returned on `LV_DRAW_COVER_CHK` if the areas is fully covered*/
|
LV_COVER_RES_COVER,
|
||||||
LV_DRAW_RES_NOT_COVER, /**< Returned on `LV_DRAW_COVER_CHK` if the areas is not covered*/
|
LV_COVER_RES_NOT_COVER,
|
||||||
LV_DRAW_RES_MASKED, /**< Returned on `LV_DRAW_COVER_CHK` if the areas is masked out*/
|
LV_COVER_RES_MASKED,
|
||||||
}lv_draw_res_t;
|
}lv_cover_res_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -574,10 +574,10 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
|||||||
/*If this object is fully cover the draw area check the children too*/
|
/*If this object is fully cover the draw area check the children too*/
|
||||||
if(_lv_area_is_in(area_p, &obj->coords, 0) && lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == false) {
|
if(_lv_area_is_in(area_p, &obj->coords, 0) && lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == false) {
|
||||||
lv_cover_check_info_t info;
|
lv_cover_check_info_t info;
|
||||||
info.res = LV_DRAW_RES_COVER;
|
info.res = LV_COVER_RES_COVER;
|
||||||
info.area = area_p;
|
info.area = area_p;
|
||||||
lv_event_send(obj, LV_EVENT_COVER_CHECK, &info);
|
lv_event_send(obj, LV_EVENT_COVER_CHECK, &info);
|
||||||
if(info.res == LV_DRAW_RES_MASKED) return NULL;
|
if(info.res == LV_COVER_RES_MASKED) return NULL;
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
||||||
@ -592,7 +592,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
|||||||
|
|
||||||
/*If no better children use this object*/
|
/*If no better children use this object*/
|
||||||
if(found_p == NULL) {
|
if(found_p == NULL) {
|
||||||
if(info.res == LV_DRAW_RES_COVER) {
|
if(info.res == LV_COVER_RES_COVER) {
|
||||||
found_p = obj;
|
found_p = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ static void lv_colorwheel_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
}
|
}
|
||||||
else if(code == LV_EVENT_COVER_CHECK) {
|
else if(code == LV_EVENT_COVER_CHECK) {
|
||||||
lv_cover_check_info_t * info = lv_event_get_param(e);
|
lv_cover_check_info_t * info = lv_event_get_param(e);
|
||||||
if(info->res != LV_DRAW_RES_MASKED) info->res = LV_DRAW_RES_NOT_COVER;
|
if(info->res != LV_COVER_RES_MASKED) info->res = LV_COVER_RES_NOT_COVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ static void lv_imgbtn_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
}
|
}
|
||||||
else if(code == LV_EVENT_COVER_CHECK) {
|
else if(code == LV_EVENT_COVER_CHECK) {
|
||||||
lv_cover_check_info_t * info = lv_event_get_param(e);
|
lv_cover_check_info_t * info = lv_event_get_param(e);
|
||||||
if(info->res != LV_DRAW_RES_MASKED) info->res = LV_DRAW_RES_NOT_COVER;
|
if(info->res != LV_COVER_RES_MASKED) info->res = LV_COVER_RES_NOT_COVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,21 +490,21 @@ static void draw_img(lv_event_t * e)
|
|||||||
lv_img_t * img = (lv_img_t *)obj;
|
lv_img_t * img = (lv_img_t *)obj;
|
||||||
if(code == LV_EVENT_COVER_CHECK) {
|
if(code == LV_EVENT_COVER_CHECK) {
|
||||||
lv_cover_check_info_t * info = lv_event_get_param(e);
|
lv_cover_check_info_t * info = lv_event_get_param(e);
|
||||||
if(info->res == LV_DRAW_RES_MASKED) return;
|
if(info->res == LV_COVER_RES_MASKED) return;
|
||||||
if(img->src_type == LV_IMG_SRC_UNKNOWN || img->src_type == LV_IMG_SRC_SYMBOL) {
|
if(img->src_type == LV_IMG_SRC_UNKNOWN || img->src_type == LV_IMG_SRC_SYMBOL) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Non true color format might have "holes"*/
|
/*Non true color format might have "holes"*/
|
||||||
if(img->cf != LV_IMG_CF_TRUE_COLOR && img->cf != LV_IMG_CF_RAW) {
|
if(img->cf != LV_IMG_CF_TRUE_COLOR && img->cf != LV_IMG_CF_RAW) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*With not LV_OPA_COVER images can't cover an area */
|
/*With not LV_OPA_COVER images can't cover an area */
|
||||||
if(lv_obj_get_style_img_opa(obj, LV_PART_MAIN) != LV_OPA_COVER) {
|
if(lv_obj_get_style_img_opa(obj, LV_PART_MAIN) != LV_OPA_COVER) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ static void draw_img(lv_event_t * e)
|
|||||||
angle_final += img->angle;
|
angle_final += img->angle;
|
||||||
|
|
||||||
if(angle_final != 0) {
|
if(angle_final != 0) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,7 +523,7 @@ static void draw_img(lv_event_t * e)
|
|||||||
const lv_area_t * clip_area = lv_event_get_param(e);
|
const lv_area_t * clip_area = lv_event_get_param(e);
|
||||||
if(zoom_final == LV_IMG_ZOOM_NONE) {
|
if(zoom_final == LV_IMG_ZOOM_NONE) {
|
||||||
if(_lv_area_is_in(clip_area, &obj->coords, 0) == false) {
|
if(_lv_area_is_in(clip_area, &obj->coords, 0) == false) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -536,7 +536,7 @@ static void draw_img(lv_event_t * e)
|
|||||||
a.y2 += obj->coords.y1;
|
a.y2 += obj->coords.y1;
|
||||||
|
|
||||||
if(_lv_area_is_in(clip_area, &a, 0) == false) {
|
if(_lv_area_is_in(clip_area, &a, 0) == false) {
|
||||||
info->res = LV_DRAW_RES_NOT_COVER;
|
info->res = LV_COVER_RES_NOT_COVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ static lv_draw_res_t lv_templ_draw(lv_obj_t * templ, const lv_area_t * clip_area
|
|||||||
{
|
{
|
||||||
/*Return false if the object is not covers the mask_p area*/
|
/*Return false if the object is not covers the mask_p area*/
|
||||||
if(mode == LV_DRAW_COVER_CHK) {
|
if(mode == LV_DRAW_COVER_CHK) {
|
||||||
return LV_DRAW_RES_NOT_COVER;
|
return LV_COVER_RES_NOT_COVER;
|
||||||
}
|
}
|
||||||
/*Draw the object*/
|
/*Draw the object*/
|
||||||
else if(mode == LV_DRAW_DRAW_MAIN) {
|
else if(mode == LV_DRAW_DRAW_MAIN) {
|
||||||
@ -206,7 +206,7 @@ static lv_draw_res_t lv_templ_draw(lv_obj_t * templ, const lv_area_t * clip_area
|
|||||||
else if(mode == LV_DRAW_DRAW_POST) {
|
else if(mode == LV_DRAW_DRAW_POST) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return LV_DRAW_RES_OK;
|
return LV_COVER_RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user