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

lv_group: add edit feature (change to edit moed on ENTER long press)

This commit is contained in:
Gabor Kiss-Vamosi 2018-06-19 11:13:03 +02:00
parent 76bc18cb12
commit ab0b60c584
11 changed files with 156 additions and 25 deletions

View File

@ -22,6 +22,7 @@
* STATIC PROTOTYPES
**********************/
static void style_mod_def(lv_style_t * style);
static void style_mod_edit_def(lv_style_t * style);
/**********************
* STATIC VARIABLES
@ -45,6 +46,7 @@ lv_group_t * lv_group_create(void)
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
group->style_mod = style_mod_def;
group->style_mod_edit = style_mod_edit_def;
group->obj_focus = NULL;
group->frozen = 0;
group->focus_cb = NULL;
@ -247,6 +249,16 @@ void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_func_t sty
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
}
/**
* Set a function for a group which will modify the object's style if it is in focus in edit mode
* @param group pointer to a group
* @param style_mod_func the style modifier function pointer
*/
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_func_t style_mod_func)
{
group->style_mod_edit = style_mod_func;
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
}
/**
* Set a function for a group which will be called when a new object is focused
@ -258,6 +270,31 @@ void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
group->focus_cb = focus_cb;
}
/**
* Enable the switching between edit and navigate mode on long press of LV_GROUP_KEY_ENTER.
* User can get the current mode and decide the whether to send
* LV_GROUP_KEY_PREV/NEXT or LV_GROUP_KEY_LEFT/RIGHT on left/right button.
* useful if there is only one encoder to navigate,
* (push: ENTER; long push: mode switch; left/right: focus or edit)
* @param group pointer to group
* @param en true or false to enable or disable this feature.
*/
void lv_group_set_edit_enabel(lv_group_t * group, bool en)
{
group->edit_mode_en = en ? 1 : 0;
}
/**
* Manually set the current mode (edit or navigate).
* Edit mode needs to be enabled with `lv_group_set_edit_enabel`.
* @param group pointer to group
* @param edit: true: edit mode; false: navigate mode
*/
void lv_group_set_editing(lv_group_t * group, bool edit)
{
group->editing = edit ? 1 : 0;
}
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
@ -268,9 +305,13 @@ lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
{
lv_style_copy(&group->style_tmp, style);
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
else style_mod_def(&group->style_tmp);
if(group->editing) {
if(group->style_mod_edit != NULL) group->style_mod_edit(&group->style_tmp);
else style_mod_edit_def(&group->style_tmp);
} else {
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
else style_mod_def(&group->style_tmp);
}
return &group->style_tmp;
}
@ -297,6 +338,16 @@ lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group)
return group->style_mod ;
}
/**
* Get a the style modifier function of a group in edit mode
* @param group pointer to a group
* @return pointer to the style modifier function
*/
lv_group_style_mod_func_t lv_group_get_style_mod_edit_cb(lv_group_t * group)
{
return group->style_mod_edit;
}
/**
* Get the focus callback function of a group
* @param group pointer to a group
@ -307,6 +358,16 @@ lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group)
return group->focus_cb;
}
/**
* Get the current mode (edit or navigate).
* @param group pointer to group
* @return true: edit mode; false: navigate mode
*/
bool lv_group_get_editing(lv_group_t * group)
{
return group->editing ? true : false;
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -318,6 +379,7 @@ lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group)
static void style_mod_def(lv_style_t * style)
{
#if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_ORANGE;
@ -333,7 +395,36 @@ static void style_mod_def(lv_style_t * style)
#else
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK;
style->body.border.width = 3;
style->body.border.width = 2;
#endif
}
/**
* Default style modifier function
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
*/
static void style_mod_edit_def(lv_style_t * style)
{
#if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_GREEN;
/*If not empty or has border then emphasis the border*/
if(style->body.empty == 0 || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
#else
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK;
style->body.border.width = 2;
#endif

View File

@ -30,8 +30,6 @@ extern "C" {
#define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/
#define LV_GROUP_KEY_PREV 11 /*0x0B, '*/
#define LV_GROUP_KEY_ENTER_LONG 14 /*0x0E, Sent by the library if ENTER is long pressed*/
#if USE_LV_GROUP != 0
/**********************
* TYPEDEFS
@ -46,9 +44,12 @@ typedef struct _lv_group_t
lv_ll_t obj_ll; /*Linked list to store the objects in the group */
lv_obj_t ** obj_focus; /*The object in focus*/
lv_group_style_mod_func_t style_mod; /*A function which modifies the style of the focused object*/
lv_group_style_mod_func_t style_mod_edit;/*A function which modifies the style of the focused object*/
lv_group_focus_cb_t focus_cb; /*A function to call when a new object is focused (optional)*/
lv_style_t style_tmp; /*Stores the modified style of the focused object */
uint8_t frozen:1; /*1: can't focus to new object*/
uint8_t edit_mode_en:1; /*1: By the long press of `LV_GROP_KEY_ENTER` the object can go to edit mode*/
uint8_t editing:1; /*1: Edit mode, 0: Navigate mode*/
} lv_group_t;
/**********************
@ -117,7 +118,14 @@ void lv_group_send_data(lv_group_t * group, uint32_t c);
* @param group pointer to a group
* @param style_mod_func the style modifier function pointer
*/
void lv_group_set_style_mod_cb(lv_group_t * group,lv_group_style_mod_func_t style_mod_func);
void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_func_t style_mod_func);
/**
* Set a function for a group which will modify the object's style if it is in focus in edit mode
* @param group pointer to a group
* @param style_mod_func the style modifier function pointer
*/
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_func_t style_mod_func);
/**
* Set a function for a group which will be called when a new object is focused
@ -126,6 +134,25 @@ void lv_group_set_style_mod_cb(lv_group_t * group,lv_group_style_mod_func_t styl
*/
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
/**
* Enable the switching between edit and navigate mode on long press of LV_GROUP_KEY_ENTER.
* User can get the current mode and decide the whether to send
* LV_GROUP_KEY_PREV/NEXT or LV_GROUP_KEY_LEFT/RIGHT on left/right button.
* useful if there is only one encoder to navigate,
* (push: ENTER; long push: mode switch; left/right: focus or edit)
* @param group pointer to group
* @param en true or false to enable or disable this feature.
*/
void lv_group_set_edit_enabel(lv_group_t * group, bool en);
/**
* Manually set the current mode (edit or navigate).
* Edit mode needs to be enabled with `lv_group_set_edit_enabel`.
* @param group pointer to group
* @param edit: true: edit mode; false: navigate mode
*/
void lv_group_set_editing(lv_group_t * group, bool edit);
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
@ -148,6 +175,13 @@ lv_obj_t * lv_group_get_focused(lv_group_t * group);
*/
lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group);
/**
* Get a the style modifier function of a group in edit mode
* @param group pointer to a group
* @return pointer to the style modifier function
*/
lv_group_style_mod_func_t lv_group_get_style_mod_edit_cb(lv_group_t * group);
/**
* Get the focus callback function of a group
* @param group pointer to a group
@ -155,6 +189,12 @@ lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group);
*/
lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group);
/**
* Get the current mode (edit or navigate).
* @param group pointer to group
* @return true: edit mode; false: navigate mode
*/
bool lv_group_get_editing(lv_group_t * group);
/**********************
* MACROS
**********************/

