img: add drawing background

This commit is contained in:
Gabor Kiss-Vamosi
2020-02-02 10:39:46 +01:00
parent a59f0edc0a
commit 64d281582d
7 changed files with 198 additions and 244 deletions

View File

@@ -3017,10 +3017,13 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
/*Return 'invalid' if the child change signal is not enabled*/ /*Return 'invalid' if the child change signal is not enabled*/
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV; if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_coord_t shadow = (lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_WIDTH) >> 1) + 1; lv_coord_t shadow = (lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_WIDTH) >> 1);
shadow += lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_SPREAD); if(shadow) {
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_X)), shadow++;
LV_MATH_ABS(lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_Y))); shadow += lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_SPREAD);
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_X)),
LV_MATH_ABS(lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_Y)));
}
} }
#if LV_USE_OBJ_REALIGN #if LV_USE_OBJ_REALIGN
else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) { else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) {

View File

@@ -509,16 +509,43 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
return cover; return cover;
} else if(mode == LV_DESIGN_DRAW_MAIN) { } else if(mode == LV_DESIGN_DRAW_MAIN) {
if(ext->h == 0 || ext->w == 0) return true; if(ext->h == 0 || ext->w == 0) return true;
lv_area_t coords; lv_area_t img_coords;
lv_obj_get_coords(img, &coords); lv_obj_get_coords(img, &img_coords);
lv_draw_rect_dsc_t bg_dsc;
lv_draw_rect_dsc_init(&bg_dsc);
lv_obj_init_draw_rect_dsc(img, LV_IMG_PART_MAIN, &bg_dsc);
/*If the border is drawn later disable loading its properties*/
if(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_BORDER_POST)) {
bg_dsc.border_opa = LV_OPA_TRANSP;
}
lv_area_t bg_coords;
lv_area_copy(&bg_coords, &img_coords);
bg_coords.x1 -= lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_LEFT);
bg_coords.x2 += lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_RIGHT);
bg_coords.y1 -= lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_TOP);
bg_coords.y2 += lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_BOTTOM);
lv_draw_rect(&bg_coords, clip_area, &bg_dsc);
if(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
lv_coord_t r = lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_RADIUS);
lv_draw_mask_radius_init(mp, &bg_coords, r, false);
/*Add the mask and use `img+8` as custom id. Don't use `obj` directly because it might be used by the user*/
lv_draw_mask_add(mp, img + 8);
}
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) { if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) {
coords.x1 += ext->offset.x; img_coords.x1 += ext->offset.x;
coords.y1 += ext->offset.y; img_coords.y1 += ext->offset.y;
if(coords.x1 > img->coords.x1) coords.x1 -= ext->w; if(img_coords.x1 > img->coords.x1) img_coords.x1 -= ext->w;
if(coords.y1 > img->coords.y1) coords.y1 -= ext->h; if(img_coords.y1 > img->coords.y1) img_coords.y1 -= ext->h;
LV_LOG_TRACE("lv_img_design: start to draw image"); LV_LOG_TRACE("lv_img_design: start to draw image");
@@ -527,13 +554,13 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
lv_obj_init_draw_img_dsc(img, LV_IMG_PART_MAIN, &img_dsc); lv_obj_init_draw_img_dsc(img, LV_IMG_PART_MAIN, &img_dsc);
lv_area_t cords_tmp; lv_area_t cords_tmp;
cords_tmp.y1 = coords.y1; cords_tmp.y1 = img_coords.y1;
cords_tmp.y2 = coords.y1 + ext->h - 1; cords_tmp.y2 = img_coords.y1 + ext->h - 1;
for(; cords_tmp.y1 <= coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) { for(; cords_tmp.y1 <= img_coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) {
cords_tmp.x1 = coords.x1; cords_tmp.x1 = img_coords.x1;
cords_tmp.x2 = coords.x1 + ext->w - 1; cords_tmp.x2 = img_coords.x1 + ext->w - 1;
for(; cords_tmp.x1 <= coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) { for(; cords_tmp.x1 <= img_coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) {
lv_draw_img(&cords_tmp, clip_area, ext->src, &img_dsc); lv_draw_img(&cords_tmp, clip_area, ext->src, &img_dsc);
} }
} }
@@ -544,12 +571,29 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
lv_obj_init_draw_label_dsc(img, LV_IMG_PART_MAIN, &label_dsc); lv_obj_init_draw_label_dsc(img, LV_IMG_PART_MAIN, &label_dsc);
label_dsc.color = lv_obj_get_style_color(img, LV_IMG_PART_MAIN, LV_STYLE_IMAGE_RECOLOR); label_dsc.color = lv_obj_get_style_color(img, LV_IMG_PART_MAIN, LV_STYLE_IMAGE_RECOLOR);
lv_draw_label(&coords, clip_area, &label_dsc, ext->src, NULL); lv_draw_label(&img_coords, clip_area, &label_dsc, ext->src, NULL);
} else { } else {
/*Trigger the error handler of image drawer*/ /*Trigger the error handler of image drawer*/
LV_LOG_WARN("lv_img_design: image source type is unknown"); LV_LOG_WARN("lv_img_design: image source type is unknown");
lv_draw_img(&img->coords, clip_area, NULL, NULL); lv_draw_img(&img->coords, clip_area, NULL, NULL);
} }
} else if(mode == LV_DESIGN_DRAW_POST) {
if(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(img + 8);
lv_mem_buf_release(param);
}
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
/*If the border is drawn later disable loading other properties*/
if(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_BORDER_POST)) {
draw_dsc.bg_opa = LV_OPA_TRANSP;
draw_dsc.pattern_opa = LV_OPA_TRANSP;
draw_dsc.shadow_opa = LV_OPA_TRANSP;
lv_obj_init_draw_rect_dsc(img, LV_OBJ_PART_MAIN, &draw_dsc);
lv_draw_rect(&img->coords, clip_area, &draw_dsc);
}
} }
return true; return true;
@@ -604,6 +648,27 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
lv_coord_t d = ds.i / 2; lv_coord_t d = ds.i / 2;
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, d); img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, d);
} }
/*Handle the padding of the background*/
lv_style_int_t left = lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_LEFT);
lv_style_int_t right = lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_RIGHT);
lv_style_int_t top = lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_TOP);
lv_style_int_t bottom = lv_obj_get_style_int(img, LV_IMG_PART_MAIN, LV_STYLE_PAD_BOTTOM);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, left);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, right);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, top);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, bottom);
/*Handle shadow*/
lv_coord_t shadow = (lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_WIDTH) >> 1);
if(shadow) {
shadow++;
shadow += lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_SPREAD);
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_X)),
LV_MATH_ABS(lv_obj_get_style_int(img, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_OFFSET_Y)));
}
} else if(sign == LV_SIGNAL_HIT_TEST) { } else if(sign == LV_SIGNAL_HIT_TEST) {
lv_hit_test_info_t *info = param; lv_hit_test_info_t *info = param;
if(ext->zoom != 256 && ext->angle == 0) { if(ext->zoom != 256 && ext->angle == 0) {

View File

@@ -8,9 +8,11 @@
*********************/ *********************/
#include "../lv_core/lv_debug.h" #include "../lv_core/lv_debug.h"
#include "../lv_themes/lv_theme.h"
#include "lv_imgbtn.h" #include "lv_imgbtn.h"
#include "lv_label.h" #include "lv_label.h"
#if LV_USE_IMGBTN != 0 #if LV_USE_IMGBTN != 0
/********************* /*********************
@@ -55,20 +57,20 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
LV_LOG_TRACE("image button create started"); LV_LOG_TRACE("image button create started");
/*Create the ancestor of image button*/ /*Create the ancestor of image button*/
lv_obj_t * new_imgbtn = lv_btn_create(par, copy); lv_obj_t * imgbtn = lv_btn_create(par, copy);
LV_ASSERT_MEM(new_imgbtn); LV_ASSERT_MEM(imgbtn);
if(new_imgbtn == NULL) return NULL; if(imgbtn == NULL) return NULL;
/*Allocate the image button type specific extended data*/ /*Allocate the image button type specific extended data*/
lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(new_imgbtn, sizeof(lv_imgbtn_ext_t)); lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(imgbtn, sizeof(lv_imgbtn_ext_t));
LV_ASSERT_MEM(ext); LV_ASSERT_MEM(ext);
if(ext == NULL) { if(ext == NULL) {
lv_obj_del(new_imgbtn); lv_obj_del(imgbtn);
return NULL; return NULL;
} }
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_imgbtn); if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(imgbtn);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_imgbtn); if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(imgbtn);
/*Initialize the allocated 'ext' */ /*Initialize the allocated 'ext' */
#if LV_IMGBTN_TILED == 0 #if LV_IMGBTN_TILED == 0
@@ -82,12 +84,12 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
ext->act_cf = LV_IMG_CF_UNKNOWN; ext->act_cf = LV_IMG_CF_UNKNOWN;
/*The signal and design functions are not copied so set them here*/ /*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_cb(new_imgbtn, lv_imgbtn_signal); lv_obj_set_signal_cb(imgbtn, lv_imgbtn_signal);
lv_obj_set_design_cb(new_imgbtn, lv_imgbtn_design); lv_obj_set_design_cb(imgbtn, lv_imgbtn_design);
/*Init the new image button image button*/ /*Init the new image button image button*/
if(copy == NULL) { if(copy == NULL) {
lv_theme_apply(imgbtn, LV_THEME_IMGBTN);
} }
/*Copy an existing image button*/ /*Copy an existing image button*/
else { else {
@@ -100,12 +102,12 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
memcpy((void*)ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right)); memcpy((void*)ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right));
#endif #endif
/*Refresh the style with new signal function*/ /*Refresh the style with new signal function*/
lv_obj_refresh_style(new_imgbtn); lv_obj_refresh_style(imgbtn);
} }
LV_LOG_INFO("image button created"); LV_LOG_INFO("image button created");
return new_imgbtn; return imgbtn;
} }
/*===================== /*=====================

View File

@@ -37,7 +37,6 @@
static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param); static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param);
static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param); static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);
static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part); static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part);
static void lv_list_btn_single_select(lv_obj_t * btn);
static bool lv_list_is_list_btn(lv_obj_t * list_btn); static bool lv_list_is_list_btn(lv_obj_t * list_btn);
static bool lv_list_is_list_img(lv_obj_t * list_btn); static bool lv_list_is_list_img(lv_obj_t * list_btn);
static bool lv_list_is_list_label(lv_obj_t * list_btn); static bool lv_list_is_list_label(lv_obj_t * list_btn);
@@ -84,13 +83,10 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_del(list); lv_obj_del(list);
return NULL; return NULL;
} }
ext->single_mode = 0;
ext->size = 0;
#if LV_USE_GROUP #if LV_USE_GROUP
ext->last_sel = NULL; ext->last_sel_btn = NULL;
ext->selected_btn = NULL; ext->act_sel_btn = NULL;
ext->last_clicked_btn = NULL;
#endif #endif
lv_obj_set_signal_cb(list, lv_list_signal); lv_obj_set_signal_cb(list, lv_list_signal);
@@ -138,8 +134,6 @@ void lv_list_clean(lv_obj_t * list)
lv_obj_t * scrl = lv_page_get_scrl(list); lv_obj_t * scrl = lv_page_get_scrl(list);
lv_obj_clean(scrl); lv_obj_clean(scrl);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->size = 0;
} }
/*====================== /*======================
@@ -165,19 +159,18 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->size++;
/*Create a list element with the image an the text*/ /*Create a list element with the image an the text*/
lv_obj_t * liste; lv_obj_t * btn;
liste = lv_btn_create(list, NULL); btn = lv_btn_create(list, NULL);
/*Save the original signal function because it will be required in `lv_list_btn_signal`*/ /*Save the original signal function because it will be required in `lv_list_btn_signal`*/
if(ancestor_btn_signal == NULL) ancestor_btn_signal = lv_obj_get_signal_cb(liste); if(ancestor_btn_signal == NULL) ancestor_btn_signal = lv_obj_get_signal_cb(btn);
/*Set the default styles*/ /*Set the default styles*/
lv_theme_apply(liste, LV_THEME_LIST_BTN); lv_theme_apply(btn, LV_THEME_LIST_BTN);
lv_page_glue_obj(liste, true); lv_page_glue_obj(btn, true);
lv_btn_set_layout(liste, LV_LAYOUT_ROW_M); lv_btn_set_layout(btn, LV_LAYOUT_ROW_M);
lv_layout_t list_layout = lv_list_get_layout(list); lv_layout_t list_layout = lv_list_get_layout(list);
bool layout_ver = false; bool layout_ver = false;
@@ -186,38 +179,38 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
} }
if(layout_ver) { if(layout_ver) {
lv_btn_set_fit2(liste, LV_FIT_FLOOD, LV_FIT_TIGHT); lv_btn_set_fit2(btn, LV_FIT_FLOOD, LV_FIT_TIGHT);
} else { } else {
lv_coord_t w = last_btn ? lv_obj_get_width(last_btn) : (LV_DPI * 3) / 2; lv_coord_t w = last_btn ? lv_obj_get_width(last_btn) : (LV_DPI * 3) / 2;
lv_btn_set_fit2(liste, LV_FIT_NONE, LV_FIT_TIGHT); lv_btn_set_fit2(btn, LV_FIT_NONE, LV_FIT_TIGHT);
lv_obj_set_width(liste, w); lv_obj_set_width(btn, w);
} }
lv_obj_set_protect(liste, LV_PROTECT_PRESS_LOST); lv_obj_set_protect(btn, LV_PROTECT_PRESS_LOST);
lv_obj_set_signal_cb(liste, lv_list_btn_signal); lv_obj_set_signal_cb(btn, lv_list_btn_signal);
#if LV_USE_IMG != 0 #if LV_USE_IMG != 0
lv_obj_t * img = NULL; lv_obj_t * img = NULL;
if(img_src) { if(img_src) {
img = lv_img_create(liste, NULL); img = lv_img_create(btn, NULL);
lv_img_set_src(img, img_src); lv_img_set_src(img, img_src);
lv_obj_set_click(img, false); lv_obj_set_click(img, false);
if(img_signal == NULL) img_signal = lv_obj_get_signal_cb(img); if(img_signal == NULL) img_signal = lv_obj_get_signal_cb(img);
} }
#endif #endif
if(txt != NULL) { if(txt != NULL) {
lv_obj_t * label = lv_label_create(liste, NULL); lv_obj_t * label = lv_label_create(btn, NULL);
lv_label_set_text(label, txt); lv_label_set_text(label, txt);
lv_obj_set_click(label, false); lv_obj_set_click(label, false);
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC); lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);
if(lv_obj_get_base_dir(liste) == LV_BIDI_DIR_RTL) { if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL) {
lv_coord_t pad = lv_obj_get_style_int(liste, LV_BTN_PART_MAIN, LV_STYLE_PAD_LEFT); lv_coord_t pad = lv_obj_get_style_int(btn, LV_BTN_PART_MAIN, LV_STYLE_PAD_LEFT);
lv_obj_set_width(label, label->coords.x2 - liste->coords.x1 - pad); lv_obj_set_width(label, label->coords.x2 - btn->coords.x1 - pad);
} }
else { else {
lv_coord_t pad = lv_obj_get_style_int(liste, LV_BTN_PART_MAIN, LV_STYLE_PAD_RIGHT); lv_coord_t pad = lv_obj_get_style_int(btn, LV_BTN_PART_MAIN, LV_STYLE_PAD_RIGHT);
lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - pad); lv_obj_set_width(label, btn->coords.x2 - label->coords.x1 - pad);
} }
if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label); if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label);
} }
@@ -227,15 +220,15 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
* focused, select it */ * focused, select it */
{ {
lv_group_t * g = lv_obj_get_group(list); lv_group_t * g = lv_obj_get_group(list);
if(ext->size == 1 && lv_group_get_focused(g) == list) { if(lv_list_get_next_btn(list, NULL) == btn && lv_group_get_focused(g) == list) {
lv_list_set_btn_selected(list, liste); lv_list_focus_btn(list, btn);
} }
} }
#endif #endif
lv_obj_set_pos(list, pos_x_ori, pos_y_ori); lv_obj_set_pos(list, pos_x_ori, pos_y_ori);
return liste; return btn;
} }
/** /**
@@ -249,14 +242,11 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index)
{ {
LV_ASSERT_OBJ(list, LV_OBJX_NAME); LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(index >= ext->size) return false;
uint16_t count = 0; uint16_t count = 0;
lv_obj_t * e = lv_list_get_next_btn(list, NULL); lv_obj_t * e = lv_list_get_next_btn(list, NULL);
while(e != NULL) { while(e != NULL) {
if(count == index) { if(count == index) {
lv_obj_del(e); lv_obj_del(e);
ext->size--;
return true; return true;
} }
e = lv_list_get_next_btn(list, e); e = lv_list_get_next_btn(list, e);
@@ -269,20 +259,6 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index)
* Setter functions * Setter functions
*====================*/ *====================*/
/**
* Set single button selected mode, only one button will be selected if enabled.
* @param list pointer to the currently pressed list object
* @param mode, enable(true)/disable(false) single selected mode.
*/
void lv_list_set_single_mode(lv_obj_t * list, bool mode)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->single_mode = mode;
}
#if LV_USE_GROUP #if LV_USE_GROUP
/** /**
@@ -291,37 +267,27 @@ void lv_list_set_single_mode(lv_obj_t * list, bool mode)
* @param btn pointer to a button to select * @param btn pointer to a button to select
* NULL to not select any buttons * NULL to not select any buttons
*/ */
void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn) void lv_list_focus_btn(lv_obj_t * list, lv_obj_t * btn)
{ {
LV_ASSERT_OBJ(list, LV_OBJX_NAME); LV_ASSERT_OBJ(list, LV_OBJX_NAME);
if(btn) LV_ASSERT_OBJ(list, "lv_btn"); if(btn) LV_ASSERT_OBJ(list, "lv_btn");
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(ext->selected_btn) { /*Defocus the current button*/
lv_btn_state_t s = lv_btn_get_state(ext->selected_btn); if(ext->act_sel_btn) lv_obj_clear_state(ext->act_sel_btn, LV_OBJ_STATE_FOCUS);
if(s == LV_BTN_STATE_PR)
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_REL);
else if(s == LV_BTN_STATE_TGL_PR)
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_REL);
}
ext->selected_btn = btn;
/*Don't forget which button was selected. /*Don't forget which button was selected.
* It will be restored when the list is focused.*/ * It will be restored when the list is focused again.*/
if(btn != NULL) { if(btn) ext->last_sel_btn = btn;
ext->last_sel = btn;
}
if(ext->selected_btn) { /*Focus the new button*/
lv_btn_state_t s = lv_btn_get_state(ext->selected_btn); ext->act_sel_btn = btn;
if(s == LV_BTN_STATE_REL)
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_PR);
else if(s == LV_BTN_STATE_TGL_REL)
lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_PR);
lv_page_focus(list, ext->selected_btn, LV_ANIM_ON); if(ext->act_sel_btn) {
lv_obj_add_state(ext->act_sel_btn, LV_OBJ_STATE_FOCUS);
lv_page_focus(list, ext->act_sel_btn, LV_ANIM_ON);
} }
} }
@@ -370,19 +336,6 @@ void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn)
* Getter functions * Getter functions
*====================*/ *====================*/
/**
* Get single button selected mode.
* @param list pointer to the currently pressed list object.
*/
bool lv_list_get_single_mode(lv_obj_t * list)
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return (ext->single_mode);
}
/** /**
* Get the text of a list element * Get the text of a list element
* @param btn pointer to list element * @param btn pointer to list element
@@ -531,8 +484,13 @@ uint16_t lv_list_get_size(const lv_obj_t * list)
{ {
LV_ASSERT_OBJ(list, LV_OBJX_NAME); LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); uint16_t size = 0;
return ext->size; lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
while(btn) {
size++;
btn = lv_list_get_next_btn(list, NULL);
}
return size;
} }
#if LV_USE_GROUP #if LV_USE_GROUP
@@ -546,7 +504,7 @@ lv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list)
LV_ASSERT_OBJ(list, LV_OBJX_NAME); LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return ext->selected_btn; return ext->act_sel_btn;
} }
#endif #endif
@@ -703,44 +661,42 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING || if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING ||
sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) { sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {
#if LV_USE_GROUP #if LV_USE_GROUP
/*If pressed/released etc by a KEYPAD or ENCODER delegate signal to the button*/ /*If pressed/released etc by a KEYPAD or ENCODER delegate signal and events to the button*/
lv_indev_t * indev = lv_indev_get_act(); lv_indev_t * indev = lv_indev_get_act();
lv_indev_type_t indev_type = lv_indev_get_type(indev); lv_indev_type_t indev_type = lv_indev_get_type(indev);
if(indev_type == LV_INDEV_TYPE_KEYPAD || if(indev_type == LV_INDEV_TYPE_KEYPAD ||
(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list)))) { (indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list)))) {
/*Get the 'pressed' button*/
lv_obj_t * btn = NULL;
btn = lv_list_get_prev_btn(list, btn);
while(btn != NULL) {
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
btn = lv_list_get_prev_btn(list, btn);
}
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
/*The page receives the key presses so the events should be propagated to the selected /*The page receives the key presses so the events should be propagated to the selected
* button*/ * button*/
if(btn) { if(ext->act_sel_btn) {
res = lv_signal_send(ext->act_sel_btn, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_PRESSED) { if(sign == LV_SIGNAL_PRESSED) {
res = lv_event_send(btn, LV_EVENT_PRESSED, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_PRESSED, NULL);
if(res != LV_RES_OK) return res;
} else if(sign == LV_SIGNAL_PRESSING) { } else if(sign == LV_SIGNAL_PRESSING) {
res = lv_event_send(btn, LV_EVENT_PRESSING, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_PRESSING, NULL);
if(res != LV_RES_OK) return res;
} else if(sign == LV_SIGNAL_LONG_PRESS) { } else if(sign == LV_SIGNAL_LONG_PRESS) {
res = lv_event_send(btn, LV_EVENT_LONG_PRESSED, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_LONG_PRESSED, NULL);
if(res != LV_RES_OK) return res;
} else if(sign == LV_SIGNAL_LONG_PRESS_REP) { } else if(sign == LV_SIGNAL_LONG_PRESS_REP) {
res = lv_event_send(btn, LV_EVENT_LONG_PRESSED_REPEAT, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
if(res != LV_RES_OK) return res;
} else if(sign == LV_SIGNAL_RELEASED) { } else if(sign == LV_SIGNAL_RELEASED) {
#if LV_USE_GROUP
ext->last_sel = btn;
#endif
if(indev->proc.long_pr_sent == 0) { if(indev->proc.long_pr_sent == 0) {
res = lv_event_send(btn, LV_EVENT_SHORT_CLICKED, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_SHORT_CLICKED, NULL);
if(res != LV_RES_OK) return res;
} }
if(lv_indev_is_dragging(indev) == false && res == LV_RES_OK) { if(lv_indev_is_dragging(indev) == false) {
res = lv_event_send(btn, LV_EVENT_CLICKED, NULL); res = lv_event_send(ext->act_sel_btn, LV_EVENT_CLICKED, NULL);
} if(res != LV_RES_OK) return res;
if(res == LV_RES_OK) {
res = lv_event_send(btn, LV_EVENT_RELEASED, NULL);
} }
res = lv_event_send(ext->act_sel_btn, LV_EVENT_RELEASED, NULL);
if(res != LV_RES_OK) return res;
} }
} }
} }
@@ -749,49 +705,23 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
#if LV_USE_GROUP #if LV_USE_GROUP
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
/*With ENCODER select the first button only in edit mode*/ /*With ENCODER focus the button only in edit mode*/
if(indev_type == LV_INDEV_TYPE_ENCODER) { lv_group_t * g = lv_obj_get_group(list);
lv_group_t * g = lv_obj_get_group(list); if((indev_type == LV_INDEV_TYPE_KEYPAD) ||
if(lv_group_get_editing(g)) { (indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(g))) {
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(ext->last_sel) {
/* Select the last used button */
lv_list_set_btn_selected(list, ext->last_sel);
} else {
/*Get the first button and mark it as selected*/
lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));
}
} else {
lv_list_set_btn_selected(list, NULL);
}
}
/*Else select the clicked button*/
else {
/*Mark the last clicked button (if any) as selected because it triggered the focus*/
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(ext->last_clicked_btn) { /* Select the last used button, or use the first no last button */
lv_list_set_btn_selected(list, ext->last_clicked_btn); if(ext->last_sel_btn) lv_list_focus_btn(list, ext->last_sel_btn);
ext->last_clicked_btn = NULL; else lv_list_focus_btn(list, lv_list_get_next_btn(list, NULL));
} else {
if(ext->last_sel) {
/* Select the last used button */
lv_list_set_btn_selected(list, ext->last_sel);
} else {
/*Get the first button and mark it as selected*/
lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));
}
}
} }
#endif #endif
} else if(sign == LV_SIGNAL_DEFOCUS) { } else if(sign == LV_SIGNAL_DEFOCUS) {
#if LV_USE_GROUP #if LV_USE_GROUP
/*De-select the selected btn*/ /*De-select the selected btn*/
lv_list_set_btn_selected(list, NULL); lv_list_focus_btn(list, NULL);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->last_clicked_btn = NULL; /*button click will be set if click happens before focus*/ ext->act_sel_btn = NULL;
ext->selected_btn = NULL;
#endif #endif
} else if(sign == LV_SIGNAL_GET_EDITABLE) { } else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param; bool * editable = (bool *)param;
@@ -803,28 +733,28 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) { if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
/*If there is a valid selected button the make the previous selected*/ /*If there is a valid selected button the make the previous selected*/
if(ext->selected_btn) { if(ext->act_sel_btn) {
lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->selected_btn); lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->act_sel_btn);
if(btn_prev) lv_list_set_btn_selected(list, btn_prev); if(btn_prev) lv_list_focus_btn(list, btn_prev);
} }
/*If there is no selected button the make the first selected*/ /*If there is no selected button the make the first selected*/
else { else {
lv_obj_t * btn = lv_list_get_next_btn(list, NULL); lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
if(btn) if(btn)
lv_list_set_btn_selected(list, lv_list_focus_btn(list,
btn); /*If there are no buttons on the list then there is no first button*/ btn); /*If there are no buttons on the list then there is no first button*/
} }
} else if(c == LV_KEY_LEFT || c == LV_KEY_UP) { } else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {
lv_list_ext_t * ext = lv_obj_get_ext_attr(list); lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
/*If there is a valid selected button the make the next selected*/ /*If there is a valid selected button the make the next selected*/
if(ext->selected_btn != NULL) { if(ext->act_sel_btn != NULL) {
lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->selected_btn); lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->act_sel_btn);
if(btn_next) lv_list_set_btn_selected(list, btn_next); if(btn_next) lv_list_focus_btn(list, btn_next);
} }
/*If there is no selected button the make the first selected*/ /*If there is no selected button the make the first selected*/
else { else {
lv_obj_t * btn = lv_list_get_next_btn(list, NULL); lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
if(btn) lv_list_set_btn_selected(list, btn); if(btn) lv_list_focus_btn(list, btn);
} }
} }
#endif #endif
@@ -865,41 +795,21 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
} }
} }
else if(sign == LV_SIGNAL_RELEASED) { else if(sign == LV_SIGNAL_RELEASED) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
#if LV_USE_GROUP #if LV_USE_GROUP
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_group_t * g = lv_obj_get_group(list); lv_group_t * g = lv_obj_get_group(list);
if(lv_group_get_focused(g) == list && lv_indev_is_dragging(lv_indev_get_act()) == false) { if(g && lv_indev_is_dragging(lv_indev_get_act()) == false) {
/* Is the list is focused then be sure only the button being released lv_group_focus_obj(list);
* has a pressed state to indicate the selected state on the list*/
lv_obj_t * btn_i = lv_list_get_prev_btn(list, NULL);
while(btn_i) {
lv_btn_state_t s = lv_btn_get_state(btn_i);
if(s == LV_BTN_STATE_PR)
lv_btn_set_state(btn_i, LV_BTN_STATE_REL);
else if(s == LV_BTN_STATE_TGL_PR)
lv_btn_set_state(btn_i, LV_BTN_STATE_TGL_REL);
btn_i = lv_list_get_prev_btn(list, btn_i);
}
/*Make the released button "selected"*/ /*Make the released button "selected"*/
lv_list_set_btn_selected(list, btn); lv_list_focus_btn(list, btn);
} }
/* If `click_focus == 1` then LV_SIGNAL_FOCUS need to know which button triggered the focus
* to mark it as selected (pressed state)*/
ext->last_clicked_btn = btn;
#endif #endif
if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode) {
lv_list_btn_single_select(btn);
}
} else if(sign == LV_SIGNAL_CLEANUP) { } else if(sign == LV_SIGNAL_CLEANUP) {
#if LV_USE_GROUP #if LV_USE_GROUP
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn)); lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_obj_t * sel = lv_list_get_btn_selected(list); lv_obj_t * sel = lv_list_get_btn_selected(list);
if(sel == btn) lv_list_set_btn_selected(list, lv_list_get_next_btn(list, btn)); if(sel == btn) lv_list_focus_btn(list, lv_list_get_next_btn(list, btn));
#endif #endif
} }
@@ -941,26 +851,6 @@ static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part)
return style_dsc_p; return style_dsc_p;
} }
/**
* Make a single button selected in the list, deselect others.
* @param btn pointer to the currently pressed list btn object
*/
static void lv_list_btn_single_select(lv_obj_t * btn)
{
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
do {
if(e == btn) {
lv_btn_set_state(e, LV_BTN_STATE_TGL_REL);
} else {
lv_btn_set_state(e, LV_BTN_STATE_REL);
}
e = lv_list_get_next_btn(list, e);
} while(e != NULL);
}
/** /**
* Check if this is really a list button or another object. * Check if this is really a list button or another object.
* @param list_btn List button * @param list_btn List button

View File

@@ -48,16 +48,10 @@ typedef struct
{ {
lv_page_ext_t page; /*Ext. of ancestor*/ lv_page_ext_t page; /*Ext. of ancestor*/
/*New data for this type */ /*New data for this type */
uint16_t size; /*the number of items(buttons) in the list*/
uint8_t single_mode : 1; /* whether single selected mode is enabled */
#if LV_USE_GROUP #if LV_USE_GROUP
lv_obj_t * last_sel; /* The last selected button. It will be reverted when the list is focused again */ lv_obj_t * last_sel_btn; /* The last selected button. It will be reverted when the list is focused again */
lv_obj_t * selected_btn; /* The button is currently being selected*/ lv_obj_t * act_sel_btn; /* The button is currently being selected*/
/*Used to make the last clicked button pressed (selected) when the list become focused and
* `click_focus == 1`*/
lv_obj_t * last_clicked_btn;
#endif #endif
} lv_list_ext_t; } lv_list_ext_t;
@@ -116,13 +110,6 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index);
* Setter functions * Setter functions
*====================*/ *====================*/
/**
* Set single button selected mode, only one button will be selected if enabled.
* @param list pointer to the currently pressed list object
* @param mode enable(true)/disable(false) single selected mode.
*/
void lv_list_set_single_mode(lv_obj_t * list, bool mode);
#if LV_USE_GROUP #if LV_USE_GROUP
/** /**
@@ -131,7 +118,7 @@ void lv_list_set_single_mode(lv_obj_t * list, bool mode);
* @param btn pointer to a button to select * @param btn pointer to a button to select
* NULL to not select any buttons * NULL to not select any buttons
*/ */
void lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn); void lv_list_focus_btn(lv_obj_t * list, lv_obj_t * btn);
#endif #endif
/** /**
@@ -186,12 +173,6 @@ void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout);
* Getter functions * Getter functions
*====================*/ *====================*/
/**
* Get single button selected mode.
* @param list pointer to the currently pressed list object.
*/
bool lv_list_get_single_mode(lv_obj_t * list);
/** /**
* Get the text of a list element * Get the text of a list element
* @param btn pointer to list element * @param btn pointer to list element

View File

@@ -45,6 +45,7 @@ typedef enum {
LV_THEME_LABEL, LV_THEME_LABEL,
LV_THEME_IMAGE, LV_THEME_IMAGE,
LV_THEME_IMGBTN,
LV_THEME_BTNM, LV_THEME_BTNM,

View File

@@ -710,6 +710,11 @@ void lv_theme_alien_apply(lv_obj_t * obj, lv_theme_style_t name)
lv_style_list_reset(list); lv_style_list_reset(list);
lv_style_list_add_style(list, &panel); lv_style_list_add_style(list, &panel);
break; break;
case LV_THEME_CONT:
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
lv_style_list_reset(list);
lv_style_list_add_style(list, &panel);
break;
case LV_THEME_BTN: case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN); list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
lv_style_list_reset(list); lv_style_list_reset(list);
@@ -756,6 +761,13 @@ void lv_theme_alien_apply(lv_obj_t * obj, lv_theme_style_t name)
break; break;
#endif #endif
#if LV_USE_IMGBTN
case LV_THEME_IMGBTN:
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
lv_style_list_reset(list);
break;
#endif
#if LV_USE_LABEL #if LV_USE_LABEL
case LV_THEME_LABEL: case LV_THEME_LABEL:
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN); list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);