1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

Merge pull request #540 from turoksama/dev-5.3

[PR] Add a DOWN symbol within ddlist.
This commit is contained in:
embeddedt 2018-11-11 21:09:10 -05:00 committed by GitHub
commit 9ae58caadb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 67 deletions

View File

@ -292,7 +292,7 @@
#define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */ #define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */
#endif #endif
/*Drop down list (dependencies: lv_page, lv_label)*/ /*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
#define USE_LV_DDLIST 1 #define USE_LV_DDLIST 1
#if USE_LV_DDLIST != 0 #if USE_LV_DDLIST != 0
#define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/ #define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/

View File

@ -92,6 +92,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
ext->option_cnt = 0; ext->option_cnt = 0;
ext->anim_time = LV_DDLIST_ANIM_TIME; ext->anim_time = LV_DDLIST_ANIM_TIME;
ext->sel_style = &lv_style_plain_color; ext->sel_style = &lv_style_plain_color;
ext->draw_arrow = 0; /*Do not draw arrow by default*/
/*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_func(new_ddlist, lv_ddlist_signal); lv_obj_set_signal_func(new_ddlist, lv_ddlist_signal);
@ -136,6 +137,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
ext->option_cnt = copy_ext->option_cnt; ext->option_cnt = copy_ext->option_cnt;
ext->sel_style = copy_ext->sel_style; ext->sel_style = copy_ext->sel_style;
ext->anim_time = copy_ext->anim_time; ext->anim_time = copy_ext->anim_time;
ext->draw_arrow = copy_ext->draw_arrow;
/*Refresh the style with new signal function*/ /*Refresh the style with new signal function*/
lv_obj_refresh_style(new_ddlist); lv_obj_refresh_style(new_ddlist);
@ -151,6 +153,19 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)
* Setter functions * Setter functions
*====================*/ *====================*/
/**
* Set arrow draw in a drop down list
* @param ddlist pointer to drop down list object
* @param en enable/disable a arrow draw. E.g. "true" for draw.
*/
void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Set the flag*/
ext->draw_arrow = en;
}
/** /**
* Set the options in a drop down list from a string * Set the options in a drop down list from a string
* @param ddlist pointer to drop down list object * @param ddlist pointer to drop down list object
@ -276,6 +291,17 @@ void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, lv_style_t *
* Getter functions * Getter functions
*====================*/ *====================*/
/**
* Get arrow draw in a drop down list
* @param ddlist pointer to drop down list object
*/
bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return ext->draw_arrow;
}
/** /**
* Get the options of a drop down list * Get the options of a drop down list
* @param ddlist pointer to drop down list object * @param ddlist pointer to drop down list object
@ -357,7 +383,6 @@ uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist)
return ext->anim_time; return ext->anim_time;
} }
/** /**
* Get a style of a drop down list * Get a style of a drop down list
* @param ddlist pointer to a drop down list object * @param ddlist pointer to a drop down list object
@ -366,25 +391,21 @@ uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist)
*/ */
lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type) lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type)
{ {
lv_style_t * style = NULL;
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
switch(type) { switch(type) {
case LV_DDLIST_STYLE_BG: case LV_DDLIST_STYLE_BG:
style = lv_page_get_style(ddlist, LV_PAGE_STYLE_BG); return lv_page_get_style(ddlist, LV_PAGE_STYLE_BG);
break;
case LV_DDLIST_STYLE_SB: case LV_DDLIST_STYLE_SB:
style = lv_page_get_style(ddlist, LV_PAGE_STYLE_SB); return lv_page_get_style(ddlist, LV_PAGE_STYLE_SB);
break;
case LV_DDLIST_STYLE_SEL: case LV_DDLIST_STYLE_SEL:
style = ext->sel_style; return ext->sel_style;
break;
default: default:
style = NULL; return NULL;
break;
} }
return style; /*To avoid warning*/
return NULL;
} }
/*===================== /*=====================
* Other functions * Other functions
@ -448,7 +469,6 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist); lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist);
/*If the list is opened draw a rectangle under the selected item*/ /*If the list is opened draw a rectangle under the selected item*/
if(ext->opened != 0) { if(ext->opened != 0) {
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG); lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
@ -502,6 +522,38 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
} }
} }
/*Add a down symbol in ddlist when closed*/
else
{
/*Draw a arrow in ddlist if enabled*/
if(ext->draw_arrow)
{
lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
const lv_font_t * font = style->text.font;
lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);
lv_coord_t font_h = lv_font_get_height(font);
lv_style_t new_style;
lv_style_copy(&new_style, style);
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_area_t area_arrow;
area_arrow.x2 = ddlist->coords.x2 - style->body.padding.hor;
area_arrow.x1 = area_arrow.x2 - lv_txt_get_width(SYMBOL_DOWN, 1, sel_style->text.font, 0, 0);
area_arrow.y1 = ddlist->coords.y1 + style->text.line_space;
area_arrow.y2 = area_arrow.y1 + font_h;
lv_area_t mask_arrow;
bool area_ok;
area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);
if (area_ok)
{
lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale,
SYMBOL_DOWN, LV_TXT_FLAG_NONE, NULL); /*Use a down arrow in ddlist, you can replace it with your custom symbol*/
}
}
}
/*Draw the scrollbar in the ancestor page design function*/ /*Draw the scrollbar in the ancestor page design function*/
ancestor_design(ddlist, mask, mode); ancestor_design(ddlist, mask, mode);
} }
@ -530,12 +582,10 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
} else if(sign == LV_SIGNAL_CLEANUP) { } else if(sign == LV_SIGNAL_CLEANUP) {
ext->label = NULL; ext->label = NULL;
} else if(sign == LV_SIGNAL_FOCUS) { } else if(sign == LV_SIGNAL_FOCUS) {
bool editing = false;
#if USE_LV_GROUP
lv_group_t * g = lv_obj_get_group(ddlist); lv_group_t * g = lv_obj_get_group(ddlist);
editing = lv_group_get_editing(g); bool editing = lv_group_get_editing(g);
#endif
lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
/*Encoders need special handling*/ /*Encoders need special handling*/
if(indev_type == LV_INDEV_TYPE_ENCODER) { if(indev_type == LV_INDEV_TYPE_ENCODER) {
/*Open the list if editing*/ /*Open the list if editing*/
@ -592,19 +642,16 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
if(ext->opened) { if(ext->opened) {
ext->sel_opt_id_ori = ext->sel_opt_id; ext->sel_opt_id_ori = ext->sel_opt_id;
ext->opened = 0; ext->opened = 0;
if(ext->action) res = ext->action(ddlist); if(ext->action) ext->action(ddlist);
#if USE_LV_GROUP
if(res == LV_RES_OK) {
lv_group_t * g = lv_obj_get_group(ddlist); lv_group_t * g = lv_obj_get_group(ddlist);
bool editing = lv_group_get_editing(g); bool editing = lv_group_get_editing(g);
if(editing) lv_group_set_editing(g, false); /*In edit mode go to navigate mode if an option is selected*/ if(editing) lv_group_set_editing(g, false); /*In edit mode go to navigate mode if an option is selected*/
}
#endif
} else { } else {
ext->opened = 1; ext->opened = 1;
} }
if(res == LV_RES_OK) lv_ddlist_refr_size(ddlist, true); lv_ddlist_refr_size(ddlist, true);
} else if(c == LV_GROUP_KEY_ESC) { } else if(c == LV_GROUP_KEY_ESC) {
if(ext->opened) { if(ext->opened) {
ext->opened = 0; ext->opened = 0;
@ -664,7 +711,6 @@ static lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void *
static lv_res_t lv_ddlist_release_action(lv_obj_t * ddlist) static lv_res_t lv_ddlist_release_action(lv_obj_t * ddlist)
{ {
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
lv_res_t res = LV_RES_OK;
if(ext->opened == 0) { /*Open the list*/ if(ext->opened == 0) { /*Open the list*/
ext->opened = 1; ext->opened = 1;
@ -695,13 +741,12 @@ static lv_res_t lv_ddlist_release_action(lv_obj_t * ddlist)
ext->sel_opt_id = new_opt; ext->sel_opt_id = new_opt;
if(ext->action != NULL) { if(ext->action != NULL) {
res = ext->action(ddlist); ext->action(ddlist);
} }
} }
lv_ddlist_refr_size(ddlist, true);
if(res == LV_RES_OK) lv_ddlist_refr_size(ddlist, true); return LV_RES_OK;
return res;
} }
@ -716,9 +761,6 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
anim_en = false; anim_en = false;
#endif #endif
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
if(ext->label == NULL) return; /*Probably the ddlist is being deleted if the label is NULL.*/
lv_style_t * style = lv_obj_get_style(ddlist); lv_style_t * style = lv_obj_get_style(ddlist);
lv_coord_t new_height; lv_coord_t new_height;
if(ext->opened) { /*Open the list*/ if(ext->opened) { /*Open the list*/
@ -767,9 +809,6 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en)
static void lv_ddlist_pos_current_option(lv_obj_t * ddlist) static void lv_ddlist_pos_current_option(lv_obj_t * ddlist)
{ {
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
if(ext->label == NULL) return; /*Probably the ddlist is being deleted if the label is NULL.*/
lv_style_t * style = lv_obj_get_style(ddlist); lv_style_t * style = lv_obj_get_style(ddlist);
const lv_font_t * font = style->text.font; const lv_font_t * font = style->text.font;
lv_coord_t font_h = lv_font_get_height(font); lv_coord_t font_h = lv_font_get_height(font);

View File

@ -54,6 +54,8 @@ typedef struct
uint16_t sel_opt_id_ori; /*Store the original index on focus*/ uint16_t sel_opt_id_ori; /*Store the original index on focus*/
uint16_t anim_time; /*Open/Close animation time [ms]*/ uint16_t anim_time; /*Open/Close animation time [ms]*/
uint8_t opened :1; /*1: The list is opened (handled by the library)*/ uint8_t opened :1; /*1: The list is opened (handled by the library)*/
uint8_t draw_arrow :1; /*1: Draw arrow*/
lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/ lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/
} lv_ddlist_ext_t; } lv_ddlist_ext_t;
@ -79,6 +81,13 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy);
* Setter functions * Setter functions
*====================*/ *====================*/
/**
* Set arrow draw in a drop down list
* @param ddlist pointer to drop down list object
* @param en enable/disable a arrow draw. E.g. "true" for draw.
*/
void lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en);
/** /**
* Set the options in a drop down list from a string * Set the options in a drop down list from a string
* @param ddlist pointer to drop down list object * @param ddlist pointer to drop down list object
@ -145,6 +154,12 @@ void lv_ddlist_set_style(lv_obj_t *ddlist, lv_ddlist_style_t type, lv_style_t *s
* Getter functions * Getter functions
*====================*/ *====================*/
/**
* Get arrow draw in a drop down list
* @param ddlist pointer to drop down list object
*/
bool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist);
/** /**
* Get the options of a drop down list * Get the options of a drop down list
* @param ddlist pointer to drop down list object * @param ddlist pointer to drop down list object

View File

@ -74,6 +74,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(new_roller, sizeof(lv_roller_ext_t)); lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(new_roller, sizeof(lv_roller_ext_t));
lv_mem_assert(ext); lv_mem_assert(ext);
if(ext == NULL) return NULL; if(ext == NULL) return NULL;
ext->ddlist.draw_arrow = 0; /*Do not draw arrow by default*/
/*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_func(new_roller, lv_roller_signal); lv_obj_set_signal_func(new_roller, lv_roller_signal);
@ -192,21 +193,17 @@ bool lv_roller_get_hor_fit(const lv_obj_t * roller)
* */ * */
lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type) lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type)
{ {
lv_style_t * style = NULL;
switch(type) { switch(type) {
case LV_ROLLER_STYLE_BG: case LV_ROLLER_STYLE_BG:
style = lv_obj_get_style(roller); return lv_obj_get_style(roller);
break;
case LV_ROLLER_STYLE_SEL: case LV_ROLLER_STYLE_SEL:
style = lv_ddlist_get_style(roller, LV_DDLIST_STYLE_SEL); return lv_ddlist_get_style(roller, LV_DDLIST_STYLE_SEL);
break;
default: default:
style = NULL; return NULL;
break;
} }
return style; /*To avoid warning*/
return NULL;
} }
/********************** /**********************
@ -319,11 +316,8 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
refr_position(roller, false); refr_position(roller, false);
} }
} else if(sign == LV_SIGNAL_FOCUS) { } else if(sign == LV_SIGNAL_FOCUS) {
bool editing = false;
#if USE_LV_GROUP
lv_group_t * g = lv_obj_get_group(roller); lv_group_t * g = lv_obj_get_group(roller);
editing = lv_group_get_editing(g); bool editing = lv_group_get_editing(g);
#endif
lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
/*Encoders need special handling*/ /*Encoders need special handling*/
@ -363,16 +357,12 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
} }
} else if(c == LV_GROUP_KEY_ENTER) { } else if(c == LV_GROUP_KEY_ENTER) {
ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Set the entered value as default*/ ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Set the entered value as default*/
if(ext->ddlist.action) res = ext->ddlist.action(roller); if(ext->ddlist.action) ext->ddlist.action(roller);
#if USE_LV_GROUP
if(res == LV_RES_OK) {
lv_group_t * g = lv_obj_get_group(roller); lv_group_t * g = lv_obj_get_group(roller);
bool editing = lv_group_get_editing(g); bool editing = lv_group_get_editing(g);
if(editing) lv_group_set_editing(g, false); /*In edit mode go to navigate mode if an option is selected*/ if(editing) lv_group_set_editing(g, false); /*In edit mode go to navigate mode if an option is selected*/
} }
#endif
}
} else if(sign == LV_SIGNAL_GET_TYPE) { } else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param; lv_obj_type_t * buf = param;
uint8_t i; uint8_t i;
@ -420,8 +410,7 @@ static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign,
if(id < 0) id = 0; if(id < 0) id = 0;
if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1; if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1;
ext->ddlist.sel_opt_id = id; ext->ddlist.sel_opt_id = id;
ext->ddlist.sel_opt_id_ori = id; if(ext->ddlist.action) ext->ddlist.action(roller);
if(ext->ddlist.action) res = ext->ddlist.action(roller);
} else if(sign == LV_SIGNAL_RELEASED) { } else if(sign == LV_SIGNAL_RELEASED) {
/*If picked an option by clicking then set it*/ /*If picked an option by clicking then set it*/
if(!lv_indev_is_dragging(indev)) { if(!lv_indev_is_dragging(indev)) {
@ -432,13 +421,12 @@ static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign,
if(id < 0) id = 0; if(id < 0) id = 0;
if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1; if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1;
ext->ddlist.sel_opt_id = id; ext->ddlist.sel_opt_id = id;
ext->ddlist.sel_opt_id_ori = id; if(ext->ddlist.action) ext->ddlist.action(roller);
if(ext->ddlist.action) res = ext->ddlist.action(roller);
} }
} }
/*Position the scrollable according to the new selected option*/ /*Position the scrollable according to the new selected option*/
if(id != -1 && res == LV_RES_OK) { if(id != -1) {
refr_position(roller, true); refr_position(roller, true);
} }
@ -511,10 +499,8 @@ static void refr_position(lv_obj_t * roller, bool anim_en)
#if USE_LV_ANIMATION == 0 #if USE_LV_ANIMATION == 0
anim_en = false; anim_en = false;
#endif #endif
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
if(ext->ddlist.label == NULL) return; /*Probably the roller is being deleted if the label is NULL.*/
lv_obj_t * roller_scrl = lv_page_get_scrl(roller); lv_obj_t * roller_scrl = lv_page_get_scrl(roller);
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label); lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);
const lv_font_t * font = style_label->text.font; const lv_font_t * font = style_label->text.font;
lv_coord_t font_h = lv_font_get_height(font); lv_coord_t font_h = lv_font_get_height(font);