View File

@ -337,11 +337,13 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
else if(data->state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_PR) {
if(data->key == LV_GROUP_KEY_ENTER &&
i->proc.long_pr_sent == 0 &&
lv_tick_elaps(i->proc.pr_timestamp) > LV_INDEV_LONG_PRESS_TIME) {
lv_group_send_data(i->group, LV_GROUP_KEY_ENTER_LONG);
lv_tick_elaps(i->proc.pr_timestamp) > LV_INDEV_LONG_PRESS_TIME &&
i->group->edit_mode_en)
{
i->group->editing = i->group->editing ? 0 : 1; /*Change between edit and navigate*/
lv_obj_t * focused = lv_group_get_focused(i->group);
if(focused) lv_obj_invalidate(focused);
i->proc.long_pr_sent = 1;
}
}
/*Release happened*/
@ -353,8 +355,10 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
lv_group_focus_next(i->group);
} else if(data->key == LV_GROUP_KEY_PREV) {
lv_group_focus_prev(i->group);
} else if(data->key == LV_GROUP_KEY_ENTER && i->proc.long_pr_sent) {
/*Do nothing. Don't send the ENTER if ENTER_LONG was sent*/
} else if(data->key == LV_GROUP_KEY_ENTER &&
(i->proc.long_pr_sent || (i->group->editing == 0 && i->group->edit_mode_en)))
{
/*Do nothing. Don't send the ENTER if pressed long was sent or in navigation mode*/
} else {
lv_group_send_data(i->group, data->key);
}

