diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index 6f1aac27b..1c6f1850a 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -297,7 +297,7 @@ void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb) * @param group pointer to group * @param en true or false to enable or disable this feature. */ -void lv_group_set_edit_enable(lv_group_t * group, bool en) +void lv_group_enable_edit(lv_group_t * group, bool en) { group->edit_mode_en = en ? 1 : 0; } @@ -389,6 +389,16 @@ lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group) return group->focus_cb; } +/** + * Get the edit mode is enabled or not. + * @param group pointer to group + * @return true editing is enabled + */ +bool lv_group_get_edit_enable(lv_group_t * group, bool en) +{ + return group->edit_mode_en ? true : false; +} + /** * Get the current mode (edit or navigate). * @param group pointer to group diff --git a/lv_core/lv_group.h b/lv_core/lv_group.h index eaee77759..c77afa86d 100644 --- a/lv_core/lv_group.h +++ b/lv_core/lv_group.h @@ -150,7 +150,7 @@ void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb); * @param group pointer to group * @param en true or false to enable or disable this feature. */ -void lv_group_set_edit_enable(lv_group_t * group, bool en); +void lv_group_enable_edit(lv_group_t * group, bool en); /** * Manually set the current mode (edit or navigate). @@ -203,6 +203,13 @@ 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); +/** + * Get the edit mode is enabled or not. + * @param group pointer to group + * @return true editing is enabled + */ +bool lv_group_get_edit_enable(lv_group_t * group, bool en); + /** * Get the current mode (edit or navigate). * @param group pointer to group diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index 6027e20f9..1fb9727f5 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -355,10 +355,14 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > LV_INDEV_LONG_PRESS_TIME ) { - lv_obj_t * focused = lv_group_get_focused(i->group); - /*If edit mode is enabled then change between edit and navigate on long press*/ - if (i->group->edit_mode_en) { + /*If edit mode is enabled and the focused obejct is editable then change between edit and navigate on long press*/ + lv_obj_t * focused = lv_group_get_focused(i->group); + bool editable = false; + focused->signal_func(focused, LV_SIGNAL_GET_EDITABLE, &editable); + + if (i->group->edit_mode_en && editable) { i->group->editing = i->group->editing ? 0 : 1; + LV_LOG_INFO("Edit mode changed"); if(focused) lv_obj_invalidate(focused); } /*If edit mode is disabled just send a long press signal*/ @@ -373,14 +377,28 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) /*The user might clear the key it was released. Always release the pressed key*/ data->key = i->proc.last_key; - if(data->key == LV_GROUP_KEY_NEXT) { - 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->group->edit_mode_en && i->group->editing == 0)) + if((data->key == LV_GROUP_KEY_NEXT) || + ((i->group->edit_mode_en && i->group->editing == 0) && + (data->key == LV_GROUP_KEY_RIGHT || data->key == LV_GROUP_KEY_DOWN))) { - /*Do nothing. Don't send the ENTER if in navigation mode*/ + lv_group_focus_next(i->group); + } + else if((data->key == LV_GROUP_KEY_PREV) || + ((i->group->edit_mode_en && i->group->editing == 0) && + (data->key == LV_GROUP_KEY_LEFT || data->key == LV_GROUP_KEY_UP))) + { + lv_group_focus_prev(i->group); + } + else if(data->key == LV_GROUP_KEY_ENTER && i->group->edit_mode_en) + { + lv_obj_t * focused = lv_group_get_focused(i->group); + bool editable = false; + focused->signal_func(focused, LV_SIGNAL_GET_EDITABLE, &editable); + /* If an ENTER is released but not long pressed and we are in edit mode or the object is not editable then send the ENTER + * In navigate mode to editable objects and after releasing the long press to change mode do not send ENTER*/ + if(!i->proc.long_pr_sent && (i->group->editing || !editable)) { + lv_group_send_data(i->group, data->key); + } } else { lv_group_send_data(i->group, data->key); } diff --git a/lv_core/lv_obj.h b/lv_core/lv_obj.h index 00e205c23..8c4f1df5f 100644 --- a/lv_core/lv_obj.h +++ b/lv_core/lv_obj.h @@ -104,6 +104,7 @@ typedef enum LV_SIGNAL_FOCUS, LV_SIGNAL_DEFOCUS, LV_SIGNAL_CONTROLL, + LV_SIGNAL_GET_EDITABLE, } lv_signal_t; typedef lv_res_t (* lv_signal_func_t) (struct _lv_obj_t * obj, lv_signal_t sign, void * param); @@ -135,9 +136,9 @@ typedef struct _lv_obj_t uint8_t drag_parent :1; /*1: Parent will be dragged instead*/ uint8_t hidden :1; /*1: Object is hidden*/ uint8_t top :1; /*1: If the object or its children is clicked it goes to the foreground*/ - uint8_t opa_scale_en :1; /*1: opa_scale is set*/ - lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/ + uint8_t opa_scale_en :1; /*1: opa_scale is set*/ uint8_t protect; /*Automatically happening actions can be prevented. 'OR'ed values from lv_obj_prot_t*/ + lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/ lv_coord_t ext_size; /*EXTtend the size of the object in every direction. E.g. for shadow drawing*/ @@ -398,6 +399,14 @@ void lv_obj_set_drag_throw(lv_obj_t * obj, bool en); */ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en); +/** + * Set editable parameter Used by groups and keyboard/encoder control. + * Editable object has something inside to choose (the elements of a list) + * @param obj pointer to an object + * @param en true: enable editing + */ +void lv_obj_set_editable(lv_obj_t * obj, bool en); + /** * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`) * @param obj pointer to an object diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 7de090641..a488923c3 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -505,9 +505,11 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) lv_point_t p; if(sign == LV_SIGNAL_CLEANUP) { lv_mem_free(ext->button_areas); - } else if(sign == LV_SIGNAL_STYLE_CHG || sign == LV_SIGNAL_CORD_CHG) { + } + else if(sign == LV_SIGNAL_STYLE_CHG || sign == LV_SIGNAL_CORD_CHG) { lv_btnm_set_map(btnm, ext->map_p); - } else if(sign == LV_SIGNAL_PRESSING) { + } + else if(sign == LV_SIGNAL_PRESSING) { uint16_t btn_pr; /*Search the pressed area*/ lv_indev_get_point(param, &p); @@ -547,7 +549,8 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } } } - } else if(sign == LV_SIGNAL_RELEASED) { + } + else if(sign == LV_SIGNAL_RELEASED) { if(ext->btn_id_pr != LV_BTNM_PR_NONE) { if(ext->action) { uint16_t txt_i = get_button_text(btnm, ext->btn_id_pr); @@ -589,10 +592,12 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) ext->btn_id_pr = LV_BTNM_PR_NONE; #endif } - } else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) { + } + else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) { ext->btn_id_pr = LV_BTNM_PR_NONE; lv_obj_invalidate(btnm); - } else if(sign == LV_SIGNAL_FOCUS) { + } + else if(sign == LV_SIGNAL_FOCUS) { #if USE_LV_GROUP lv_indev_t * indev = lv_indev_get_act(); if(lv_obj_is_focused(btnm) && lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { @@ -600,12 +605,15 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) lv_indev_get_point(indev, &p); uint16_t btn_i = get_button_from_point(btnm, &p); ext->btn_id_pr = btn_i; + } else { + ext->btn_id_pr = 0; } #else ext->btn_id_pr = 0; #endif lv_obj_invalidate(btnm); - } else if(sign == LV_SIGNAL_CONTROLL) { + } + else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char *)param); if(c == LV_GROUP_KEY_RIGHT) { if(ext->btn_id_pr == LV_BTNM_PR_NONE) ext->btn_id_pr = 0; @@ -616,7 +624,8 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) if(ext->btn_id_pr == LV_BTNM_PR_NONE) ext->btn_id_pr = 0; if(ext->btn_id_pr > 0) ext->btn_id_pr--; lv_obj_invalidate(btnm); - } else if(c == LV_GROUP_KEY_DOWN) { + } + else if(c == LV_GROUP_KEY_DOWN) { lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG); /*Find the area below the the current*/ if(ext->btn_id_pr == LV_BTNM_PR_NONE) { @@ -636,7 +645,8 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) if(area_below < ext->btn_cnt) ext->btn_id_pr = area_below; } lv_obj_invalidate(btnm); - } else if(c == LV_GROUP_KEY_UP) { + } + else if(c == LV_GROUP_KEY_UP) { lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG); /*Find the area below the the current*/ if(ext->btn_id_pr == LV_BTNM_PR_NONE) { @@ -656,22 +666,29 @@ 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) { + } + 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) { ext->action(btnm, cut_ctrl_byte(ext->map_p[txt_i])); } } - } else if(sign == LV_SIGNAL_GET_TYPE) { - lv_obj_type_t * buf = param; - uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ - if(buf->type[i] == NULL) break; - } - buf->type[i] = "lv_btnm"; } } + else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; + } + else if(sign == LV_SIGNAL_GET_TYPE) { + lv_obj_type_t * buf = param; + uint8_t i; + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + if(buf->type[i] == NULL) break; + } + buf->type[i] = "lv_btnm"; + } + return res; } diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index 700d22ecc..b8fde2a42 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -574,6 +574,9 @@ static lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * par lv_ddlist_refr_size(ddlist, true); } } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index 3b6f228fa..a2fa39d20 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -570,6 +570,9 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param) lv_btn_set_state(btn, LV_BTN_STATE_REL); } last_clicked_btn = NULL; /*button click will set if comes before focus*/ + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; } else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char *)param); if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) { diff --git a/lv_objx/lv_mbox.c b/lv_objx/lv_mbox.c index f2e669c8f..a3fc331e8 100644 --- a/lv_objx/lv_mbox.c +++ b/lv_objx/lv_mbox.c @@ -387,9 +387,13 @@ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_STYLE_CHG) { mbox_realign(mbox); - } else if(sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS || sign == LV_SIGNAL_CONTROLL) { + } else if(sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS || + sign == LV_SIGNAL_CONTROLL || sign == LV_SIGNAL_GET_EDITABLE) { if(ext->btnm) { - ext->btnm->signal_func(ext->btnm, sign, param); + + + + ext->btnm->signal_func(ext->btnm, sign, param); } } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index 7fe973fb0..eb8b48788 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -271,7 +271,7 @@ lv_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page) * @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) +bool lv_page_get_arrow_scroll(lv_obj_t * page) { lv_page_ext_t * ext = lv_obj_get_ext_attr(page); return ext->arrow_scroll ? true : false; @@ -612,6 +612,9 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) lv_obj_set_y(scrl, lv_obj_get_y(scrl) + lv_obj_get_height(page) / 4); #endif } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = lv_page_get_arrow_scroll(page); } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_page.h b/lv_objx/lv_page.h index afd89aae1..773a2e306 100644 --- a/lv_objx/lv_page.h +++ b/lv_objx/lv_page.h @@ -199,7 +199,7 @@ lv_sb_mode_t lv_page_get_sb_mode(lv_obj_t * page); * @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); +bool lv_page_get_arrow_scroll(lv_obj_t * page); /** * Get width of the scrollable part of a page diff --git a/lv_objx/lv_slider.c b/lv_objx/lv_slider.c index b400d6763..2dcc8db02 100644 --- a/lv_objx/lv_slider.c +++ b/lv_objx/lv_slider.c @@ -462,6 +462,9 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par lv_slider_set_value(slider, lv_slider_get_value(slider) - 1); if(ext->action != NULL) ext->action(slider); } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index b9ff4ed23..47954f089 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -261,6 +261,9 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) lv_sw_off(sw); if(slider_action) slider_action(sw); } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = false; /*The ancestor slider is editable the switch is not*/ } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 82811fcff..496057b66 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -236,6 +236,10 @@ void lv_ta_add_text(lv_obj_t * ta, const char * txt) if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/ /*Insert the text*/ + + + + lv_label_ins_text(ext->label, ext->cursor.pos, txt); if(ext->pwd_mode != 0) { @@ -983,6 +987,9 @@ static lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param) #endif } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_tabview.c b/lv_objx/lv_tabview.c index e878cd5d0..9d76c43bc 100644 --- a/lv_objx/lv_tabview.c +++ b/lv_objx/lv_tabview.c @@ -579,6 +579,9 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p if(ext->btns) { ext->btns->signal_func(ext->btns, sign, param); } + } else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i;