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

feat(dropdown): lv_dropdown_set/get_selected_highlight + minor fixes

This commit is contained in:
Gabor Kiss-Vamosi 2021-02-27 20:34:08 +01:00
parent b1677205b0
commit 347680a3c0
9 changed files with 120 additions and 80 deletions

View File

@ -4,9 +4,11 @@
static void event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
#if LV_USE_LOG /*To avoid warnings if LV_LOG_USER is empty*/
char buf[32];
lv_dropdown_get_selected_str(obj, buf, sizeof(buf));
LV_LOG_USER("Option: %s\n", buf);
LV_LOG_USER("Option: %s", buf);
#endif
}
}

View File

@ -1,32 +1,42 @@
#include "../../../lvgl.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLES
static void event_cb(lv_obj_t * dropdown, lv_event_t e)
{
if(e == LV_EVENT_VALUE_CHANGED) {
char buf[64];
lv_dropdown_get_selected_str(dropdown, buf, sizeof(buf));
LV_LOG_USER("'%s' is selected", buf);
}
}
/**
* Create a menu from a drop-down list and show some drop-down list features and styling
*/
void lv_example_dropdown_3(void)
{
/*Create a drop down list*/
lv_obj_t * dd = lv_dropdown_create(lv_scr_act(), NULL);
lv_obj_align(dd, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10);
lv_dropdown_set_options(dd, "New\n"
"Open\n"
"Edit\n"
"Close\n"
"Preferences\n"
"Exit");
lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act(), NULL);
lv_obj_align(dropdown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
lv_dropdown_set_options(dropdown, "New project\n"
"New file\n"
"Open project\n"
"Recent projects\n"
"Preferences\n"
"Exit");
/*Set a fixed text to display on the button of the drop-down list*/
lv_dropdown_set_text(dd, "Menu");
lv_dropdown_set_text(dropdown, "Menu");
/*Use a custom image as down icon*/
/*Use a custom image as down icon and flip it when the list is opened*/
LV_IMG_DECLARE(img_caret_down)
lv_dropdown_set_symbol(dd, &img_caret_down);
lv_dropdown_set_symbol(dropdown, &img_caret_down);
lv_obj_set_style_transform_angle(dropdown, LV_PART_MAIN, LV_STATE_CHECKED, 1800);
/* Remove the style of the selected part on the list.
* In a menu we don't need to show the last clicked item*/
lv_obj_t * list = lv_dropdown_get_list(dd);
lv_obj_remove_style(list, LV_PART_SELECTED, LV_STATE_DEFAULT, NULL);
/* In a menu we don't need to show the last clicked item*/
lv_dropdown_set_selected_highlight(dropdown, false);
lv_obj_add_event_cb(dropdown, event_cb, NULL);
}
#endif

View File

@ -477,7 +477,7 @@ static void style_init(void)
#if LV_USE_LED
lv_style_init(&styles->led);
style_init_reset(&styles->led);
lv_style_set_bg_opa(&styles->led, LV_OPA_COVER);
lv_style_set_bg_color(&styles->led, lv_color_white());
lv_style_set_bg_grad_color(&styles->led, lv_color_grey());
@ -758,8 +758,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->line_space_large);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_PRESSED, &styles->bg_color_grey);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_SELECTED, LV_STATE_PRESSED, &styles->pressed);
}
#endif

View File

@ -361,8 +361,8 @@ void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en)
void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * ver_area)
{
lv_area_set(hor_area, 0, 0, 0, 0);
lv_area_set(ver_area, 0, 0, 0, 0);
lv_area_set(hor_area, 0, 0, -1, -1);
lv_area_set(ver_area, 0, 0, -1, -1);
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) == false) return;

View File

@ -48,9 +48,13 @@ void lv_obj_del(lv_obj_t * obj)
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_obj_invalidate(obj);
lv_obj_t * par = lv_obj_get_parent(obj);
if(par) {
lv_obj_scrollbar_invalidate(par);
}
lv_disp_t * disp = NULL;
bool act_scr_del = false;
lv_obj_t * par = lv_obj_get_parent(obj);
if(par == NULL) {
disp = lv_obj_get_disp(obj);
if(!disp) return; /*Shouldn't happen*/
@ -93,7 +97,6 @@ void lv_obj_clean(lv_obj_t * obj)
obj->spec_attr->scroll.x = 0;
obj->spec_attr->scroll.y = 0;
}
}
void lv_obj_del_anim_ready_cb(lv_anim_t * a)