View File

@ -389,10 +389,6 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
}
}
ext->long_pr_action_executed = 0;
} else if(c == LV_GROUP_KEY_ENTER_LONG) {
if(ext->actions[LV_BTN_ACTION_LONG_PR] && state != LV_BTN_STATE_INA) {
res = ext->actions[LV_BTN_ACTION_LONG_PR](btn);
}
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;

View File

@ -629,7 +629,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
}
lv_obj_invalidate(btnm);
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
} else if(c == LV_GROUP_KEY_ENTER) {
if(ext->action != NULL) {
uint16_t txt_i = get_button_text(btnm, ext->btn_id_pr);
if(txt_i != LV_BTNM_PR_NONE) {

View File

@ -546,7 +546,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask)
/*Add the month name*/
header_area.y1 += ext->style_header->body.padding.ver;
lv_draw_label(&header_area, mask, ext->style_header, get_month_name(calendar, ext->showed_date.month), opa_scale, LV_TXT_FLAG_CENTER, NULL);
lv_draw_label(&header_area, mask, ext->style_header, opa_scale, get_month_name(calendar, ext->showed_date.month), LV_TXT_FLAG_CENTER, NULL);
/*Add the left arrow*/
lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header;
@ -651,7 +651,7 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask)
week_box_area.y1 -= ext->style_week_box->body.padding.ver;
week_box_area.y2 += ext->style_week_box->body.padding.ver;
lv_draw_rect(&week_box_area, mask, opa_scale, ext->style_week_box);
lv_draw_rect(&week_box_area, mask, ext->style_week_box, opa_scale);
in_week_box = true;
} else {

View File

@ -311,7 +311,7 @@ static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
char c = *((char *)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP ||
c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
c == LV_GROUP_KEY_ENTER) {
lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));
}
} else if(sign == LV_SIGNAL_GET_TYPE) {

View File

@ -551,7 +551,7 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par
lv_ddlist_pos_current_option(ddlist);
lv_obj_invalidate(ddlist);
}
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
} else if(c == LV_GROUP_KEY_ENTER) {
if(ext->opened) {
ext->sel_opt_id_ori = ext->sel_opt_id;
ext->opened = 0;

View File

@ -584,7 +584,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
lv_page_focus(list, btn_prev, ext->anim_time);
}
}
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
} else if(c == LV_GROUP_KEY_ENTER) {
/*Get the 'pressed' button*/
lv_obj_t * btn = NULL;
btn = get_next_btn(list, btn);

View File

@ -323,7 +323,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
if(ext->ddlist.sel_opt_id > 0) {
lv_roller_set_selected(roller, ext->ddlist.sel_opt_id - 1, true);
}
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
} else if(c == LV_GROUP_KEY_ENTER) {
if(ext->ddlist.action) ext->ddlist.action(roller);
ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Set the entered value as default*/
}

View File

@ -244,7 +244,7 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char *)param);
if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ENTER_LONG) {
if(c == LV_GROUP_KEY_ENTER) {
if(lv_sw_get_state(sw)) lv_sw_off(sw);
else lv_sw_on(sw);