lv_group: add click_focus option
This commit is contained in:
@@ -50,6 +50,9 @@ lv_group_t * lv_group_create(void)
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
group->focus_cb = NULL;
|
||||
group->click_focus = 1;
|
||||
group->edit_mode_en = 0;
|
||||
group->editing = 0;
|
||||
|
||||
return group;
|
||||
}
|
||||
@@ -141,6 +144,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
lv_obj_t ** i;
|
||||
LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus == i) return; /*Don't focus the already focused object again*/
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
@@ -150,6 +154,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
||||
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
if(g->focus_cb) g->focus_cb(g);
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
@@ -295,6 +300,16 @@ void lv_group_set_editing(lv_group_t * group, bool edit)
|
||||
group->editing = edit ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en)
|
||||
{
|
||||
group->click_focus = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
@@ -322,7 +337,7 @@ lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(lv_group_t * group)
|
||||
{
|
||||
if(group == NULL) return NULL;
|
||||
if(!group) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
@@ -335,6 +350,7 @@ 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)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod ;
|
||||
}
|
||||
|
||||
@@ -345,6 +361,7 @@ lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group)
|
||||
*/
|
||||
lv_group_style_mod_func_t lv_group_get_style_mod_edit_cb(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod_edit;
|
||||
}
|
||||
|
||||
@@ -355,6 +372,7 @@ lv_group_style_mod_func_t lv_group_get_style_mod_edit_cb(lv_group_t * group)
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->focus_cb;
|
||||
}
|
||||
|
||||
@@ -365,9 +383,21 @@ lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group)
|
||||
*/
|
||||
bool lv_group_get_editing(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->editing ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->click_focus ? true : false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
@@ -52,9 +52,10 @@ typedef struct _lv_group_t
|
||||
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*/
|
||||
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*/
|
||||
uint8_t click_focus :1; /*1: If an object in a group is clicked by an indev then it will be focused */
|
||||
} lv_group_t;
|
||||
|
||||
/**********************
|
||||
@@ -152,12 +153,19 @@ void lv_group_set_edit_enable(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`.
|
||||
* Edit mode needs to be enabled with `lv_group_set_edit_enable`.
|
||||
* @param group pointer to group
|
||||
* @param edit: true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit);
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
@@ -200,6 +208,15 @@ lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group);
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(lv_group_t * group);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -542,6 +542,23 @@ static void indev_proc_release(lv_indev_proc_t * proc)
|
||||
/*Forgot the act obj and send a released signal */
|
||||
if(proc->act_obj != NULL) {
|
||||
proc->act_obj->signal_func(proc->act_obj, LV_SIGNAL_RELEASED, indev_act);
|
||||
|
||||
/*Handle click focus*/
|
||||
#if USE_LV_GROUP
|
||||
lv_group_t * g = lv_obj_get_group(proc->act_obj);
|
||||
lv_obj_t * parent = proc->act_obj;
|
||||
while(g == NULL) {
|
||||
parent = lv_obj_get_parent(parent);
|
||||
if(parent == NULL) break;
|
||||
g = lv_obj_get_group(parent);
|
||||
}
|
||||
|
||||
if(g != NULL && parent != NULL)
|
||||
if(lv_group_get_click_focus(g)) {
|
||||
lv_group_focus_obj(parent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(proc->reset_query != 0) return;
|
||||
proc->act_obj = NULL;
|
||||
proc->pr_timestamp = 0;
|
||||
|
||||
@@ -219,7 +219,6 @@ static void line_draw_skew(line_draw_t * main_line, const lv_area_t * mask, cons
|
||||
vect_norm.x = vect_norm.x << 4;
|
||||
vect_norm.y = vect_norm.y << 4;
|
||||
|
||||
printf("width %d\n", width);
|
||||
#if LV_COMPILER_VLA_SUPPORTED
|
||||
lv_point_t pattern[width_safe];
|
||||
#else
|
||||
|
||||
@@ -569,7 +569,17 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
ext->btn_id_tgl = ext->btn_id_pr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if USE_LV_GROUP
|
||||
/*Leave the clicked button as pressed if this the focused object in a group*/
|
||||
lv_group_t * g = lv_obj_get_group(btnm);
|
||||
if(lv_group_get_focused(g) != btnm) {
|
||||
ext->btn_id_pr = LV_BTNM_PR_NONE;
|
||||
}
|
||||
#else
|
||||
ext->btn_id_pr = LV_BTNM_PR_NONE;
|
||||
#endif
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
|
||||
ext->btn_id_pr = LV_BTNM_PR_NONE;
|
||||
|
||||
@@ -532,14 +532,14 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
btn = get_next_btn(list, btn);
|
||||
}
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_TGL_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_TGL_REL) break;
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
@@ -555,40 +555,58 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
btn = get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_TGL_REL) break;
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn_prev = btn;
|
||||
btn = get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
/*If there is a valid "pressed" button the make the next "pressed"*/
|
||||
if(btn_prev != NULL && btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_TGL_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_prev, ext->anim_time);
|
||||
}
|
||||
/*If there is no "pressed" button the make the first "pressed"*/
|
||||
else {
|
||||
btn = get_next_btn(list, NULL);
|
||||
if(btn) { /*If there are no buttons on the list hen there is no first button*/
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn, ext->anim_time);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
/*Get the last pressed button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
|
||||
btn = get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_TGL_REL) break;
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
/*If there is a valid "pressed" button the make the next "pressed"*/
|
||||
if(btn != NULL) {
|
||||
lv_obj_t * btn_prev = get_next_btn(list, btn);
|
||||
if(btn_prev != NULL) {
|
||||
lv_obj_t * btn_next = get_next_btn(list, btn);
|
||||
if(btn_next != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_TGL_REL);
|
||||
lv_page_focus(list, btn_prev, ext->anim_time);
|
||||
lv_btn_set_state(btn_next, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_next, ext->anim_time);
|
||||
}
|
||||
}
|
||||
/*If there is no "pressed" button the make the first "pressed"*/
|
||||
else {
|
||||
btn = get_next_btn(list, NULL);
|
||||
if(btn) { /*If there are no buttons on the list hen there is no first button*/
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn, ext->anim_time);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_TGL_REL) break;
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->sb.ver_draw = 0;
|
||||
ext->sb.style = &lv_style_pretty;
|
||||
ext->sb.mode = LV_SB_MODE_AUTO;
|
||||
ext->arrow_scroll = 0;
|
||||
|
||||
/*Init the new page object*/
|
||||
if(copy == NULL) {
|
||||
@@ -117,6 +118,8 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
lv_page_set_pr_action(new_page, copy_ext->pr_action);
|
||||
lv_page_set_rel_action(new_page, copy_ext->rel_action);
|
||||
lv_page_set_sb_mode(new_page, copy_ext->sb.mode);
|
||||
lv_page_set_arrow_scroll(new_page, copy_ext->arrow_scroll);
|
||||
|
||||
|
||||
lv_page_set_style(new_page, LV_PAGE_STYLE_BG, lv_page_get_style(copy, LV_PAGE_STYLE_BG));
|
||||
lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, lv_page_get_style(copy, LV_PAGE_STYLE_SCRL));
|
||||
@@ -175,7 +178,7 @@ void lv_page_set_pr_action(lv_obj_t * page, lv_action_t pr_action)
|
||||
/**
|
||||
* Set the scroll bar mode on a page
|
||||
* @param page pointer to a page object
|
||||
* @param sb.mode the new mode from 'lv_page_sb.mode_t' enum
|
||||
* @param sb_mode the new mode from 'lv_page_sb.mode_t' enum
|
||||
*/
|
||||
void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)
|
||||
{
|
||||
@@ -189,6 +192,17 @@ void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)
|
||||
lv_obj_invalidate(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable scrolling with arrows if the page is in group (arrows: LV_GROUP_KEY_LEFT/RIGHT/UP/DOWN)
|
||||
* @param page pointer to a page object
|
||||
* @param en true: enable scrolling with arrows
|
||||
*/
|
||||
void lv_page_set_arrow_scroll(lv_obj_t * page, bool en)
|
||||
{
|
||||
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
|
||||
ext->arrow_scroll = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a style of a page
|
||||
* @param page pointer to a page object
|
||||
@@ -244,6 +258,17 @@ lv_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page)
|
||||
return ext->sb.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the the scrolling with arrows (LV_GROUP_KEY_LEFT/RIGHT/UP/DOWN) is enabled or not
|
||||
* @param page pointer to a page object
|
||||
* @return true: scrolling with arrows is enabled
|
||||
*/
|
||||
bool lv_page_get_arrow_scroll(lv_obj_t * page, bool en)
|
||||
{
|
||||
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
|
||||
return ext->arrow_scroll ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a style of a page
|
||||
* @param page pointer to page object
|
||||
@@ -538,12 +563,13 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
uint32_t c = *((uint32_t *) param);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(page);
|
||||
if(c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_RIGHT) {
|
||||
|
||||
if((c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_RIGHT) && ext->arrow_scroll) {
|
||||
#if USE_LV_ANIMATION
|
||||
lv_anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = a.start - LV_DPI / 2;
|
||||
a.end = a.start - lv_obj_get_height(page) / 4;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
@@ -555,15 +581,15 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
#else
|
||||
lv_obj_set_y(scrl, lv_obj_get_y(scrl) - LV_DPI / 2);
|
||||
lv_obj_set_y(scrl, lv_obj_get_y(scrl) - lv_obj_get_height(page) / 4);
|
||||
#endif
|
||||
|
||||
} else if(c == LV_GROUP_KEY_UP || c == LV_GROUP_KEY_LEFT) {
|
||||
} else if((c == LV_GROUP_KEY_UP || c == LV_GROUP_KEY_LEFT) && ext->arrow_scroll) {
|
||||
#if USE_LV_ANIMATION
|
||||
lv_anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = a.start + LV_DPI / 2;
|
||||
a.end = a.start + lv_obj_get_height(page) / 4;
|
||||
a.fp = (lv_anim_fp_t)lv_obj_set_y;
|
||||
a.path = lv_anim_path_linear;
|
||||
a.end_cb = NULL;
|
||||
@@ -575,7 +601,7 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
a.repeat_pause = 0;
|
||||
lv_anim_create(&a);
|
||||
#else
|
||||
lv_obj_set_y(scrl, lv_obj_get_y(scrl) - LV_DPI / 2);
|
||||
lv_obj_set_y(scrl, lv_obj_get_y(scrl) + lv_obj_get_height(page) / 4);
|
||||
#endif
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_GET_TYPE) {
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef struct
|
||||
uint8_t ver_draw :1; /*1: vertical scrollbar is visible now (Handled by the library)*/
|
||||
uint8_t mode :3; /*Scrollbar visibility from 'lv_page_sb_mode_t'*/
|
||||
} sb;
|
||||
uint8_t arrow_scroll :1; /*1: Enable scrolling with LV_GROUP_KEY_LEFT/RIGHT/UP/DOWN*/
|
||||
} lv_page_ext_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -118,10 +119,17 @@ void lv_page_set_pr_action(lv_obj_t * page, lv_action_t pr_action);
|
||||
/**
|
||||
* Set the scroll bar mode on a page
|
||||
* @param page pointer to a page object
|
||||
* @param sb.mode the new mode from 'lv_page_sb.mode_t' enum
|
||||
* @param sb_mode the new mode from 'lv_page_sb.mode_t' enum
|
||||
*/
|
||||
void lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode);
|
||||
|
||||
/**
|
||||
* Enable/Disable scrolling with arrows if the page is in group (arrows: LV_GROUP_KEY_LEFT/RIGHT/UP/DOWN)
|
||||
* @param page pointer to a page object
|
||||
* @param en true: enable scrolling with arrows
|
||||
*/
|
||||
void lv_page_set_arrow_scroll(lv_obj_t * page, bool en);
|
||||
|
||||
/**
|
||||
* Set the fit attribute of the scrollable part of a page.
|
||||
* It means it can set its size automatically to involve all children.
|
||||
@@ -185,6 +193,14 @@ void lv_page_set_style(lv_obj_t *page, lv_page_style_t type, lv_style_t *style);
|
||||
*/
|
||||
lv_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page);
|
||||
|
||||
|
||||
/**
|
||||
* Get the the scrolling with arrows (LV_GROUP_KEY_LEFT/RIGHT/UP/DOWN) is enabled or not
|
||||
* @param page pointer to a page object
|
||||
* @return true: scrolling with arrows is enabled
|
||||
*/
|
||||
bool lv_page_get_arrow_scroll(lv_obj_t * page, bool en);
|
||||
|
||||
/**
|
||||
* Get width of the scrollable part of a page
|
||||
* @param page pointer to a page object
|
||||
|
||||
Reference in New Issue
Block a user