View File

@ -140,7 +140,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
#if LV_USE_THEME_DEFAULT
if(lv_theme_default_is_inited() == false) {
disp->theme = lv_theme_default_init(disp, LV_COLOR_PALETTE_BLUE_GREY, LV_COLOR_PALETTE_BLUE, LV_FONT_DEFAULT, LV_FONT_DEFAULT, LV_FONT_DEFAULT);
disp->theme = lv_theme_default_init(disp, LV_COLOR_PALETTE_BLUE_GREY, LV_COLOR_PALETTE_CYAN, LV_FONT_DEFAULT, LV_FONT_DEFAULT, LV_FONT_DEFAULT);
}
#endif

View File

@ -533,7 +533,7 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
return lv_color_black();
}
lv_color_t lv_color_get_palette_accent_1(lv_color_palette_t palette)
lv_color_t lv_color_get_palette_accent_1(lv_color_palette_t palette)
{
switch(palette) {
case LV_COLOR_PALETTE_RED: return lv_color_red_accent_1();
@ -553,7 +553,8 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
case LV_COLOR_PALETTE_ORANGE: return lv_color_orange_accent_1();
case LV_COLOR_PALETTE_DEEP_ORANGE: return lv_color_deep_orange_accent_1();
default:
LV_LOG_WARN("Color palette %d has no accent colors");
LV_LOG_INFO("Color palette %d has no accent colors, use main color instead", palette);
return lv_color_get_palette_main(palette);
}
return lv_color_black();
}
@ -578,7 +579,8 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
case LV_COLOR_PALETTE_ORANGE: return lv_color_orange_accent_2();
case LV_COLOR_PALETTE_DEEP_ORANGE: return lv_color_deep_orange_accent_2();
default:
LV_LOG_WARN("Color palette %d has no accent colors");
LV_LOG_INFO("Color palette %d has no accent colors, use main color instead", palette);
return lv_color_get_palette_main(palette);
}
return lv_color_black();
}
@ -603,7 +605,8 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
case LV_COLOR_PALETTE_ORANGE: return lv_color_orange_accent_3();
case LV_COLOR_PALETTE_DEEP_ORANGE: return lv_color_deep_orange_accent_3();
default:
LV_LOG_WARN("Color palette %d has no accent colors");
LV_LOG_INFO("Color palette %d has no accent colors, use main color instead", palette);
return lv_color_get_palette_main(palette);
}
return lv_color_black();
}
@ -628,7 +631,8 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
case LV_COLOR_PALETTE_ORANGE: return lv_color_orange_accent_4();
case LV_COLOR_PALETTE_DEEP_ORANGE: return lv_color_deep_orange_accent_4();
default:
LV_LOG_WARN("Color palette %d has no accent colors");
LV_LOG_INFO("Color palette %d has no accent colors, use main color instead", palette);
return lv_color_get_palette_main(palette);
}
return lv_color_black();
}

View File

