img: add drawing background
This commit is contained in:
@@ -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*/
|
||||
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
|
||||
} 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;
|
||||
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)));
|
||||
lv_coord_t shadow = (lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_SHADOW_WIDTH) >> 1);
|
||||
if(shadow) {
|
||||
shadow++;
|
||||
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
|
||||
else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) {
|
||||
|
||||
@@ -509,16 +509,43 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area
|
||||
return cover;
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
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) {
|
||||
coords.x1 += ext->offset.x;
|
||||
coords.y1 += ext->offset.y;
|
||||
img_coords.x1 += ext->offset.x;
|
||||
img_coords.y1 += ext->offset.y;
|
||||
|
||||
if(coords.x1 > img->coords.x1) coords.x1 -= ext->w;
|
||||
if(coords.y1 > img->coords.y1) coords.y1 -= ext->h;
|
||||
if(img_coords.x1 > img->coords.x1) img_coords.x1 -= ext->w;
|
||||
if(img_coords.y1 > img->coords.y1) img_coords.y1 -= ext->h;
|
||||
|
||||
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_area_t cords_tmp;
|
||||
cords_tmp.y1 = coords.y1;
|
||||
cords_tmp.y2 = coords.y1 + ext->h - 1;
|
||||
cords_tmp.y1 = img_coords.y1;
|
||||
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) {
|
||||
cords_tmp.x1 = coords.x1;
|
||||
cords_tmp.x2 = coords.x1 + ext->w - 1;
|
||||
for(; cords_tmp.x1 <= coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) {
|
||||
for(; cords_tmp.y1 <= img_coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) {
|
||||
cords_tmp.x1 = img_coords.x1;
|
||||
cords_tmp.x2 = img_coords.x1 + ext->w - 1;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
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 {
|
||||
/*Trigger the error handler of image drawer*/
|
||||
LV_LOG_WARN("lv_img_design: image source type is unknown");
|
||||
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;
|
||||
@@ -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;
|
||||
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) {
|
||||
lv_hit_test_info_t *info = param;
|
||||
if(ext->zoom != 256 && ext->angle == 0) {
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
*********************/
|
||||
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "lv_imgbtn.h"
|
||||
#include "lv_label.h"
|
||||
|
||||
|
||||
#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");
|
||||
|
||||
/*Create the ancestor of image button*/
|
||||
lv_obj_t * new_imgbtn = lv_btn_create(par, copy);
|
||||
LV_ASSERT_MEM(new_imgbtn);
|
||||
if(new_imgbtn == NULL) return NULL;
|
||||
lv_obj_t * imgbtn = lv_btn_create(par, copy);
|
||||
LV_ASSERT_MEM(imgbtn);
|
||||
if(imgbtn == NULL) return NULL;
|
||||
|
||||
/*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);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(new_imgbtn);
|
||||
lv_obj_del(imgbtn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_imgbtn);
|
||||
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_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(imgbtn);
|
||||
|
||||
/*Initialize the allocated 'ext' */
|
||||
#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;
|
||||
|
||||
/*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_design_cb(new_imgbtn, lv_imgbtn_design);
|
||||
lv_obj_set_signal_cb(imgbtn, lv_imgbtn_signal);
|
||||
lv_obj_set_design_cb(imgbtn, lv_imgbtn_design);
|
||||
|
||||
/*Init the new image button image button*/
|
||||
if(copy == NULL) {
|
||||
|
||||
lv_theme_apply(imgbtn, LV_THEME_IMGBTN);
|
||||
}
|
||||
/*Copy an existing image button*/
|
||||
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));
|
||||
#endif
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_imgbtn);
|
||||
lv_obj_refresh_style(imgbtn);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("image button created");
|
||||
|
||||
return new_imgbtn;
|
||||
return imgbtn;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
|
||||
@@ -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_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 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_img(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);
|
||||
return NULL;
|
||||
}
|
||||
ext->single_mode = 0;
|
||||
ext->size = 0;
|
||||
|
||||
#if LV_USE_GROUP
|
||||
ext->last_sel = NULL;
|
||||
ext->selected_btn = NULL;
|
||||
ext->last_clicked_btn = NULL;
|
||||
ext->last_sel_btn = NULL;
|
||||
ext->act_sel_btn = NULL;
|
||||
#endif
|
||||
|
||||
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_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);
|
||||
ext->size++;
|
||||
/*Create a list element with the image an the text*/
|
||||
lv_obj_t * liste;
|
||||
liste = lv_btn_create(list, NULL);
|
||||
lv_obj_t * btn;
|
||||
btn = lv_btn_create(list, NULL);
|
||||
|
||||
/*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*/
|
||||
lv_theme_apply(liste, LV_THEME_LIST_BTN);
|
||||
lv_theme_apply(btn, LV_THEME_LIST_BTN);
|
||||
|
||||
lv_page_glue_obj(liste, true);
|
||||
lv_btn_set_layout(liste, LV_LAYOUT_ROW_M);
|
||||
lv_page_glue_obj(btn, true);
|
||||
lv_btn_set_layout(btn, LV_LAYOUT_ROW_M);
|
||||
|
||||
lv_layout_t list_layout = lv_list_get_layout(list);
|
||||
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) {
|
||||
lv_btn_set_fit2(liste, LV_FIT_FLOOD, LV_FIT_TIGHT);
|
||||
lv_btn_set_fit2(btn, LV_FIT_FLOOD, LV_FIT_TIGHT);
|
||||
} else {
|
||||
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_obj_set_width(liste, w);
|
||||
lv_btn_set_fit2(btn, LV_FIT_NONE, LV_FIT_TIGHT);
|
||||
lv_obj_set_width(btn, w);
|
||||
}
|
||||
|
||||
|
||||
lv_obj_set_protect(liste, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_set_signal_cb(liste, lv_list_btn_signal);
|
||||
lv_obj_set_protect(btn, LV_PROTECT_PRESS_LOST);
|
||||
lv_obj_set_signal_cb(btn, lv_list_btn_signal);
|
||||
|
||||
#if LV_USE_IMG != 0
|
||||
lv_obj_t * img = NULL;
|
||||
if(img_src) {
|
||||
img = lv_img_create(liste, NULL);
|
||||
img = lv_img_create(btn, NULL);
|
||||
lv_img_set_src(img, img_src);
|
||||
lv_obj_set_click(img, false);
|
||||
if(img_signal == NULL) img_signal = lv_obj_get_signal_cb(img);
|
||||
}
|
||||
#endif
|
||||
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_obj_set_click(label, false);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);
|
||||
if(lv_obj_get_base_dir(liste) == LV_BIDI_DIR_RTL) {
|
||||
lv_coord_t pad = lv_obj_get_style_int(liste, LV_BTN_PART_MAIN, LV_STYLE_PAD_LEFT);
|
||||
lv_obj_set_width(label, label->coords.x2 - liste->coords.x1 - pad);
|
||||
if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL) {
|
||||
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 - btn->coords.x1 - pad);
|
||||
}
|
||||
else {
|
||||
lv_coord_t pad = lv_obj_get_style_int(liste, LV_BTN_PART_MAIN, LV_STYLE_PAD_RIGHT);
|
||||
lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - pad);
|
||||
lv_coord_t pad = lv_obj_get_style_int(btn, LV_BTN_PART_MAIN, LV_STYLE_PAD_RIGHT);
|
||||
lv_obj_set_width(label, btn->coords.x2 - label->coords.x1 - pad);
|
||||
}
|
||||
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 */
|
||||
{
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if(ext->size == 1 && lv_group_get_focused(g) == list) {
|
||||
lv_list_set_btn_selected(list, liste);
|
||||
if(lv_list_get_next_btn(list, NULL) == btn && lv_group_get_focused(g) == list) {
|
||||
lv_list_focus_btn(list, btn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
if(index >= ext->size) return false;
|
||||
uint16_t count = 0;
|
||||
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(count == index) {
|
||||
lv_obj_del(e);
|
||||
ext->size--;
|
||||
return true;
|
||||
}
|
||||
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
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
/**
|
||||
@@ -291,37 +267,27 @@ void lv_list_set_single_mode(lv_obj_t * list, bool mode)
|
||||
* @param btn pointer to a button to select
|
||||
* 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);
|
||||
if(btn) LV_ASSERT_OBJ(list, "lv_btn");
|
||||
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
|
||||
if(ext->selected_btn) {
|
||||
lv_btn_state_t s = lv_btn_get_state(ext->selected_btn);
|
||||
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);
|
||||
}
|
||||
/*Defocus the current button*/
|
||||
if(ext->act_sel_btn) lv_obj_clear_state(ext->act_sel_btn, LV_OBJ_STATE_FOCUS);
|
||||
|
||||
ext->selected_btn = btn;
|
||||
|
||||
/*Don't forget which button was selected.
|
||||
* It will be restored when the list is focused.*/
|
||||
if(btn != NULL) {
|
||||
ext->last_sel = btn;
|
||||
}
|
||||
* It will be restored when the list is focused again.*/
|
||||
if(btn) ext->last_sel_btn = btn;
|
||||
|
||||
if(ext->selected_btn) {
|
||||
lv_btn_state_t s = lv_btn_get_state(ext->selected_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);
|
||||
/*Focus the new button*/
|
||||
ext->act_sel_btn = btn;
|
||||
|
||||
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
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
return ext->size;
|
||||
uint16_t size = 0;
|
||||
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
|
||||
@@ -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_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
return ext->selected_btn;
|
||||
return ext->act_sel_btn;
|
||||
}
|
||||
#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 ||
|
||||
sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
#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_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_KEYPAD ||
|
||||
(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);
|
||||
|
||||
/*The page receives the key presses so the events should be propagated to the selected
|
||||
* 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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
#if LV_USE_GROUP
|
||||
ext->last_sel = btn;
|
||||
#endif
|
||||
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) {
|
||||
res = lv_event_send(btn, LV_EVENT_CLICKED, NULL);
|
||||
}
|
||||
if(res == LV_RES_OK) {
|
||||
res = lv_event_send(btn, LV_EVENT_RELEASED, NULL);
|
||||
if(lv_indev_is_dragging(indev) == false) {
|
||||
res = lv_event_send(ext->act_sel_btn, LV_EVENT_CLICKED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
|
||||
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
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
||||
/*With ENCODER select the first button only in edit mode*/
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER) {
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if(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*/
|
||||
/*With ENCODER focus the button only in edit mode*/
|
||||
lv_group_t * g = lv_obj_get_group(list);
|
||||
if((indev_type == LV_INDEV_TYPE_KEYPAD) ||
|
||||
(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_clicked_btn) {
|
||||
lv_list_set_btn_selected(list, ext->last_clicked_btn);
|
||||
ext->last_clicked_btn = 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));
|
||||
}
|
||||
}
|
||||
/* Select the last used button, or use the first no last button */
|
||||
if(ext->last_sel_btn) lv_list_focus_btn(list, ext->last_sel_btn);
|
||||
else lv_list_focus_btn(list, lv_list_get_next_btn(list, NULL));
|
||||
}
|
||||
#endif
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/*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);
|
||||
ext->last_clicked_btn = NULL; /*button click will be set if click happens before focus*/
|
||||
ext->selected_btn = NULL;
|
||||
ext->act_sel_btn = NULL;
|
||||
#endif
|
||||
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
|
||||
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) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/*If there is a valid selected button the make the previous selected*/
|
||||
if(ext->selected_btn) {
|
||||
lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->selected_btn);
|
||||
if(btn_prev) lv_list_set_btn_selected(list, btn_prev);
|
||||
if(ext->act_sel_btn) {
|
||||
lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->act_sel_btn);
|
||||
if(btn_prev) lv_list_focus_btn(list, btn_prev);
|
||||
}
|
||||
/*If there is no selected button the make the first selected*/
|
||||
else {
|
||||
lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
|
||||
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*/
|
||||
}
|
||||
} else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
/*If there is a valid selected button the make the next selected*/
|
||||
if(ext->selected_btn != NULL) {
|
||||
lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->selected_btn);
|
||||
if(btn_next) lv_list_set_btn_selected(list, btn_next);
|
||||
if(ext->act_sel_btn != NULL) {
|
||||
lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->act_sel_btn);
|
||||
if(btn_next) lv_list_focus_btn(list, btn_next);
|
||||
}
|
||||
/*If there is no selected button the make the first selected*/
|
||||
else {
|
||||
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
|
||||
@@ -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) {
|
||||
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
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
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) {
|
||||
/* Is the list is focused then be sure only the button being released
|
||||
* 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);
|
||||
}
|
||||
|
||||
if(g && lv_indev_is_dragging(lv_indev_get_act()) == false) {
|
||||
lv_group_focus_obj(list);
|
||||
/*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
|
||||
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) {
|
||||
|
||||
#if LV_USE_GROUP
|
||||
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
|
||||
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
|
||||
}
|
||||
|
||||
@@ -941,26 +851,6 @@ static lv_style_list_t * lv_list_get_style(lv_obj_t * list, uint8_t part)
|
||||
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.
|
||||
* @param list_btn List button
|
||||
|
||||
@@ -48,16 +48,10 @@ typedef struct
|
||||
{
|
||||
lv_page_ext_t page; /*Ext. of ancestor*/
|
||||
/*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
|
||||
lv_obj_t * last_sel; /* 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*/
|
||||
/*Used to make the last clicked button pressed (selected) when the list become focused and
|
||||
* `click_focus == 1`*/
|
||||
lv_obj_t * last_clicked_btn;
|
||||
lv_obj_t * last_sel_btn; /* The last selected button. It will be reverted when the list is focused again */
|
||||
lv_obj_t * act_sel_btn; /* The button is currently being selected*/
|
||||
#endif
|
||||
} lv_list_ext_t;
|
||||
|
||||
@@ -116,13 +110,6 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index);
|
||||
* 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
|
||||
|
||||
/**
|
||||
@@ -131,7 +118,7 @@ void lv_list_set_single_mode(lv_obj_t * list, bool mode);
|
||||
* @param btn pointer to a button to select
|
||||
* 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
|
||||
|
||||
/**
|
||||
@@ -186,12 +173,6 @@ void lv_list_set_layout(lv_obj_t * list, lv_layout_t layout);
|
||||
* 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
|
||||
* @param btn pointer to list element
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef enum {
|
||||
LV_THEME_LABEL,
|
||||
|
||||
LV_THEME_IMAGE,
|
||||
LV_THEME_IMGBTN,
|
||||
|
||||
LV_THEME_BTNM,
|
||||
|
||||
|
||||
@@ -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_add_style(list, &panel);
|
||||
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:
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
lv_style_list_reset(list);
|
||||
@@ -756,6 +761,13 @@ void lv_theme_alien_apply(lv_obj_t * obj, lv_theme_style_t name)
|
||||
break;
|
||||
#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
|
||||
case LV_THEME_LABEL:
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
|
||||
Reference in New Issue
Block a user