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:
parent
76bc18cb12
commit
ab0b60c584
@ -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
|
||||
|
||||
|
@ -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
|
||||
**********************/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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*/
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user