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*/
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) {

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;
} 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) {

View File

@@ -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;
}
/*=====================

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_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

View File

@@ -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

View File

@@ -45,6 +45,7 @@ typedef enum {
LV_THEME_LABEL,
LV_THEME_IMAGE,
LV_THEME_IMGBTN,
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_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);