diff --git a/lv_core/lv_obj.c b/lv_core/lv_obj.c index aef9cb28a..52e3e64a6 100644 --- a/lv_core/lv_obj.c +++ b/lv_core/lv_obj.c @@ -190,6 +190,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->opa_scale_en = 0; new_obj->protect = LV_PROTECT_NONE; new_obj->opa_scale = LV_OPA_COVER; + new_obj->parent_event = 0; new_obj->ext_attr = NULL; @@ -299,6 +300,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->drag_parent = copy->drag_parent; new_obj->hidden = copy->hidden; new_obj->top = copy->top; + new_obj->parent_event = copy->parent_event; new_obj->opa_scale_en = copy->opa_scale_en; new_obj->protect = copy->protect; @@ -1104,6 +1106,16 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en) obj->drag_parent = (en == true ? 1 : 0); } +/** + * Propagate the events to the parent too + * @param obj pointer to an object + * @param en true: enable the event propagation + */ +void lv_obj_set_parent_event(lv_obj_t * obj, bool en) +{ + obj->parent_event = (en == true ? 1 : 0); +} + /** * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`) * @param obj pointer to an object @@ -1174,7 +1186,7 @@ lv_res_t lv_obj_send_event(lv_obj_t * obj, lv_event_t event) if(obj_act_event_deleted) return LV_RES_INV; - if(obj->event_parent && obj->par) { + if(obj->parent_event && obj->par) { lv_res_t res = lv_obj_send_event(obj->par, event); if(res != LV_RES_OK) return LV_RES_INV; } @@ -1638,6 +1650,16 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj) return obj->drag_parent == 0 ? false : true; } +/** + * Get the drag parent attribute of an object + * @param obj pointer to an object + * @return true: drag parent is enabled + */ +bool lv_obj_get_parent_event(const lv_obj_t * obj) +{ + return obj->parent_event == 0 ? false : true; +} + /** * Get the opa scale enable parameter * @param obj pointer to an object diff --git a/lv_core/lv_obj.h b/lv_core/lv_obj.h index b9903025d..7bd61feca 100644 --- a/lv_core/lv_obj.h +++ b/lv_core/lv_obj.h @@ -192,7 +192,7 @@ typedef struct _lv_obj_t 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*/ - uint8_t event_parent :1; /*1: Send the object's events to the parent too. */ + uint8_t parent_event :1; /*1: Send the object's events to the parent too. */ uint8_t protect; /*Automatically happening actions can be prevented. 'OR'ed values from `lv_protect_t`*/ lv_opa_t opa_scale; /*Scale down the opacity by this factor. Effects all children as well*/ @@ -454,12 +454,11 @@ 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) + * Propagate the events to the parent too * @param obj pointer to an object - * @param en true: enable editing + * @param en true: enable the event propagation */ -//void lv_obj_set_editable(lv_obj_t * obj, bool en); +void lv_obj_set_parent_event(lv_obj_t * obj, bool en); /** * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`) @@ -721,6 +720,12 @@ bool lv_obj_get_drag_throw(const lv_obj_t * obj); */ bool lv_obj_get_drag_parent(const lv_obj_t * obj); +/** + * Get the drag parent attribute of an object + * @param obj pointer to an object + * @return true: drag parent is enabled + */ +bool lv_obj_get_parent_event(const lv_obj_t * obj); /** * Get the opa scale enable parameter diff --git a/lv_misc/lv_txt.c b/lv_misc/lv_txt.c index ded96332a..36b1a3bb3 100644 --- a/lv_misc/lv_txt.c +++ b/lv_misc/lv_txt.c @@ -437,7 +437,7 @@ static uint8_t lv_txt_utf8_size(const char * str) else if((str[0] & 0xE0) == 0xC0) return 2; else if((str[0] & 0xF0) == 0xE0) return 3; else if((str[0] & 0xF8) == 0xF0) return 4; - return 0; + return 1; /*If the char was invalid step tell it's 1 byte long*/ } @@ -616,7 +616,6 @@ static uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id) } return byte_cnt; - } diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 3cb724b84..582f1a866 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -43,7 +43,7 @@ static bool maps_are_identical(const char ** map1, const char ** map2); * STATIC VARIABLES **********************/ static const char * lv_btnm_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", - "\002Btn4", "Btn5", "" + "Btn4", "Btn5", "" }; static lv_design_cb_t ancestor_design_f; @@ -80,7 +80,7 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy) if(ext == NULL) return NULL; ext->btn_cnt = 0; - ext->btn_id_pr = LV_BTNM_PR_NONE; + ext->btn_id_pr = LV_BTNM_BTN_NONE; ext->button_areas = NULL; ext->ctrl_bits = NULL; ext->map_p = NULL; @@ -277,13 +277,13 @@ void lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t * ctrl_map * Set the pressed button i.e. visually highlight it. * Mainly used a when the btnm is in a group to show the selected button * @param btnm pointer to button matrix object - * @param id index of the currently pressed button (`LV_BTNM_PR_NONE` to unpress) + * @param id index of the currently pressed button (`LV_BTNM_BTN_NONE` to unpress) */ void lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); - if (id >= ext->btn_cnt && id != LV_BTNM_PR_NONE) + if (id >= ext->btn_cnt && id != LV_BTNM_BTN_NONE) return; if (id == ext->btn_id_pr) @@ -354,10 +354,8 @@ void lv_btnm_set_btn_hidden(const lv_obj_t * btnm, uint16_t btn_idx, bool hidden { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); if (btn_idx >= ext->btn_cnt) return; - if (hidden) - ext->ctrl_bits[btn_idx] |= LV_BTNM_BTN_HIDDEN; - else - ext->ctrl_bits[btn_idx] &= (~LV_BTNM_BTN_HIDDEN); + if (hidden) ext->ctrl_bits[btn_idx] |= LV_BTNM_BTN_HIDDEN; + else ext->ctrl_bits[btn_idx] &= (~LV_BTNM_BTN_HIDDEN); invalidate_button_area(btnm, btn_idx); } @@ -366,14 +364,14 @@ void lv_btnm_set_btn_hidden(const lv_obj_t * btnm, uint16_t btn_idx, bool hidden * Enable/disable a single button in the matrix * @param btnm pointer to button matrix object * @param btn_id 0 based index of the button to modify. - * @param disabled true: disable the button + * @param ina true: make the button inactive */ -void lv_btnm_set_btn_inactive(const lv_obj_t * btnm, uint16_t btn_id, bool disabled) +void lv_btnm_set_btn_inactive(const lv_obj_t * btnm, uint16_t btn_id, bool ina) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); if (btn_id >= ext->btn_cnt) return; - if (disabled)ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_INACTIVE; + if (ina) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_INACTIVE; else ext->ctrl_bits[btn_id] &= (~LV_BTNM_BTN_INACTIVE); invalidate_button_area(btnm, btn_id); @@ -383,46 +381,58 @@ void lv_btnm_set_btn_inactive(const lv_obj_t * btnm, uint16_t btn_id, bool disab * Enable/disable long press for a single button in the matrix * @param btnm pointer to button matrix object * @param btn_id 0 based index of the button to modify. - * @param disabled true: disable repeat + * @param no_rep true: disable repeat */ -void lv_btnm_set_btn_no_repeat(const lv_obj_t * btnm, uint16_t btn_id, bool disabled) +void lv_btnm_set_btn_no_repeat(const lv_obj_t * btnm, uint16_t btn_id, bool no_rep) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); if (btn_id >= ext->btn_cnt) return; - if (disabled) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_NO_REPEAT; + if (no_rep) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_NO_REPEAT; else ext->ctrl_bits[btn_id] &= (~LV_BTNM_BTN_NO_REPEAT); +} - invalidate_button_area(btnm, btn_id); +/** + * Enable/disable toggling a single button in the matrix + * @param btnm pointer to button matrix object + * @param btn_id 0 based index of the button to modify. + * @param tgl true: toggle enable + */ +void lv_btnm_set_btn_toggle(const lv_obj_t * btnm, uint16_t btn_id, bool tgl) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + if (btn_id >= ext->btn_cnt) return; + if (tgl) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_TOGGLE; + else ext->ctrl_bits[btn_id] &= (~LV_BTNM_BTN_TOGGLE); } /** * Make the a single button button toggled or not toggled. * @param btnm pointer to button matrix object * @param btn_id index of button (not counting "\n") - * @param en true: enable toggling; false: disable toggling + * @param state true: toggled; false: not toggled */ -void lv_btnm_set_btn_toggle_state(lv_obj_t * btnm, uint16_t btn_id, bool toggle) +void lv_btnm_set_btn_toggle_state(lv_obj_t * btnm, uint16_t btn_id, bool state) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); if (btn_id >= ext->btn_cnt) return; - if(toggle) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_TOGGLE_STATE; - else ext->ctrl_bits[btn_id] &= LV_BTNM_BTN_TOGGLE_STATE; + if(state) ext->ctrl_bits[btn_id] |= LV_BTNM_BTN_TOGGLE_STATE; + else ext->ctrl_bits[btn_id] &= (~LV_BTNM_BTN_TOGGLE_STATE); invalidate_button_area(btnm, btn_id); - - lv_obj_invalidate(btnm); } /** * Set hidden/disabled/repeat flags for a single button. * @param btnm pointer to button matrix object - * @param btn_idx 0 based index of the button to modify. + * @param btn_id 0 based index of the button to modify. * @param hidden true: hide the button - * @param disabled true: disable the button - * @param disable_repeat true: disable repeat + * @param inactive true: disable the button + * @param no_repeat true: disable repeat + * @param toggle true: enable toggling + * @param toggled_state true: set toggled state */ -void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, bool disabled, bool disable_repeat, bool toggle, bool toggle_state) +void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, bool inactive, bool no_repeat, bool toggle, bool toggle_state) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); if (btn_id >= ext->btn_cnt) return; @@ -430,7 +440,8 @@ void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, uint8_t flags = ext->ctrl_bits[btn_id]; flags = hidden ? flags | LV_BTNM_BTN_HIDDEN : flags & (~LV_BTNM_BTN_HIDDEN); - flags = disabled ? flags | LV_BTNM_BTN_INACTIVE : flags & (~LV_BTNM_BTN_INACTIVE); + flags = inactive ? flags | LV_BTNM_BTN_INACTIVE : flags & (~LV_BTNM_BTN_INACTIVE); + flags = no_repeat ? flags | LV_BTNM_BTN_NO_REPEAT : flags & (~LV_BTNM_BTN_NO_REPEAT); flags = toggle ? flags | LV_BTNM_BTN_TOGGLE : flags & (~LV_BTNM_BTN_TOGGLE); flags = toggle_state ? flags | LV_BTNM_BTN_TOGGLE_STATE : flags & (~LV_BTNM_BTN_TOGGLE_STATE); @@ -459,6 +470,22 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width lv_btnm_set_map(btnm, ext->map_p); } +/** + * Set the toggle state of all buttons + * @param btnm pointer to a button matrix object + * @param state true: toggled; false: not toggled + */ +void lv_btnm_set_btn_toggle_state_all(lv_obj_t * btnm, bool state) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + uint16_t i; + for(i = 0; i < ext->btn_cnt; i++) { + if(state) ext->ctrl_bits[i] |= LV_BTNM_BTN_TOGGLE_STATE; + else ext->ctrl_bits[i] &= (~LV_BTNM_BTN_TOGGLE_STATE); + } + + lv_obj_invalidate(btnm); +} /*===================== * Getter functions @@ -491,19 +518,36 @@ bool lv_btnm_get_recolor(const lv_obj_t * btnm) * Get the index of the lastly "activated" button by the user (pressed, released etc) * Useful in the the `event_cb` to get the text of the button, check if hidden etc. * @param btnm pointer to button matrix object - * @return index of the last released button (LV_BTNM_PR_NONE: if unset) + * @return index of the last released button (LV_BTNM_BTN_NONE: if unset) */ uint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); - return ext->btn_id_pr; + return ext->btn_id_act; } +/** + * Get the text of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb` + * @param btnm pointer to button matrix object + * @return text of the last released button (NULL: if unset) + */ +const char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + if(ext->btn_id_act != LV_BTNM_BTN_NONE) { + return lv_btnm_get_btn_text(btnm, ext->btn_id_act); + } else { + return NULL; + } +} + + /** * Get the pressed button's index. * The button be really pressed by the user or manually set to pressed with `lv_btnm_set_pressed` * @param btnm pointer to button matrix object - * @return index of the pressed button (LV_BTNM_PR_NONE: if unset) + * @return index of the pressed button (LV_BTNM_BTN_NONE: if unset) */ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm) { @@ -517,10 +561,10 @@ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm) * @param btn_index the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return text of btn_index` button */ -uint16_t lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id) +const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); - if(btn_id > ext->btn_cnt) return LV_BTNM_PR_NONE; + if(btn_id > ext->btn_cnt) return NULL; uint16_t txt_i = 0; uint16_t btn_i = 0; @@ -533,9 +577,9 @@ uint16_t lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id) if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++; } - if(btn_i == ext->btn_cnt) return LV_BTNM_PR_NONE; + if(btn_i == ext->btn_cnt) return NULL; - return txt_i; + return ext->map_p[txt_i]; } /** @@ -545,7 +589,7 @@ uint16_t lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id) * @param btn_index the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: long press repeat is disabled; false: long press repeat enabled */ -bool lv_btnm_is_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id) +bool lv_btnm_get_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); return button_is_repeat_disabled(ext->ctrl_bits[btn_id]); @@ -558,7 +602,7 @@ bool lv_btnm_is_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id) * @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: hidden; false: not hidden */ -bool lv_btnm_is_btn_hidden(lv_obj_t * btnm, uint16_t btn_id) +bool lv_btnm_get_btn_hidden(lv_obj_t * btnm, uint16_t btn_id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); return button_is_hidden(ext->ctrl_bits[btn_id]); @@ -571,7 +615,7 @@ bool lv_btnm_is_btn_hidden(lv_obj_t * btnm, uint16_t btn_id) * @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: inactive; false: not inactive */ -bool lv_btnm_is_btn_inactive(lv_obj_t * btnm, uint16_t btn_id) +bool lv_btnm_get_btn_inactive(lv_obj_t * btnm, uint16_t btn_id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); return button_is_inactive(ext->ctrl_bits[btn_id]); @@ -581,7 +625,7 @@ bool lv_btnm_is_btn_inactive(lv_obj_t * btnm, uint16_t btn_id) * @param btnm pointer to button matrix object * @return btn_id index a of a button not counting "\n". (The return value of lv_btnm_get_pressed/released) */ -bool lv_btnm_is_btn_toggle(const lv_obj_t * btnm, int16_t btn_id) +bool lv_btnm_get_btn_toggle(const lv_obj_t * btnm, int16_t btn_id) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); @@ -781,8 +825,11 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) lv_indev_get_point(param, &p); btn_pr = get_button_from_point(btnm, &p); + invalidate_button_area(btnm, ext->btn_id_pr) /*Invalidate the old area*/; ext->btn_id_pr = btn_pr; ext->btn_id_act = btn_pr; + invalidate_button_area(btnm, ext->btn_id_pr); /*Invalidate the new area*/ + } else if(sign == LV_SIGNAL_PRESSING) { uint16_t btn_pr; @@ -792,10 +839,10 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) /*Invalidate to old and the new areas*/; if(btn_pr != ext->btn_id_pr) { lv_indev_reset_lpr(param); - if(ext->btn_id_pr != LV_BTNM_PR_NONE) { + if(ext->btn_id_pr != LV_BTNM_BTN_NONE) { invalidate_button_area(btnm, ext->btn_id_pr); } - if(btn_pr != LV_BTNM_PR_NONE) { + if(btn_pr != LV_BTNM_BTN_NONE) { invalidate_button_area(btnm, btn_pr); } } @@ -803,12 +850,11 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) ext->btn_id_pr = btn_pr; } else if(sign == LV_SIGNAL_RELEASED) { - if(ext->btn_id_pr != LV_BTNM_PR_NONE) { - + if(ext->btn_id_pr != LV_BTNM_BTN_NONE) { /*Toggle the button if enabled*/ if(button_is_toggle(ext->ctrl_bits[ext->btn_id_pr])) { if(ext->ctrl_bits[ext->btn_id_pr] & LV_BTNM_BTN_TOGGLE_STATE) { - ext->ctrl_bits[ext->btn_id_pr] &= LV_BTNM_BTN_TOGGLE_STATE; + ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNM_BTN_TOGGLE_STATE); } else { ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNM_BTN_TOGGLE_STATE; } @@ -818,10 +864,10 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) /*Leave the clicked button when releases if this not 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; + ext->btn_id_pr = LV_BTNM_BTN_NONE; } #else - ext->btn_id_pr = LV_BTNM_PR_NONE; + ext->btn_id_pr = LV_BTNM_BTN_NONE; #endif } @@ -830,7 +876,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) { - ext->btn_id_pr = LV_BTNM_PR_NONE; + ext->btn_id_pr = LV_BTNM_BTN_NONE; lv_obj_invalidate(btnm); } else if(sign == LV_SIGNAL_FOCUS) { @@ -846,7 +892,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } else if(indev_type == LV_INDEV_TYPE_ENCODER) { /*In navigation mode don't select any button but in edit mode select the fist*/ if(lv_group_get_editing(lv_obj_get_group(btnm))) ext->btn_id_pr = 0; - else ext->btn_id_pr = LV_BTNM_PR_NONE; + else ext->btn_id_pr = LV_BTNM_BTN_NONE; } else { ext->btn_id_pr = 0; } @@ -858,18 +904,20 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) 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; + if(ext->btn_id_pr == LV_BTNM_BTN_NONE) ext->btn_id_pr = 0; else ext->btn_id_pr++; if(ext->btn_id_pr >= ext->btn_cnt - 1) ext->btn_id_pr = ext->btn_cnt - 1; lv_obj_invalidate(btnm); - } else if(c == LV_GROUP_KEY_LEFT) { - if(ext->btn_id_pr == LV_BTNM_PR_NONE) ext->btn_id_pr = 0; + } + else if(c == LV_GROUP_KEY_LEFT) { + if(ext->btn_id_pr == LV_BTNM_BTN_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) { + if(ext->btn_id_pr == LV_BTNM_BTN_NONE) { ext->btn_id_pr = 0; } else { uint16_t area_below; @@ -886,10 +934,11 @@ 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) { + if(ext->btn_id_pr == LV_BTNM_BTN_NONE) { ext->btn_id_pr = 0; } else { int16_t area_above; @@ -907,6 +956,9 @@ 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(sign == LV_SIGNAL_GET_EDITABLE) { bool * editable = (bool *)param; @@ -959,6 +1011,8 @@ static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** lv_mem_assert(ext->ctrl_bits); if(ext->button_areas == NULL || ext->ctrl_bits == NULL) btn_cnt = 0; + memset(ext->ctrl_bits, 0, sizeof(lv_btnm_ctrl_t) * btn_cnt); + ext->btn_cnt = btn_cnt; } @@ -969,7 +1023,8 @@ static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** */ static uint8_t get_button_width(lv_btnm_ctrl_t ctrl_bits) { - return ctrl_bits ? ctrl_bits & LV_BTNM_WIDTH_MASK : 1; + uint8_t w = ctrl_bits & LV_BTNM_WIDTH_MASK; + return w != 0 ? w: 1; } static bool button_is_hidden(lv_btnm_ctrl_t ctrl_bits) @@ -1001,7 +1056,7 @@ static bool button_get_toggle_state(lv_btnm_ctrl_t ctrl_bits) * Gives the button id of a button under a given point * @param btnm pointer to a button matrix object * @param p a point with absolute coordinates - * @return the id of the button or LV_BTNM_PR_NONE. + * @return the id of the button or LV_BTNM_BTN_NONE. */ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p) { @@ -1022,7 +1077,7 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p) } } - if(i == ext->btn_cnt) i = LV_BTNM_PR_NONE; + if(i == ext->btn_cnt) i = LV_BTNM_BTN_NONE; return i; } diff --git a/lv_objx/lv_btnm.h b/lv_objx/lv_btnm.h index 9defde228..6386d4dfb 100644 --- a/lv_objx/lv_btnm.h +++ b/lv_objx/lv_btnm.h @@ -38,7 +38,7 @@ extern "C" { #define LV_BTNM_BTN_TOGGLE 0x40 #define LV_BTNM_BTN_TOGGLE_STATE 0x80 -#define LV_BTNM_PR_NONE 0xFFFF +#define LV_BTNM_BTN_NONE 0xFFFF /********************** * TYPEDEFS **********************/ @@ -56,8 +56,8 @@ typedef struct lv_btnm_ctrl_t *ctrl_bits; /*Array of control bytes*/ lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of buttons in each state*/ uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/ - uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNM_PR_NONE*/ - uint16_t btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNM_PR_NONE */ + uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNM_BTN_NONE*/ + uint16_t btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNM_BTN_NONE */ uint8_t recolor :1; /*Enable button recoloring*/ } lv_btnm_ext_t; @@ -118,7 +118,7 @@ void lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t * ctrl_map * Set the pressed button i.e. visually highlight it. * Mainly used a when the btnm is in a group to show the selected button * @param btnm pointer to button matrix object - * @param id index of the currently pressed button (`LV_BTNM_PR_NONE` to unpress) + * @param id index of the currently pressed button (`LV_BTNM_BTN_NONE` to unpress) */ void lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id); @@ -149,35 +149,45 @@ void lv_btnm_set_btn_hidden(const lv_obj_t * btnm, uint16_t btn_idx, bool hidden * Enable/disable a single button in the matrix * @param btnm pointer to button matrix object * @param btn_id 0 based index of the button to modify. - * @param disabled true: disable the button + * @param ina true: make the button inactive */ -void lv_btnm_set_btn_inactive(const lv_obj_t * btnm, uint16_t btn_id, bool disabled); +void lv_btnm_set_btn_inactive(const lv_obj_t * btnm, uint16_t btn_id, bool ina); /** * Enable/disable long press for a single button in the matrix * @param btnm pointer to button matrix object * @param btn_id 0 based index of the button to modify. - * @param disabled true: disable repeat + * @param no_rep true: disable repeat */ -void lv_btnm_set_btn_no_repeat(const lv_obj_t * btnm, uint16_t btn_id, bool disabled); +void lv_btnm_set_btn_no_repeat(const lv_obj_t * btnm, uint16_t btn_id, bool no_rep); + +/** + * Enable/disable toggling a single button in the matrix + * @param btnm pointer to button matrix object + * @param btn_id 0 based index of the button to modify. + * @param tgl true: toggle enable + */ +void lv_btnm_set_btn_toggle(const lv_obj_t * btnm, uint16_t btn_id, bool tgl); /** * Make the a single button button toggled or not toggled. * @param btnm pointer to button matrix object * @param btn_id index of button (not counting "\n") - * @param en true: enable toggling; false: disable toggling + * @param state true: toggled; false: not toggled */ void lv_btnm_set_btn_toggle_state(lv_obj_t * btnm, uint16_t btn_id, bool toggle); /** * Set hidden/disabled/repeat flags for a single button. * @param btnm pointer to button matrix object - * @param btn_idx 0 based index of the button to modify. + * @param btn_id 0 based index of the button to modify. * @param hidden true: hide the button - * @param disabled true: disable the button - * @param disable_repeat true: disable repeat + * @param inactive true: disable the button + * @param no_repeat true: disable repeat + * @param toggle true: enable toggling + * @param toggled_state true: set toggled state */ -void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, bool disabled, bool disable_repeat, bool toggle, bool toggle_state); +void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, bool inactive, bool no_repeat, bool toggle, bool toggle_state); /** * Set a single buttons relative width. @@ -190,6 +200,12 @@ void lv_btnm_set_btn_flags(const lv_obj_t * btnm, uint16_t btn_id, bool hidden, */ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width); +/** + * Set the toggle state of all buttons + * @param btnm pointer to a button matrix object + * @param state true: toggled; false: not toggled + */ +void lv_btnm_set_btn_toggle_state_all(lv_obj_t * btnm, bool state); /*===================== * Getter functions @@ -213,15 +229,23 @@ bool lv_btnm_get_recolor(const lv_obj_t * btnm); * Get the index of the lastly "activated" button by the user (pressed, released etc) * Useful in the the `event_cb` to get the text of the button, check if hidden etc. * @param btnm pointer to button matrix object - * @return index of the last released button (LV_BTNM_PR_NONE: if unset) + * @return index of the last released button (LV_BTNM_BTN_NONE: if unset) */ uint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm); +/** + * Get the text of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb` + * @param btnm pointer to button matrix object + * @return text of the last released button (NULL: if unset) + */ +const char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm); + /** * Get the pressed button's index. * The button be really pressed by the user or manually set to pressed with `lv_btnm_set_pressed` * @param btnm pointer to button matrix object - * @return index of the pressed button (LV_BTNM_PR_NONE: if unset) + * @return index of the pressed button (LV_BTNM_BTN_NONE: if unset) */ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm); @@ -231,7 +255,7 @@ uint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm); * @param btn_index the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return text of btn_index` button */ -uint16_t lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id); +const char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id); /** * Check whether "no repeat" for a button is set or not. @@ -240,7 +264,7 @@ uint16_t lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id); * @param btn_index the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: long press repeat is disabled; false: long press repeat enabled */ -bool lv_btnm_is_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id); +bool lv_btnm_get_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id); /** * Check whether a button for a button is hidden or not. @@ -249,7 +273,7 @@ bool lv_btnm_is_btn_no_repeate(lv_obj_t * btnm, uint16_t btn_id); * @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: hidden; false: not hidden */ -bool lv_btnm_is_btn_hidden(lv_obj_t * btnm, uint16_t btn_id); +bool lv_btnm_get_btn_hidden(lv_obj_t * btnm, uint16_t btn_id); /** * Check whether a button for a button is inactive or not. @@ -258,14 +282,14 @@ bool lv_btnm_is_btn_hidden(lv_obj_t * btnm, uint16_t btn_id); * @param btn_id the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released) * @return true: inactive; false: not inactive */ -bool lv_btnm_is_btn_inactive(lv_obj_t * btnm, uint16_t btn_id); +bool lv_btnm_get_btn_inactive(lv_obj_t * btnm, uint16_t btn_id); /** * Check if the button can be toggled or not * @param btnm pointer to button matrix object * @return btn_id index a of a button not counting "\n". (The return value of lv_btnm_get_pressed/released) */ -bool lv_btnm_is_btn_toggle(const lv_obj_t * btnm, int16_t btn_id); +bool lv_btnm_get_btn_toggle(const lv_obj_t * btnm, int16_t btn_id); /** * Check if the button is toggled or not diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index 47b3447c4..04c14ad26 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -25,7 +25,7 @@ * STATIC PROTOTYPES **********************/ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param); -static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt); +static void lv_kb_def_event_cb(lv_obj_t * kb); /********************** * STATIC VARIABLES @@ -33,10 +33,10 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt); static lv_signal_cb_t ancestor_signal; static const char * kb_map_lc[] = { - "\2051#", "\204q", "\204w", "\204e", "\204r", "\204t", "\204y", "\204u", "\204i", "\204o", "\204p", "\207Bksp", "\n", - "\226ABC", "\203a", "\203s", "\203d", "\203f", "\203g", "\203h", "\203j", "\203k", "\203l", "\207Enter", "\n", + "#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "Bksp", "\n", + "ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", "Enter", "\n", "_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n", - "\202"LV_SYMBOL_CLOSE, "\202"LV_SYMBOL_LEFT, "\206 ", "\202"LV_SYMBOL_RIGHT, "\202"LV_SYMBOL_OK, "" + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" }; static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = { @@ -47,10 +47,10 @@ static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = { }; static const char * kb_map_uc[] = { - "\2051#", "\204Q", "\204W", "\204E", "\204R", "\204T", "\204Y", "\204U", "\204I", "\204O", "\204P", "\207Bksp", "\n", - "\226abc", "\203A", "\203S", "\203D", "\203F", "\203G", "\203H", "\203J", "\203K", "\203L", "\207Enter", "\n", + "#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Bksp", "\n", + "abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Enter", "\n", "_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n", - "\202"LV_SYMBOL_CLOSE, "\202"LV_SYMBOL_LEFT, "\206 ", "\202"LV_SYMBOL_RIGHT, "\202"LV_SYMBOL_OK, "" + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" }; static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = { @@ -61,10 +61,10 @@ static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = { }; static const char * kb_map_spec[] = { - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "\202Bksp", "\n", - "\222abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Bksp", "\n", + "abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n", "\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n", - "\202"LV_SYMBOL_CLOSE, "\202"LV_SYMBOL_LEFT, "\206 ", "\202"LV_SYMBOL_RIGHT, "\202"LV_SYMBOL_OK, "" + LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" }; static const lv_btnm_ctrl_t kb_ctrl_spec_map[] = { @@ -130,7 +130,6 @@ lv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_size(new_kb, LV_DPI * 3, LV_DPI * 2); lv_obj_align(new_kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - lv_btnm_set_action(new_kb, lv_kb_def_action); lv_btnm_set_map(new_kb, kb_map_lc); lv_btnm_set_ctrl_map(new_kb, kb_ctrl_lc_map); @@ -367,7 +366,15 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { + } + else if(sign == LV_SIGNAL_RELEASED) { + lv_kb_def_event_cb(kb); + } + else if(sign == LV_SIGNAL_LONG_PRESS_REP) { + bool no_rep = lv_btnm_get_btn_no_repeate(kb, lv_btnm_get_active_btn(kb)); + if(no_rep == false) lv_kb_def_event_cb(kb); + } + 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*/ @@ -380,55 +387,52 @@ static lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param) } /** - * Called when a button of 'kb_btnm' is released - * @param btnm pointer to 'kb_btnm' - * @param i the index of the released button from the current btnm map - * @return LV_ACTION_RES_INV if the btnm is deleted else LV_ACTION_RES_OK + * Called when a button of the keyboard is released + * @param kb pointer to a keyboard + * @param event type of the event */ -static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) +static void lv_kb_def_event_cb(lv_obj_t * kb) { lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb); - lv_res_t res = LV_RES_OK; + + uint16_t btn_id = lv_btnm_get_active_btn(kb); + if(btn_id == LV_BTNM_BTN_NONE) return; + if(lv_btnm_get_btn_hidden(kb, btn_id)) return; + if(lv_btnm_get_btn_inactive(kb, btn_id)) return; + + const char * txt = lv_btnm_get_active_btn_text(kb); + if(txt == NULL) return; /*Do the corresponding action according to the text of the button*/ if(strcmp(txt, "abc") == 0) { lv_btnm_set_map(kb, kb_map_lc); lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map); - return LV_RES_OK; + return; } else if(strcmp(txt, "ABC") == 0) { lv_btnm_set_map(kb, kb_map_uc); lv_btnm_set_ctrl_map(kb, kb_ctrl_uc_map); - return LV_RES_OK; + return; } else if(strcmp(txt, "1#") == 0) { lv_btnm_set_map(kb, kb_map_spec); lv_btnm_set_ctrl_map(kb, kb_ctrl_spec_map); - return LV_RES_OK; + return; } else if(strcmp(txt, LV_SYMBOL_CLOSE) == 0) { if(kb->event_cb) { - res = lv_obj_send_event(kb, LV_EVENT_CANCEL); - if(res != LV_RES_OK) return res; + lv_obj_send_event(kb, LV_EVENT_CANCEL); } else { lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ lv_obj_del(kb); } - return res; + return; } else if(strcmp(txt, LV_SYMBOL_OK) == 0) { - if(kb->event_cb) { - res = lv_obj_send_event(kb, LV_EVENT_APPLY); - if(res != LV_RES_OK) return res; - } - else { - lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ - res = lv_obj_del(kb); - } - return res; + if(kb->event_cb) lv_obj_send_event(kb, LV_EVENT_APPLY); + else lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ + return; } - if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/ - /*Add the characters to the text area if set*/ - if(ext->ta == NULL) return res; + if(ext->ta == NULL) return; if(strcmp(txt, "Enter") == 0)lv_ta_add_char(ext->ta, '\n'); else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) lv_ta_cursor_left(ext->ta); @@ -455,7 +459,6 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) } else { lv_ta_add_text(ext->ta, txt); } - return LV_RES_OK; } #endif diff --git a/lv_objx/lv_mbox.c b/lv_objx/lv_mbox.c index ad86867b9..f3b34fb22 100644 --- a/lv_objx/lv_mbox.c +++ b/lv_objx/lv_mbox.c @@ -7,6 +7,7 @@ /********************* * INCLUDES *********************/ +#include #include "lv_mbox.h" #if LV_USE_MBOX != 0 @@ -37,8 +38,8 @@ **********************/ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param); static void mbox_realign(lv_obj_t * mbox); -static lv_res_t lv_mbox_close_action(lv_obj_t * btn, const char * txt); static void lv_mbox_close_end_cb(lv_obj_t * mbox); +static void lv_mbox_default_event_cb(lv_obj_t * mbox, lv_event_t event); /********************** * STATIC VARIABLES @@ -93,6 +94,7 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy) lv_cont_set_fit2(new_mbox, LV_FIT_NONE, LV_FIT_TIGHT); lv_obj_set_width(new_mbox, LV_DPI * 2); lv_obj_align(new_mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(new_mbox, lv_mbox_default_event_cb); /*Set the default styles*/ lv_theme_t * th = lv_theme_get_current(); @@ -131,9 +133,8 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy) * @param mbox pointer to message box object * @param btn_map button descriptor (button matrix map). * E.g. a const char *txt[] = {"ok", "close", ""} (Can not be local variable) - * @param action a function which will be called when a button is released */ -void lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map, lv_btnm_action_t action) +void lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map) { lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); @@ -153,8 +154,7 @@ void lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map, lv_btnm_action_t a } lv_btnm_set_map(ext->btnm, btn_map); - if(action == NULL) lv_btnm_set_action(ext->btnm, lv_mbox_close_action); /*Set a default action anyway*/ - else lv_btnm_set_action(ext->btnm, action); + lv_obj_set_parent_event(ext->btnm, true); mbox_realign(mbox); } @@ -176,19 +176,6 @@ void lv_mbox_set_text(lv_obj_t * mbox, const char * txt) mbox_realign(mbox); } - -/** - * Stop the action to call when button is released - * @param pointer to an 'lv_btnm_action_t' action. In the action you need to use `lv_mbox_get_from_btn()` to get the `mbox`. - * @param pointer to an 'lv_btnm_action_t' action - */ -void lv_mbox_set_action(lv_obj_t * mbox, lv_btnm_action_t action) -{ - lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); - lv_btnm_set_action(ext->btnm, action); -} - - /** * Set animation duration * @param mbox pointer to a message box object @@ -311,16 +298,29 @@ const char * lv_mbox_get_text(const lv_obj_t * mbox) } /** - * Get the message box object from one of its button. - * It is useful in the button release actions where only the button is known - * @param btn pointer to a button of a message box - * @return pointer to the button's message box + * Get the index of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb`. + * @param btnm pointer to button matrix object + * @return index of the last released button (LV_BTNM_BTN_NONE: if unset) */ -lv_obj_t * lv_mbox_get_from_btn(const lv_obj_t * btn) +uint16_t lv_mbox_get_active_btn(lv_obj_t * mbox) { - lv_obj_t * mbox = lv_obj_get_parent(btn); + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + if(ext->btnm) return lv_btnm_get_active_btn(ext->btnm); + else return LV_BTNM_BTN_NONE; +} - return mbox; +/** + * Get the text of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb`. + * @param btnm pointer to button matrix object + * @return text of the last released button (NULL: if unset) + */ +const char * lv_mbox_get_active_btn_text(lv_obj_t * mbox) +{ + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + if(ext->btnm) return lv_btnm_get_active_btn_text(ext->btnm); + else return NULL; } /** @@ -402,7 +402,6 @@ lv_obj_t * lv_mbox_get_btnm(lv_obj_t * mbox) return ext->btnm; } - /********************** * STATIC FUNCTIONS **********************/ @@ -437,10 +436,19 @@ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param) if(lv_obj_get_width(mbox) != lv_area_get_width(param)) { mbox_realign(mbox); } - } else if(sign == LV_SIGNAL_STYLE_CHG) { + } + else if(sign == LV_SIGNAL_STYLE_CHG) { mbox_realign(mbox); - } else if(sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS || + } + else if(sign == LV_SIGNAL_PRESSED) { + /*If the message box was pressed clear the last active button*/ + if(ext->btnm) { + lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btnm); + btnm_ext->btn_id_act = LV_BTNM_BTN_NONE; + } + } + 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_cb(ext->btnm, sign, param); @@ -456,7 +464,7 @@ static lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param) /*In navigation mode don't select any button but in edit mode select the fist*/ lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btnm); if(lv_group_get_editing(lv_obj_get_group(mbox))) btnm_ext->btn_id_pr = 0; - else btnm_ext->btn_id_pr = LV_BTNM_PR_NONE; + else btnm_ext->btn_id_pr = LV_BTNM_BTN_NONE; } #endif } @@ -497,20 +505,21 @@ static void mbox_realign(lv_obj_t * mbox) } } -static lv_res_t lv_mbox_close_action(lv_obj_t * btn, const char * txt) -{ - lv_obj_t * mbox = lv_mbox_get_from_btn(btn); - - if(txt[0] != '\0') { - lv_mbox_start_auto_close(mbox, 0); - return LV_RES_INV; - } - - return LV_RES_OK; -} - static void lv_mbox_close_end_cb(lv_obj_t * mbox) { lv_obj_del(mbox); } + + +static void lv_mbox_default_event_cb(lv_obj_t * mbox, lv_event_t event) +{ + if(event != LV_EVENT_CLICKED) return; + + uint16_t btn_id = lv_mbox_get_active_btn(mbox); + if(btn_id == LV_BTNM_BTN_NONE) return; + + lv_mbox_start_auto_close(mbox, 0); + +} + #endif diff --git a/lv_objx/lv_mbox.h b/lv_objx/lv_mbox.h index d3c0deffb..1d256b3ac 100644 --- a/lv_objx/lv_mbox.h +++ b/lv_objx/lv_mbox.h @@ -90,9 +90,8 @@ lv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy); * @param mbox pointer to message box object * @param btn_map button descriptor (button matrix map). * E.g. a const char *txt[] = {"ok", "close", ""} (Can not be local variable) - * @param action a function which will be called when a button is released */ -void lv_mbox_add_btns(lv_obj_t * mbox, const char **btn_map, lv_btnm_action_t action); +void lv_mbox_add_btns(lv_obj_t * mbox, const char **btn_mapaction); /*===================== * Setter functions @@ -105,13 +104,6 @@ void lv_mbox_add_btns(lv_obj_t * mbox, const char **btn_map, lv_btnm_action_t ac */ void lv_mbox_set_text(lv_obj_t * mbox, const char * txt); -/** - * Stop the action to call when button is released - * @param mbox pointer to a message box object - * @param pointer to an 'lv_btnm_action_t' action. In the action you need to use `lv_mbox_get_from_btn()` to get the `mbox`. - */ -void lv_mbox_set_action(lv_obj_t * mbox, lv_btnm_action_t action); - /** * Set animation duration * @param mbox pointer to a message box object @@ -159,12 +151,20 @@ void lv_mbox_set_recolor(lv_obj_t * mbox, bool en); const char * lv_mbox_get_text(const lv_obj_t * mbox); /** - * Get the message box object from one of its button. - * It is useful in the button release actions where only the button is known - * @param btn pointer to a button of a message box - * @return pointer to the button's message box + * Get the index of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb`. + * @param btnm pointer to button matrix object + * @return index of the last released button (LV_BTNM_BTN_NONE: if unset) */ -lv_obj_t * lv_mbox_get_from_btn(const lv_obj_t * btn); +uint16_t lv_mbox_get_active_btn(lv_obj_t * mbox); + +/** + * Get the text of the lastly "activated" button by the user (pressed, released etc) + * Useful in the the `event_cb`. + * @param btnm pointer to button matrix object + * @return text of the last released button (NULL: if unset) + */ +const char * lv_mbox_get_active_btn_text(lv_obj_t * mbox); /** * Get the animation duration (close animation time) diff --git a/lv_objx/lv_tabview.c b/lv_objx/lv_tabview.c index d745882e5..70b675868 100644 --- a/lv_objx/lv_tabview.c +++ b/lv_objx/lv_tabview.c @@ -39,7 +39,7 @@ static lv_res_t tabpage_scrl_signal(lv_obj_t * tab_scrl, lv_signal_t sign, void static void tabpage_pressed_handler(lv_obj_t * tabview, lv_obj_t * tabpage); static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage); static void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage); -static lv_res_t tab_btnm_action(lv_obj_t * tab_btnm, const char * tab_name); +static void tab_btnm_event_cb(lv_obj_t * tab_btnm, lv_event_t event); static void tabview_realign(lv_obj_t * tabview); /********************** @@ -89,7 +89,6 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) ext->content = NULL; ext->indic = NULL; ext->btns = NULL; - ext->tab_load_action = NULL; ext->btns_pos = LV_TABVIEW_BTNS_POS_TOP; ext->anim_time = LV_TABVIEW_ANIM_TIME; ext->btns_hide = 0; @@ -111,8 +110,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) ext->btns = lv_btnm_create(new_tabview, NULL); lv_obj_set_height(ext->btns, 3 * LV_DPI / 4); lv_btnm_set_map(ext->btns, tab_def); - lv_btnm_set_action(ext->btns, tab_btnm_action); - lv_btnm_set_toggle(ext->btns, true, 0); + lv_obj_set_event_cb(ext->btns, tab_btnm_event_cb); ext->indic = lv_obj_create(ext->btns, NULL); lv_obj_set_width(ext->indic, LV_DPI); @@ -151,7 +149,6 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) ext->indic = lv_obj_create(ext->btns, copy_ext->indic); ext->content = lv_cont_create(new_tabview, copy_ext->content); ext->anim_time = copy_ext->anim_time; - ext->tab_load_action = copy_ext->tab_load_action; ext->tab_name_ptr = lv_mem_alloc(sizeof(char *)); lv_mem_assert(ext->tab_name_ptr); @@ -218,18 +215,10 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name) /*Extend the button matrix map with the new name*/ char * name_dm; - if((name[0] & LV_BTNM_CTRL_MASK) == LV_BTNM_CTRL_CODE) { /*If control byte presented let is*/ - name_dm = lv_mem_alloc(strlen(name) + 1); /*+1 for the the closing '\0' */ - lv_mem_assert(name_dm); - if(name_dm == NULL) return NULL; - strcpy(name_dm, name); - } else { /*Set a no long press control byte is not presented*/ - name_dm = lv_mem_alloc(strlen(name) + 2); /*+1 for the the closing '\0' and +1 for the control byte */ - lv_mem_assert(name_dm); - if(name_dm == NULL) return NULL; - name_dm[0] = '\221'; - strcpy(&name_dm[1], name); - } + name_dm = lv_mem_alloc(strlen(name) + 1); /*+1 for the the closing '\0' */ + lv_mem_assert(name_dm); + if(name_dm == NULL) return NULL; + strcpy(name_dm, name); ext->tab_cnt++; ext->tab_name_ptr = lv_mem_realloc(ext->tab_name_ptr, sizeof(char *) * (ext->tab_cnt + 1)); @@ -240,6 +229,7 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name) ext->tab_name_ptr[ext->tab_cnt] = ""; lv_btnm_set_map(ext->btns, ext->tab_name_ptr); + lv_btnm_set_btn_no_repeat(ext->btns, ext->tab_cnt - 1, true); /*Modify the indicator size*/ lv_style_t * style_tabs = lv_obj_get_style(ext->btns); @@ -250,10 +240,11 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name) /*Set the first btn as active*/ if(ext->tab_cnt == 1) { ext->tab_cur = 0; - lv_tabview_set_tab_act(tabview, 0, false); tabview_realign(tabview); /*To set the proper btns height*/ } + lv_tabview_set_tab_act(tabview, ext->tab_cur, false); + return h; } @@ -278,7 +269,8 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, bool anim_en) lv_res_t res = LV_RES_OK; if(id >= ext->tab_cnt) id = ext->tab_cnt - 1; - if(ext->tab_load_action && id != ext->tab_cur) res = ext->tab_load_action(tabview, id); + + if(id != ext->tab_cur) res = lv_obj_send_event(tabview, LV_EVENT_VALUE_CHANGED); if(res != LV_RES_OK) return; /*Prevent the tab loading*/ ext->tab_cur = id; @@ -331,19 +323,7 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, bool anim_en) #endif } - lv_btnm_set_toggle(ext->btns, true, ext->tab_cur); -} - -/** - * Set an action to call when a tab is loaded (Good to create content only if required) - * lv_tabview_get_act() still gives the current (old) tab (to remove content from here) - * @param tabview pointer to a tabview object - * @param action pointer to a function to call when a btn is loaded - */ -void lv_tabview_set_tab_load_action(lv_obj_t * tabview, lv_tabview_action_t action) -{ - lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview); - ext->tab_load_action = action; + lv_btnm_set_btn_toggle_state(ext->btns, ext->tab_cur, true); } /** @@ -484,17 +464,6 @@ lv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id) return NULL; } -/** - * Get the tab load action - * @param tabview pointer to a tabview object - * @param return the current btn load action - */ -lv_tabview_action_t lv_tabview_get_tab_load_action(const lv_obj_t * tabview) -{ - lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview); - return ext->tab_load_action; -} - /** * Get horizontal sliding is enabled or not * @param tabview pointer to Tab view object @@ -806,26 +775,23 @@ static void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage) } /** - * Called when a tab button is released + * Called when a tab button is clicked * @param tab_btnm pointer to the tab's button matrix object - * @param id the id of the tab (>= 0) - * @return LV_ACTION_RES_OK because the button matrix in not deleted in the function + * @param event type of the event */ -static lv_res_t tab_btnm_action(lv_obj_t * tab_btnm, const char * tab_name) +static void tab_btnm_event_cb(lv_obj_t * tab_btnm, lv_event_t event) { + if(event != LV_EVENT_CLICKED) return; + + uint16_t btn_id = lv_btnm_get_active_btn(tab_btnm); + if(btn_id == LV_BTNM_BTN_NONE) return; + + + lv_btnm_set_btn_toggle_state_all(tab_btnm, false); + lv_btnm_set_btn_toggle_state(tab_btnm, btn_id, true); + lv_obj_t * tab = lv_obj_get_parent(tab_btnm); - const char ** tabs_map = lv_btnm_get_map(tab_btnm); - - uint8_t i = 0; - - while(tabs_map[i][0] != '\0') { - if(strcmp(&tabs_map[i][1], tab_name) == 0) break; /*[1] to skip the control byte*/ - i++; - } - - lv_tabview_set_tab_act(tab, i, true); - - return LV_RES_OK; + lv_tabview_set_tab_act(tab, btn_id, true); } /** diff --git a/lv_objx/lv_tabview.h b/lv_objx/lv_tabview.h index 1b77a5f33..7a56f3c22 100644 --- a/lv_objx/lv_tabview.h +++ b/lv_objx/lv_tabview.h @@ -42,11 +42,6 @@ extern "C" { * TYPEDEFS **********************/ -/* parametes: pointer to a tabview object, tab_id - * return: LV_RES_INV: to prevent the loading of the tab; LV_RES_OK: if everything is fine*/ -typedef lv_res_t (*lv_tabview_action_t)(lv_obj_t *, uint16_t); - - enum { LV_TABVIEW_BTNS_POS_TOP, LV_TABVIEW_BTNS_POS_BOTTOM, @@ -71,7 +66,6 @@ typedef struct uint8_t drag_hor :1; uint8_t btns_hide :1; lv_tabview_btns_pos_t btns_pos :1; - lv_tabview_action_t tab_load_action; } lv_tabview_ext_t; enum { @@ -128,14 +122,6 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name); */ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, bool anim_en); -/** - * Set an action to call when a tab is loaded (Good to create content only if required) - * lv_tabview_get_act() still gives the current (old) tab (to remove content from here) - * @param tabview pointer to a tabview object - * @param action pointer to a function to call when a tab is loaded - */ -void lv_tabview_set_tab_load_action(lv_obj_t *tabview, lv_tabview_action_t action); - /** * Enable horizontal sliding with touch pad * @param tabview pointer to Tab view object @@ -197,13 +183,6 @@ uint16_t lv_tabview_get_tab_count(const lv_obj_t * tabview); */ lv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id); -/** - * Get the tab load action - * @param tabview pointer to a tabview object - * @param return the current tab load action - */ -lv_tabview_action_t lv_tabview_get_tab_load_action(const lv_obj_t *tabview); - /** * Get horizontal sliding is enabled or not * @param tabview pointer to Tab view object diff --git a/lv_objx/lv_tileview.c b/lv_objx/lv_tileview.c index 9ce57a083..6bc38509c 100644 --- a/lv_objx/lv_tileview.c +++ b/lv_objx/lv_tileview.c @@ -134,7 +134,7 @@ void lv_tileview_add_element(lv_obj_t * element) { /* Let objects eventto propaget to the scrollable part of the tileview. * It is required the handle dargging of the tileview with the element.*/ - element->event_parent = 1; + element->parent_event = 1; lv_obj_set_drag_parent(element, true); }