@ -305,6 +305,15 @@ void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol)
lv_obj_invalidate(obj);
}
void lv_dropdown_set_selected_highlight(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_dropdown_t * dropdown = (lv_dropdown_t *) obj;
dropdown->selected_highlight = en;
if(dropdown->list) lv_obj_invalidate(dropdown->list);
}
/*=====================
* Getter functions
*====================*/
@ -381,7 +390,6 @@ void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf
lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_dropdown_t * dropdown = (lv_dropdown_t *) obj;
return dropdown->max_height;
}
@ -389,18 +397,21 @@ lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj)
const char * lv_dropdown_get_symbol(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_dropdown_t * dropdown = (lv_dropdown_t *) obj;
return dropdown->symbol;
}
bool lv_dropdown_get_selected_highlight(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_dropdown_t * dropdown = (lv_dropdown_t *) obj;
return dropdown->selected_highlight;
}
lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_dropdown_t * dropdown = (lv_dropdown_t *) obj;
return dropdown->dir;
}
@ -421,16 +432,16 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj)
lv_obj_clear_flag(dropdown->list, LV_OBJ_FLAG_CLICK_FOCUSABLE);
}
lv_obj_t * label = get_label(dropdown_obj);
lv_label_set_text_static(label, dropdown->options);
lv_obj_set_width(dropdown->list, LV_SIZE_CONTENT);
/*Set smaller width to the width of the button*/
if(lv_obj_get_width(dropdown->list) <= lv_obj_get_width(dropdown_obj) &&
(dropdown->dir == LV_DIR_TOP || dropdown->dir == LV_DIR_BOTTOM)) {
lv_obj_set_width(dropdown->list, lv_obj_get_width(dropdown_obj));
} else {
lv_obj_set_width(dropdown->list, LV_SIZE_CONTENT);
}
lv_obj_t * label = get_label(dropdown_obj);
lv_label_set_text_static(label, dropdown->options);
lv_coord_t label_h = lv_obj_get_height(label);
lv_coord_t top = lv_obj_get_style_pad_top(dropdown->list, LV_PART_MAIN);
@ -450,7 +461,7 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj)
list_h = dropdown_obj->coords.y1 - 1;
}
else {
list_h = LV_VER_RES - dropdown_obj->coords.y2 - 1;
list_h = LV_VER_RES - dropdown_obj->coords.y2 - 1 ;
}
}
}
@ -475,10 +486,10 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj)
position_to_selected(dropdown_obj);
if(dir == LV_DIR_BOTTOM) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
if(dir == LV_DIR_BOTTOM) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
else if(dir == LV_DIR_TOP) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
else if(dir == LV_DIR_LEFT) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_LEFT_TOP, 0, 0);
else if(dir == LV_DIR_RIGHT)lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
else if(dir == LV_DIR_LEFT) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_LEFT_TOP, 0, 0);
else if(dir == LV_DIR_RIGHT) lv_obj_align(dropdown->list, dropdown_obj, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
if(dropdown->dir == LV_DIR_LEFT || dropdown->dir == LV_DIR_RIGHT) {
if(dropdown->list->coords.y2 >= LV_VER_RES) {
@ -532,6 +543,7 @@ static void lv_dropdown_constructor(lv_obj_t * obj, const lv_obj_t * copy)
dropdown->symbol = LV_SYMBOL_DOWN;
dropdown->text = NULL;
dropdown->static_txt = 1;
dropdown->selected_highlight = 1;
dropdown->sel_opt_id = 0;
dropdown->sel_opt_id_orig = 0;
dropdown->pr_opt_id = LV_DROPDOWN_PR_NONE;
@ -713,30 +725,9 @@ static lv_draw_res_t lv_dropdown_list_draw(lv_obj_t * list_obj, const lv_area_t
/*Draw the object*/
else if(mode == LV_DRAW_MODE_MAIN_DRAW) {
lv_obj_draw_base(MY_CLASS_LIST, list_obj, clip_area, mode);
lv_dropdown_list_t * list = (lv_dropdown_list_t *)list_obj;
lv_obj_t * dropdown_obj = list->dropdown;
lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj;
/*Draw the boxes if the page is not being deleted*/
if(dropdown->list) {
/* Clip area might be too large too to shadow but
* the selected option can be drawn on only the background*/
lv_area_t clip_area_core;
bool has_common;
has_common = _lv_area_intersect(&clip_area_core, clip_area, &dropdown->list->coords);
if(has_common) {
if(dropdown->pr_opt_id != LV_DROPDOWN_PR_NONE) {
draw_box(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_PRESSED);
}
draw_box(dropdown_obj, &clip_area_core, dropdown->sel_opt_id, LV_STATE_DEFAULT);
}
}
}
/*Post draw when the children are drawn*/
else if(mode == LV_DRAW_MODE_POST_DRAW) {
lv_obj_draw_base(MY_CLASS_LIST, list_obj, clip_area, mode);
lv_dropdown_list_t * list = (lv_dropdown_list_t *)list_obj;
lv_obj_t * dropdown_obj = list->dropdown;
@ -750,13 +741,23 @@ static lv_draw_res_t lv_dropdown_list_draw(lv_obj_t * list_obj, const lv_area_t
bool has_common;
has_common = _lv_area_intersect(&clip_area_core, clip_area, &dropdown->list->coords);
if(has_common) {
if(dropdown->pr_opt_id != LV_DROPDOWN_PR_NONE) {
if(dropdown->selected_highlight) {
if(dropdown->pr_opt_id == dropdown->sel_opt_id) {
draw_box(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_CHECKED | LV_STATE_PRESSED);
draw_box_label(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_CHECKED | LV_STATE_PRESSED);
} else {
draw_box(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_PRESSED);
draw_box_label(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_PRESSED);
draw_box(dropdown_obj, &clip_area_core, dropdown->sel_opt_id, LV_STATE_CHECKED);
draw_box_label(dropdown_obj, &clip_area_core, dropdown->sel_opt_id, LV_STATE_CHECKED);
}
} else {
draw_box(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_PRESSED);
draw_box_label(dropdown_obj, &clip_area_core, dropdown->pr_opt_id, LV_STATE_PRESSED);
}
draw_box_label(dropdown_obj, &clip_area_core, dropdown->sel_opt_id, LV_STATE_DEFAULT);
}
}
lv_obj_draw_base(MY_CLASS_LIST, list_obj, clip_area, mode);
}
return LV_DRAW_RES_OK;
@ -904,6 +905,8 @@ static lv_res_t lv_dropdown_list_signal(lv_obj_t * list, lv_signal_t sign, void
static void draw_box(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint16_t id, lv_state_t state)
{
if(id == LV_DROPDOWN_PR_NONE) return;
lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj;
lv_obj_t * list_obj = dropdown->list;
lv_state_t state_orig = list_obj->state;
@ -938,6 +941,8 @@ static void draw_box(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint1
static void draw_box_label(lv_obj_t * dropdown_obj, const lv_area_t * clip_area, uint16_t id, lv_state_t state)
{
if(id == LV_DROPDOWN_PR_NONE) return;
lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj;
lv_obj_t * list_obj = dropdown->list;
lv_state_t state_orig = list_obj->state;

View File

@ -37,17 +37,18 @@ LV_EXPORT_CONST_INT(LV_DROPDOWN_POS_LAST);
typedef struct {
lv_obj_t obj;
lv_obj_t * list; /*The dropped down list*/
const char * text; /*Text to display on the ddlist's button*/
const void * symbol; /*Arrow or other icon when the drop-down list is closed*/
char * options;
lv_coord_t max_height; /*Height of the ddlist when opened. (0: auto-size)*/
uint16_t option_cnt; /*Number of options*/
uint16_t sel_opt_id; /*Index of the currently selected option*/
uint16_t sel_opt_id_orig; /*Store the original index on focus*/
uint16_t pr_opt_id; /*Index of the currently pressed option*/
lv_dir_t dir : 4;
uint8_t static_txt : 1;
lv_obj_t * list; /**< The dropped down list*/
const char * text; /**< Text to display on the ddlist's button*/
const void * symbol; /**< Arrow or other icon when the drop-down list is closed*/
char * options; /**< Options in a a '\n' separated list*/
lv_coord_t max_height; /**< Maximal height of the list when opened. (0: no max. height)*/
uint16_t option_cnt; /**< Number of options*/
uint16_t sel_opt_id; /**< Index of the currently selected option*/
uint16_t sel_opt_id_orig; /**< Store the original index on focus*/
uint16_t pr_opt_id; /**< Index of the currently pressed option*/
lv_dir_t dir :4; /**< Direction in which the list should open */
uint8_t static_txt :1; /**< 1: Only a pointer is saved in `options`*/
uint8_t selected_highlight:1; /**< 1: Make the selected option highlighted in the list*/
}lv_dropdown_t;
typedef struct {
@ -140,10 +141,17 @@ void lv_dropdown_set_max_height(lv_obj_t * obj, lv_coord_t h);
* @param obj pointer to drop-down list object
* @param symbol a text like `LV_SYMBOL_DOWN`, an image (pointer or path) or NULL to not draw symbol icon
* @note angle and zoom transformation can be applied if the symbol is an image.
* E.g. when drop down is checked (opened) rotate the symbol by 180
* E.g. when drop down is checked (opened) rotate the symbol by 180 degree
*/
void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol);
/**
* Set whether the selected option in the list should be highlighted or not
* @param obj pointer to drop-down list object
* @param en true: highlight enabled; false: disabled
*/
void lv_dropdown_set_selected_highlight(lv_obj_t * obj, bool en);
/*=====================
* Getter functions
*====================*/
@ -200,11 +208,18 @@ lv_coord_t lv_dropdown_get_max_height(const lv_obj_t * obj);
/**
* Get the symbol on the drop-down list. Typically a down caret or arrow.
* @param obj pointer to drop-down list object
* @return the symbol or NULL if not enabled
* @param obj pointer to drop-down list object
* @return the symbol or NULL if not enabled
*/
const char * lv_dropdown_get_symbol(lv_obj_t * obj);
/**
* Get whether the selected option in the list should be highlighted or not
* @param obj pointer to drop-down list object
* @return true: highlight enabled; false: disabled
*/
bool lv_dropdown_get_selected_highlight(lv_obj_t * obj);
/**
* Get the direction of the drop-down list
* @param obj pointer to a drop-down list object