diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index ebd4eca67..b8a939211 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -64,7 +64,7 @@ static lv_obj_t * indev_obj_act = NULL; */ void lv_indev_init(void) { - lv_indev_reset(NULL); /*Reset all input devices*/ + lv_indev_reset(NULL, NULL); /*Reset all input devices*/ } /** @@ -145,19 +145,26 @@ lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev) return indev->driver.type; } + /** * Reset one or all input devices * @param indev pointer to an input device to reset or NULL to reset all of them + * @param obj pointer to an object which triggers the reset. */ -void lv_indev_reset(lv_indev_t * indev) +void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj) { - if(indev) + if(indev) { indev->proc.reset_query = 1; - else { + if(obj == NULL || indev->proc.types.pointer.last_pressed == obj) { + indev->proc.types.pointer.last_pressed = NULL; + } + } else { lv_indev_t * i = lv_indev_get_next(NULL); while(i) { i->proc.reset_query = 1; - + if(obj == NULL || i->proc.types.pointer.last_pressed == obj) { + i->proc.types.pointer.last_pressed = NULL; + } i = lv_indev_get_next(i); } } @@ -938,7 +945,8 @@ static void indev_proc_release(lv_indev_proc_t * proc) if(indev_reset_check(proc)) return; /*Handle click focus*/ - if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_CLICK_FOCUS) == false) { + if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_CLICK_FOCUS) == false && + proc->types.pointer.last_pressed != indev_obj_act) { #if LV_USE_GROUP lv_group_t * g_act = lv_obj_get_group(indev_obj_act); lv_group_t * g_prev = proc->types.pointer.last_pressed ? lv_obj_get_group(proc->types.pointer.last_pressed) : NULL; @@ -967,11 +975,18 @@ static void indev_proc_release(lv_indev_proc_t * proc) } /*The object are not in the same group (in different group or one in not a group)*/ else { - /*Leave the object focused in the previous group and focus to the act. its group*/ + /*Focus to the act. its group*/ if(g_act) { lv_group_focus_obj(indev_obj_act); if(indev_reset_check(proc)) return; } + /*If the prev. obj. is not in a group then defocus it.*/ + if(g_prev == NULL && proc->types.pointer.last_pressed) { + lv_signal_send(proc->types.pointer.last_pressed, LV_SIGNAL_DEFOCUS, NULL); + if(indev_reset_check(proc)) return; + lv_event_send(proc->types.pointer.last_pressed, LV_EVENT_DEFOCUSED, NULL); + if(indev_reset_check(proc)) return; + } /*Focus on a non-group object*/ else { if(proc->types.pointer.last_pressed) { @@ -1051,7 +1066,6 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) if(indev->proc.reset_query) { indev->proc.types.pointer.act_obj = NULL; indev->proc.types.pointer.last_obj = NULL; - indev->proc.types.pointer.last_pressed = NULL; indev->proc.types.pointer.drag_limit_out = 0; indev->proc.types.pointer.drag_in_prog = 0; indev->proc.long_pr_sent = 0; @@ -1398,7 +1412,7 @@ static void indev_gesture(lv_indev_proc_t * proc) /** * Checks if the reset_query flag has been set. If so, perform necessary global indev cleanup actions * @param proc pointer to an input device 'proc' - * return true if indev query should be immediately truncated. + * @return true if indev query should be immediately truncated. */ static bool indev_reset_check(lv_indev_proc_t * proc) { diff --git a/src/lv_core/lv_indev.h b/src/lv_core/lv_indev.h index fca073901..7fc2d1a77 100644 --- a/src/lv_core/lv_indev.h +++ b/src/lv_core/lv_indev.h @@ -57,8 +57,9 @@ lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev); /** * Reset one or all input devices * @param indev pointer to an input device to reset or NULL to reset all of them + * @param obj pointer to an object which triggers the reset. */ -void lv_indev_reset(lv_indev_t * indev); +void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj); /** * Reset the long press state of an input device diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index fb44f56aa..66b9a0b03 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -409,7 +409,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj) lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) { - lv_indev_reset(indev); + lv_indev_reset(indev, obj); } if(indev->proc.types.pointer.last_pressed == obj) { indev->proc.types.pointer.last_pressed = NULL; @@ -417,7 +417,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj) #if LV_USE_GROUP if(indev->group == group && obj == lv_indev_get_obj_act()) { - lv_indev_reset(indev); + lv_indev_reset(indev, obj); } #endif indev = lv_indev_get_next(indev); @@ -1454,33 +1454,42 @@ void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot) obj->protect &= prot; } -void lv_obj_set_state(lv_obj_t * obj, lv_obj_state_t state) +void lv_obj_set_state(lv_obj_t * obj, lv_obj_state_t new_state) +{ + if(obj->state_dsc.act == new_state) return; + + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + lv_style_int_t t = lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_TRANSITION_TIME); + if(t == 0) { + lv_anim_del(obj, obj_state_anim_cb); + obj->state_dsc.act = new_state; + obj->state_dsc.prev = new_state; + obj->state_dsc.anim = 0; + lv_obj_refresh_style(obj); + } + /*Set the new state for prev state too to get the TRANSITION_TIME for the new state*/ + else { + obj->state_dsc.prev = obj->state_dsc.act; + obj->state_dsc.act = new_state; + obj->state_dsc.anim = 0; + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_exec_cb(&a, obj, obj_state_anim_cb); + lv_anim_set_values(&a, 0, 255); + lv_anim_set_time(&a, t, 0); + lv_anim_create(&a); + } + +} + +void lv_obj_add_state(lv_obj_t * obj, lv_obj_state_t state) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_obj_state_t new_state = obj->state_dsc.act | state; if(obj->state_dsc.act != new_state) { - lv_style_int_t t = lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_TRANSITION_TIME); - if(t == 0) { - lv_anim_del(obj, obj_state_anim_cb); - obj->state_dsc.act = new_state; - obj->state_dsc.prev = new_state; - obj->state_dsc.anim = 0; - lv_obj_refresh_style(obj); - } - /*Set the new state for prev state too to get the TRANSITION_TIME for the new state*/ - else { - obj->state_dsc.prev = obj->state_dsc.act; - obj->state_dsc.act = new_state; - obj->state_dsc.anim = 0; - - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_exec_cb(&a, obj, obj_state_anim_cb); - lv_anim_set_values(&a, 0, 255); - lv_anim_set_time(&a, t, 0); - lv_anim_create(&a); - } + lv_obj_set_state(obj, new_state); } } @@ -1490,27 +1499,7 @@ void lv_obj_clear_state(lv_obj_t * obj, lv_obj_state_t state) lv_obj_state_t new_state = obj->state_dsc.act & (~state); if(obj->state_dsc.act != new_state) { - lv_style_int_t t = lv_obj_get_style_int(obj, LV_OBJ_PART_MAIN, LV_STYLE_TRANSITION_TIME); - if(t == 0) { - lv_anim_del(obj, obj_state_anim_cb); - obj->state_dsc.act = new_state; - obj->state_dsc.prev = new_state; - obj->state_dsc.anim = 0; - lv_obj_refresh_style(obj); - } - /*Set the new state for prev state too to get the TRANSITION_TIME for the new state*/ - else { - obj->state_dsc.prev = obj->state_dsc.act; - obj->state_dsc.act = new_state; - obj->state_dsc.anim = 0; - - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_exec_cb(&a, obj, obj_state_anim_cb); - lv_anim_set_values(&a, 0, 255); - lv_anim_set_time(&a, t, 0); - lv_anim_create(&a); - } + lv_obj_set_state(obj, new_state); } } /** @@ -2889,9 +2878,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) if(lv_group_get_editing(lv_obj_get_group(obj))) { uint8_t state = LV_OBJ_STATE_FOCUS; state |= LV_OBJ_STATE_EDIT; - lv_obj_set_state(obj, state); + lv_obj_add_state(obj, state); } else { - lv_obj_set_state(obj, LV_OBJ_STATE_FOCUS); + lv_obj_add_state(obj, LV_OBJ_STATE_FOCUS); lv_obj_clear_state(obj, LV_OBJ_STATE_EDIT); } } else if(sign == LV_SIGNAL_DEFOCUS) { @@ -3025,7 +3014,7 @@ static void delete_children(lv_obj_t * obj) lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) { - lv_indev_reset(indev); + lv_indev_reset(indev, obj); } if(indev->proc.types.pointer.last_pressed == obj) { @@ -3033,7 +3022,7 @@ static void delete_children(lv_obj_t * obj) } #if LV_USE_GROUP if(indev->group == group && obj == lv_indev_get_obj_act()) { - lv_indev_reset(indev); + lv_indev_reset(indev, obj); } #endif indev = lv_indev_get_next(indev); diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 1bc9b7891..8683ba0c3 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -641,6 +641,8 @@ void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot); void lv_obj_set_state(lv_obj_t * obj, lv_obj_state_t state); +void lv_obj_add_state(lv_obj_t * obj, lv_obj_state_t state); + void lv_obj_clear_state(lv_obj_t * obj, lv_obj_state_t state); /** diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 35d359abf..534fba316 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -156,7 +156,7 @@ enum { LV_STYLE_STATE_HOVER = (1 << (3 + LV_STYLE_STATE_POS)), LV_STYLE_STATE_PRESSED = (1 << (4 + LV_STYLE_STATE_POS)), LV_STYLE_STATE_DISABLED = (1 << (6 + LV_STYLE_STATE_POS)), - LV_STYLE_STATE_ALL = (0x7F << LV_STYLE_STATE_POS) + LV_STYLE_STATE_ALL = (0x7F << LV_STYLE_STATE_POS), }; typedef uint16_t lv_style_state_t; diff --git a/src/lv_objx/lv_btn.c b/src/lv_objx/lv_btn.c index 372c1834c..9bfdabde5 100644 --- a/src/lv_objx/lv_btn.c +++ b/src/lv_objx/lv_btn.c @@ -138,17 +138,17 @@ void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state) break; case LV_BTN_STATE_PR: lv_obj_clear_state(btn, LV_OBJ_STATE_CHECKED); - lv_obj_set_state(btn, LV_OBJ_STATE_PRESSED); + lv_obj_add_state(btn, LV_OBJ_STATE_PRESSED); break; case LV_BTN_STATE_TGL_REL: - lv_obj_set_state(btn, LV_OBJ_STATE_CHECKED); + lv_obj_add_state(btn, LV_OBJ_STATE_CHECKED); lv_obj_clear_state(btn, LV_OBJ_STATE_PRESSED); break; case LV_BTN_STATE_TGL_PR: - lv_obj_set_state(btn, LV_OBJ_STATE_PRESSED | LV_OBJ_STATE_CHECKED); + lv_obj_add_state(btn, LV_OBJ_STATE_PRESSED | LV_OBJ_STATE_CHECKED); break; case LV_BTN_STATE_INA: - lv_obj_set_state(btn, LV_OBJ_STATE_DISABLED); + lv_obj_add_state(btn, LV_OBJ_STATE_DISABLED); break; } @@ -169,7 +169,7 @@ void lv_btn_toggle(lv_obj_t * btn) if(lv_obj_get_state(btn, LV_BTN_PART_MAIN) & LV_OBJ_STATE_CHECKED) { lv_obj_clear_state(btn, LV_OBJ_STATE_CHECKED); } else { - lv_obj_set_state(btn, LV_OBJ_STATE_CHECKED); + lv_obj_add_state(btn, LV_OBJ_STATE_CHECKED); } } diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index abc98cab4..760f52555 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -677,16 +677,19 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar } /*Focused and/or pressed + checked or released button*/ else { + btnm->state_dsc.act = LV_OBJ_STATE_NORMAL; if(tgl_state) btnm->state_dsc.act = LV_OBJ_STATE_CHECKED; if(ext->btn_id_pr == btn_i) btnm->state_dsc.act |= LV_OBJ_STATE_PRESSED; if(ext->btn_id_focused == btn_i) btnm->state_dsc.act |= LV_OBJ_STATE_FOCUS; btnm->state_dsc.prev = btnm->state_dsc.act; + lv_draw_rect_dsc_init(&draw_rect_tmp_dsc); lv_draw_label_dsc_init(&draw_label_tmp_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_tmp_dsc); lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_tmp_dsc); draw_rect_dsc_act = &draw_rect_tmp_dsc; draw_label_dsc_act = &draw_label_tmp_dsc; + btnm->state_dsc = state_ori; } @@ -850,7 +853,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) res = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b); } } - } else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) { + } else if(sign == LV_SIGNAL_PRESS_LOST) { ext->btn_id_pr = LV_BTNM_BTN_NONE; ext->btn_id_act = LV_BTNM_BTN_NONE; lv_obj_invalidate(btnm); diff --git a/src/lv_objx/lv_cb.c b/src/lv_objx/lv_cb.c index e26e66fff..e285d954d 100644 --- a/src/lv_objx/lv_cb.c +++ b/src/lv_objx/lv_cb.c @@ -181,10 +181,13 @@ static lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param) const lv_font_t * font = lv_obj_get_style_ptr(ext->label, LV_LABEL_PART_MAIN, LV_STYLE_FONT); lv_coord_t line_height = lv_font_get_line_height(font); lv_obj_set_size(ext->bullet, line_height, line_height); - lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); - } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { - lv_btn_set_state(ext->bullet, lv_btn_get_state(cb)); - } else if(sign == LV_SIGNAL_CONTROL) { + lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CB_PART_BG)); + } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST || + sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS) { + lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CB_PART_BG)); + } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED) { + + }else if(sign == LV_SIGNAL_CONTROL) { char c = *((char *)param); if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN || c == LV_KEY_LEFT || c == LV_KEY_UP) { /*Follow the backgrounds state with the bullet*/ diff --git a/src/lv_objx/lv_cb.h b/src/lv_objx/lv_cb.h index e1c74b65f..942696065 100644 --- a/src/lv_objx/lv_cb.h +++ b/src/lv_objx/lv_cb.h @@ -49,8 +49,8 @@ typedef struct /** Checkbox styles. */ enum { - LV_CB_PART_BG, /**< Style of object background. */ - LV_CB_PART_BULLET, /**< Style of box (released). */ + LV_CB_PART_BG = LV_BTN_PART_MAIN, /**< Style of object background. */ + LV_CB_PART_BULLET = _LV_BTN_PART_REAL_LAST, /**< Style of box (released). */ }; typedef uint8_t lv_cb_style_t; diff --git a/src/lv_objx/lv_sw.c b/src/lv_objx/lv_sw.c index dafffdb08..9111bc050 100644 --- a/src/lv_objx/lv_sw.c +++ b/src/lv_objx/lv_sw.c @@ -127,7 +127,7 @@ void lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim) lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); ext->state = 1; lv_bar_set_value(sw, 1, anim); - lv_obj_set_state(sw, LV_OBJ_STATE_CHECKED); + lv_obj_add_state(sw, LV_OBJ_STATE_CHECKED); } /** diff --git a/src/lv_themes/lv_theme_alien.c b/src/lv_themes/lv_theme_alien.c index 0b26908b9..79bc4833e 100644 --- a/src/lv_themes/lv_theme_alien.c +++ b/src/lv_themes/lv_theme_alien.c @@ -235,6 +235,7 @@ static void slider_init(void) lv_style_set_int(&slider_knob, LV_STYLE_PAD_BOTTOM, LV_DPI/20); lv_style_set_int(&slider_knob, LV_STYLE_PAD_LEFT, LV_DPI/20); lv_style_set_int(&slider_knob, LV_STYLE_PAD_RIGHT, LV_DPI/20); + lv_style_set_color(&slider_knob, LV_STYLE_BG_COLOR | LV_STYLE_STATE_FOCUS, LV_COLOR_RED); #endif } @@ -249,6 +250,7 @@ static void sw_init(void) lv_style_set_int(&sw_knob, LV_STYLE_PAD_BOTTOM, - LV_DPI/20); lv_style_set_int(&sw_knob, LV_STYLE_PAD_LEFT, - LV_DPI/20); lv_style_set_int(&sw_knob, LV_STYLE_PAD_RIGHT, - LV_DPI/20); + lv_style_set_color(&sw_knob, LV_STYLE_BG_COLOR | LV_STYLE_STATE_FOCUS, LV_COLOR_RED); #endif } @@ -363,10 +365,12 @@ static void cb_init(void) lv_style_set_int(&cb_bullet, LV_STYLE_BORDER_WIDTH , 2); lv_style_set_color(&cb_bullet, LV_STYLE_BORDER_COLOR , lv_color_hex(0x52555a)); lv_style_set_color(&cb_bullet, LV_STYLE_BORDER_COLOR | LV_STYLE_STATE_PRESSED , lv_color_darken(lv_color_hex(0x52555a), LV_OPA_30)); + lv_style_set_color(&cb_bullet, LV_STYLE_BORDER_COLOR | LV_STYLE_STATE_FOCUS, LV_COLOR_RED); + lv_style_set_color(&cb_bullet, LV_STYLE_BORDER_COLOR | LV_STYLE_STATE_FOCUS | LV_STYLE_STATE_PRESSED, LV_COLOR_LIME); lv_style_set_color(&cb_bullet, LV_STYLE_BG_COLOR, COLOR_ACCENT); lv_style_set_opa(&cb_bullet, LV_STYLE_BG_OPA | LV_STYLE_STATE_CHECKED , LV_OPA_COVER); lv_style_set_opa(&cb_bullet, LV_STYLE_BORDER_OPA | LV_STYLE_STATE_CHECKED , LV_OPA_80); - lv_style_set_int(&cb_bullet, LV_STYLE_TRANSITION_TIME , 100); + lv_style_set_int(&cb_bullet, LV_STYLE_TRANSITION_TIME , 1000);