diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 142ed080a..61c545567 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,7 @@ # https://aka.ms/yaml trigger: -- master +- dev-7.0 pool: vmImage: 'ubuntu-latest' @@ -14,10 +14,7 @@ steps: displayName: 'Run a one-line script' - script: | - echo Start build - echo root content: - ls cd tests echo tests content: python build.py - displayName: 'Build' \ No newline at end of file + displayName: 'Build' diff --git a/lv_conf_template.h b/lv_conf_template.h index 165ee9c9b..b089f2d05 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -584,9 +584,6 @@ typedef void * lv_obj_user_data_t; /*--END OF LV_CONF_H--*/ -/*Be sure every define has a default value*/ -#include "lvgl/src/lv_conf_checker.h" - #endif /*LV_CONF_H*/ #endif /*End of "Content enable"*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 5de614627..7e134d932 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -10,12 +10,14 @@ #include -#ifdef LV_CONF_PATH +#if defined(LV_CONF_PATH) #define __LV_TO_STR_AUX(x) #x #define __LV_TO_STR(x) __LV_TO_STR_AUX(x) #include __LV_TO_STR(LV_CONF_PATH) #undef __LV_TO_STR_AUX #undef __LV_TO_STR +#elif defined(LV_CONF_INCLUDE_SIMPLE) +#include "lv_conf.h" #else #include "../../lv_conf.h" #endif diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index ad44d7661..cfa6fb1e8 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1488,6 +1488,10 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data) */ lv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data) { + if(obj != NULL) { + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + } + /* Build a simple linked list from the objects used in the events * It's important to know if an this object was deleted by a nested event * called from this `even_cb`. */ @@ -2820,12 +2824,14 @@ bool lv_obj_is_focused(const lv_obj_t * obj) *------------------*/ /** - * Hit-test an object given a particular point in screen space. - * @param obj object to hit-test + * Check if a given screen-space point is on an object's coordinates. + * + * This method is intended to be used mainly by advanced hit testing algorithms to check + * whether the point is even within the object (as an optimization). + * @param obj object to check * @param point screen-space point - * @return true if the object is considered under the point */ -bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point) { +bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point) { #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY lv_area_t ext_area; ext_area.x1 = obj->coords.x1 - obj->ext_click_pad_hor; @@ -2847,15 +2853,24 @@ bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point) { #endif return false; } + return true; +} + +/** + * Hit-test an object given a particular point in screen space. + * @param obj object to hit-test + * @param point screen-space point + * @return true if the object is considered under the point + */ +bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point) { if(obj->adv_hittest) { lv_hit_test_info_t hit_info; hit_info.point = point; hit_info.result = true; obj->signal_cb(obj, LV_SIGNAL_HIT_TEST, &hit_info); - if(!hit_info.result) - return false; - } - return true; + return hit_info.result; + } else + return lv_obj_is_point_on_coords(obj, point); } /** diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 64153b6ab..8183f8d76 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -993,6 +993,22 @@ lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj); * Other get *-----------------*/ +/** + * Check if a given screen-space point is on an object's coordinates. + * + * This method is intended to be used mainly by advanced hit testing algorithms to check + * whether the point is even within the object (as an optimization). + * @param obj object to check + * @param point screen-space point + */ +bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point); + +/** + * Hit-test an object given a particular point in screen space. + * @param obj object to hit-test + * @param point screen-space point + * @return true if the object is considered under the point + */ bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point); /** diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 529fb2252..733ef14d5 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -207,6 +207,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_lab char *bidi_txt = lv_mem_buf_get(line_end - line_start + 1); lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, dsc->bidi_dir, NULL, 0); #else + (void)bidi_dir; const char *bidi_txt = txt + line_start; #endif diff --git a/src/lv_misc/lv_gc.c b/src/lv_misc/lv_gc.c index c192057c7..ed4d0676e 100644 --- a/src/lv_misc/lv_gc.c +++ b/src/lv_misc/lv_gc.c @@ -29,12 +29,11 @@ /********************** * STATIC VARIABLES **********************/ -lv_mem_buf_t _lv_mem_buf[LV_MEM_BUF_MAX_NUM]; - #if(!defined(LV_ENABLE_GC)) || LV_ENABLE_GC == 0 LV_ROOTS #endif /* LV_ENABLE_GC */ + /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_gc.h b/src/lv_misc/lv_gc.h index d4ef5a9ac..22110dc49 100644 --- a/src/lv_misc/lv_gc.h +++ b/src/lv_misc/lv_gc.h @@ -24,8 +24,6 @@ extern "C" { * DEFINES *********************/ -extern lv_mem_buf_t _lv_mem_buf[LV_MEM_BUF_MAX_NUM]; - #define LV_ITERATE_ROOTS(f) \ f(lv_ll_t, _lv_task_ll) /*Linked list to store the lv_tasks*/ \ f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \ @@ -37,6 +35,7 @@ extern lv_mem_buf_t _lv_mem_buf[LV_MEM_BUF_MAX_NUM]; f(lv_ll_t, _lv_img_defoder_ll) \ f(lv_img_cache_entry_t*, _lv_img_cache_array) \ f(void*, _lv_task_act) \ + f(lv_mem_buf_arr_t , _lv_mem_buf) \ #define LV_DEFINE_ROOT(root_type, root_name) root_type root_name; #define LV_ROOTS LV_ITERATE_ROOTS(LV_DEFINE_ROOT) diff --git a/src/lv_misc/lv_ll.h b/src/lv_misc/lv_ll.h index 3c05c1e90..2ac66a48f 100644 --- a/src/lv_misc/lv_ll.h +++ b/src/lv_misc/lv_ll.h @@ -136,8 +136,8 @@ uint32_t lv_ll_get_len(const lv_ll_t * ll_p); * @param ll_p * @param n1_p * @param n2_p - */ void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p); + */ /** * Move a nodw before an other node in the same linked list diff --git a/src/lv_misc/lv_mem.c b/src/lv_misc/lv_mem.c index 1940fd93f..44703b146 100644 --- a/src/lv_misc/lv_mem.c +++ b/src/lv_misc/lv_mem.c @@ -16,6 +16,10 @@ #include LV_MEM_CUSTOM_INCLUDE #endif +#if defined(LV_GC_INCLUDE) +#include LV_GC_INCLUDE +#endif /* LV_ENABLE_GC */ + /********************* * DEFINES *********************/ @@ -403,23 +407,23 @@ void * lv_mem_buf_get(uint32_t size) /*Try to find a free buffer with suitable size */ uint8_t i; for(i = 0; i < LV_MEM_BUF_MAX_NUM; i++) { - if(_lv_mem_buf[i].used == 0 && _lv_mem_buf[i].size >= size) { - _lv_mem_buf[i].used = 1; - return _lv_mem_buf[i].p; + if(LV_GC_ROOT(_lv_mem_buf[i]).used == 0 && LV_GC_ROOT(_lv_mem_buf[i]).size >= size) { + LV_GC_ROOT(_lv_mem_buf[i]).used = 1; + return LV_GC_ROOT(_lv_mem_buf[i]).p; } } /*Reallocate a free buffer*/ for(i = 0; i < LV_MEM_BUF_MAX_NUM; i++) { - if(_lv_mem_buf[i].used == 0) { - _lv_mem_buf[i].used = 1; - _lv_mem_buf[i].size = size; + if(LV_GC_ROOT(_lv_mem_buf[i]).used == 0) { + LV_GC_ROOT(_lv_mem_buf[i]).used = 1; + LV_GC_ROOT(_lv_mem_buf[i]).size = size; /*if this fails you probably need to increase your LV_MEM_SIZE/heap size*/ - _lv_mem_buf[i].p = lv_mem_realloc(_lv_mem_buf[i].p, size); - if(_lv_mem_buf[i].p == NULL) { + LV_GC_ROOT(_lv_mem_buf[i]).p = lv_mem_realloc(LV_GC_ROOT(_lv_mem_buf[i]).p, size); + if(LV_GC_ROOT(_lv_mem_buf[i]).p == NULL) { LV_LOG_ERROR("lv_mem_buf_get: Out of memory, can't allocate a new buffer (increase your LV_MEM_SIZE/heap size)") } - return _lv_mem_buf[i].p; + return LV_GC_ROOT(_lv_mem_buf[i]).p; } } @@ -436,8 +440,8 @@ void lv_mem_buf_release(void * p) { uint8_t i; for(i = 0; i < LV_MEM_BUF_MAX_NUM; i++) { - if(_lv_mem_buf[i].p == p) { - _lv_mem_buf[i].used = 0; + if(LV_GC_ROOT(_lv_mem_buf[i]).p == p) { + LV_GC_ROOT(_lv_mem_buf[i]).used = 0; return; } } @@ -452,11 +456,11 @@ void lv_mem_buf_free_all(void) { uint8_t i; for(i = 0; i < LV_MEM_BUF_MAX_NUM; i++) { - if(_lv_mem_buf[i].p) { - lv_mem_free(_lv_mem_buf[i].p); - _lv_mem_buf[i].p = NULL; - _lv_mem_buf[i].used = 0; - _lv_mem_buf[i].size = 0; + if(LV_GC_ROOT(_lv_mem_buf[i]).p) { + lv_mem_free(LV_GC_ROOT(_lv_mem_buf[i]).p); + LV_GC_ROOT(_lv_mem_buf[i]).p = NULL; + LV_GC_ROOT(_lv_mem_buf[i]).used = 0; + LV_GC_ROOT(_lv_mem_buf[i]).size = 0; } } } diff --git a/src/lv_misc/lv_mem.h b/src/lv_misc/lv_mem.h index 729cd2465..bb0cdc829 100644 --- a/src/lv_misc/lv_mem.h +++ b/src/lv_misc/lv_mem.h @@ -52,6 +52,9 @@ typedef struct { uint8_t used :1; }lv_mem_buf_t; +typedef lv_mem_buf_t lv_mem_buf_arr_t[LV_MEM_BUF_MAX_NUM]; +extern lv_mem_buf_arr_t _lv_mem_buf; + /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/src/lv_objx/lv_bar.c b/src/lv_objx/lv_bar.c index 0281c455c..69186615a 100644 --- a/src/lv_objx/lv_bar.c +++ b/src/lv_objx/lv_bar.c @@ -25,6 +25,12 @@ #define LV_BAR_SIZE_MIN 4 /*hor. pad and ver. pad cannot make the indicator smaller then this [px]*/ +#if LV_USE_ANIMATION +#define LV_BAR_IS_ANIMATING(anim_struct) (((anim_struct).anim_state) != LV_BAR_ANIM_STATE_INV) +#define LV_BAR_GET_ANIM_VALUE(orig_value, anim_struct) (LV_BAR_IS_ANIMATING(anim_struct) ? ((anim_struct).anim_end) : (orig_value)) +#else +#define LV_BAR_GET_ANIM_VALUE(orig_value, anim_struct) (orig_value) +#endif /********************** * TYPEDEFS **********************/ @@ -264,12 +270,8 @@ int16_t lv_bar_get_value(const lv_obj_t * bar) LV_ASSERT_OBJ(bar, LV_OBJX_NAME); lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); - /*If animated tell that it's already at the end value*/ -#if LV_USE_ANIMATION - if(ext->cur_value_anim.is_animating) return ext->cur_value_anim.anim_end; -#endif - /*No animation, simple return the current value*/ - return ext->cur_value; + + return LV_BAR_GET_ANIM_VALUE(ext->cur_value, ext->cur_value_anim); } /** @@ -285,12 +287,7 @@ int16_t lv_bar_get_start_value(const lv_obj_t * bar) if(ext->type != LV_BAR_TYPE_CUSTOM) return ext->min_value; - /*If animated tell that it's already at the end value*/ -#if LV_USE_ANIMATION - if(ext->start_value_anim.is_animating) return ext->start_value_anim.anim_end; -#endif - /*No animation, simple return the current value*/ - return ext->start_value; + return LV_BAR_GET_ANIM_VALUE(ext->start_value, ext->start_value_anim); } /** @@ -398,16 +395,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area) int32_t range = ext->max_value - ext->min_value; bool hor = objw >= objh ? true : false; bool sym = false; - if(ext->type == LV_BAR_TYPE_SYM && ext->min_value < 0 && ext->max_value > 0) sym = true; - - bool cur_value_anim = false; -#if LV_USE_ANIMATION - if(ext->cur_value_anim.is_animating) cur_value_anim = true; -#endif - bool start_value_anim = false; -#if LV_USE_ANIMATION - if(ext->start_value_anim.is_animating) start_value_anim = true; -#endif + if(ext->type == LV_BAR_TYPE_SYM && ext->min_value < 0 && ext->max_value > 0 && ext->start_value == ext->min_value) sym = true; /*Calculate the indicator area*/ lv_style_value_t bg_left = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_PAD_LEFT); @@ -434,69 +422,70 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area) lv_coord_t indich = lv_area_get_height(&ext->indic_area); /*Calculate the indicator length*/ - lv_coord_t indic_length; + lv_coord_t anim_length = hor ? indicw : indich; - lv_coord_t anim_cur_value, anim_start_value; - if(cur_value_anim) { -#if LV_USE_ANIMATION - anim_cur_value = ext->cur_value_anim.anim_val; -#endif - } else { - anim_cur_value = ext->cur_value; - } + lv_coord_t anim_cur_value_x, anim_start_value_x; - if(start_value_anim) { -#if LV_USE_ANIMATION - anim_start_value = ext->start_value_anim.anim_val; -#endif - } else { - anim_start_value = ext->start_value; - } + lv_coord_t * axis1, * axis2; + lv_coord_t (*indic_length_calc)(const lv_area_t *area); - indic_length = (int32_t)((int32_t)(hor ? indicw : indich) * ((anim_cur_value - ext->min_value) - (anim_start_value - ext->min_value))) / - (ext->max_value - ext->min_value); - - /*Horizontal bar*/ if(hor) { - ext->indic_area.x2 = ext->indic_area.x1 + indic_length - 1; - if(sym) { - lv_coord_t zero; - zero = ext->indic_area.x1 + (-ext->min_value * indicw) / range; - if(ext->indic_area.x2 > zero) - ext->indic_area.x1 = zero; - else { - ext->indic_area.x1 = ext->indic_area.x2; - ext->indic_area.x2 = zero; - } - } else { - lv_coord_t increment = ((anim_start_value-ext->min_value) * indicw) / range; - ext->indic_area.x1 += increment; - ext->indic_area.x2 += increment; - } + axis1 = &ext->indic_area.x1; + axis2 = &ext->indic_area.x2; + indic_length_calc = lv_area_get_width; + } else { + axis1 = &ext->indic_area.y1; + axis2 = &ext->indic_area.y2; + indic_length_calc = lv_area_get_height; } - /*Vertical bar*/ - else { - ext->indic_area.y1 = ext->indic_area.y2 - indic_length + 1; - if(sym) { - lv_coord_t zero; - zero = ext->indic_area.y2 - (-ext->min_value * objh) / range; - if(ext->indic_area.y1 < zero) - ext->indic_area.y2 = zero; - else { - ext->indic_area.y2 = ext->indic_area.y1; - ext->indic_area.y1 = zero; - } - } else { - lv_coord_t increment = ((anim_start_value-ext->min_value) * objh) / range; - ext->indic_area.y1 += increment; - ext->indic_area.y2 += increment; - } + +#if LV_USE_ANIMATION + if(LV_BAR_IS_ANIMATING(ext->start_value_anim)) { + lv_coord_t anim_start_value_start_x = + (int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_start - ext->min_value)) / range; + lv_coord_t anim_start_value_end_x = + (int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_end - ext->min_value)) / range; + + anim_start_value_x = (((anim_start_value_end_x - anim_start_value_start_x) * ext->start_value_anim.anim_state) >> LV_BAR_ANIM_STATE_NORM); + } else +#endif + { + anim_start_value_x = (int32_t)((int32_t)anim_length * (ext->start_value - ext->min_value)) / range; + } + +#if LV_USE_ANIMATION + if(LV_BAR_IS_ANIMATING(ext->cur_value_anim)) { + lv_coord_t anim_cur_value_start_x = + (int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_start - ext->min_value)) / range; + lv_coord_t anim_cur_value_end_x = + (int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_end - ext->min_value)) / range; + + anim_cur_value_x = (((anim_cur_value_end_x - anim_cur_value_start_x) * ext->cur_value_anim.anim_state) >> LV_BAR_ANIM_STATE_NORM); + } else +#endif + { + anim_cur_value_x = (int32_t)((int32_t)anim_length * (ext->cur_value - ext->min_value)) / range; + } + + /* Set the indicator length */ + *axis2 = *axis1 + anim_cur_value_x; + *axis1 += anim_start_value_x; + + if(sym) { + lv_coord_t zero; + zero = *axis1 + (-ext->min_value * anim_length) / range; + if(*axis2 > zero) + *axis1 = zero; + else { + *axis1 = *axis2; + *axis2 = zero; + } } /*Draw the indicator*/ /*Do not draw a zero length indicator*/ - if(!sym && indic_length == 0) return; + if(!sym && indic_length_calc(&ext->indic_area) == 0) return; uint16_t bg_radius = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_RADIUS); lv_coord_t short_side = LV_MATH_MIN(objw, objh); @@ -639,7 +628,7 @@ static lv_style_dsc_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part) #if LV_USE_ANIMATION static void lv_bar_anim(lv_bar_anim_t * var, lv_anim_value_t value) { - var->anim_val = value; + var->anim_state = value; lv_obj_invalidate(var->bar); } @@ -647,7 +636,7 @@ static void lv_bar_anim_ready(lv_anim_t * a) { lv_bar_anim_t * var = a->var; lv_bar_ext_t * ext = lv_obj_get_ext_attr(var->bar); - var->is_animating = false; + var->anim_state = LV_BAR_ANIM_STATE_INV; if(var == &ext->cur_value_anim) ext->cur_value = var->anim_end; else if(var == &ext->start_value_anim) @@ -662,7 +651,7 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_ } else { lv_bar_ext_t *ext = lv_obj_get_ext_attr(bar); /*No animation in progress -> simply set the values*/ - if(!anim_info->is_animating) { + if(anim_info->anim_state == LV_BAR_ANIM_STATE_INV) { anim_info->anim_start = *value_ptr; anim_info->anim_end = new_value; } @@ -676,8 +665,8 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_ lv_anim_t a; a.var = anim_info; - a.start = anim_info->anim_start; - a.end = anim_info->anim_end; + a.start = LV_BAR_ANIM_STATE_START; + a.end = LV_BAR_ANIM_STATE_END; a.exec_cb = (lv_anim_exec_xcb_t)lv_bar_anim; a.path_cb = lv_anim_path_linear; a.ready_cb = lv_bar_anim_ready; @@ -689,7 +678,6 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_ a.repeat_pause = 0; lv_anim_create(&a); - anim_info->is_animating = true; } } @@ -698,7 +686,7 @@ static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim) bar_anim->bar = bar; bar_anim->anim_start = 0; bar_anim->anim_end = 0; - bar_anim->is_animating = false; + bar_anim->anim_state = LV_BAR_ANIM_STATE_INV; } #endif diff --git a/src/lv_objx/lv_bar.h b/src/lv_objx/lv_bar.h index 79dfeb9af..7108d7a26 100644 --- a/src/lv_objx/lv_bar.h +++ b/src/lv_objx/lv_bar.h @@ -27,6 +27,18 @@ extern "C" { * DEFINES *********************/ +/** Bar animation start value. (Not the real value of the Bar just indicates process animation)*/ +#define LV_BAR_ANIM_STATE_START 0 + +/** Bar animation end value. (Not the real value of the Bar just indicates process animation)*/ +#define LV_BAR_ANIM_STATE_END 256 + +/** Mark no animation is in progress */ +#define LV_BAR_ANIM_STATE_INV -1 + +/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/ +#define LV_BAR_ANIM_STATE_NORM 8 + /********************** * TYPEDEFS **********************/ @@ -43,8 +55,7 @@ typedef struct { lv_obj_t * bar; lv_anim_value_t anim_start; lv_anim_value_t anim_end; - lv_anim_value_t anim_val; - uint8_t is_animating : 1; + lv_anim_value_t anim_state; } lv_bar_anim_t; #endif diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index f6a285d07..54fdd7aaf 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -861,9 +861,10 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) lv_indev_type_t indev_type = lv_indev_get_type(indev); /*If not focused by an input device assume the last input device*/ - if(indev_type == LV_INDEV_TYPE_NONE) { - indev_type = lv_indev_get_type(lv_indev_get_next(NULL)); - } + if(indev == NULL) { + indev = lv_indev_get_next(NULL); + indev_type = lv_indev_get_type(indev); + } if(indev_type == LV_INDEV_TYPE_POINTER) { /*Select the clicked button*/ diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 4f6be702c..95c6d26aa 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -900,9 +900,14 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p static bool lv_cpicker_hit(lv_obj_t * cpicker, const lv_point_t * p) { + bool is_point_on_coords = lv_obj_is_point_on_coords(cpicker, p); + if(!is_point_on_coords) + return false; + lv_cpicker_ext_t * ext = (lv_cpicker_ext_t *)lv_obj_get_ext_attr(cpicker); if(ext->type != LV_CPICKER_TYPE_DISC || ext->preview) return true; + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); lv_area_t area_mid; lv_area_copy(&area_mid, &cpicker->coords); diff --git a/src/lv_objx/lv_img.c b/src/lv_objx/lv_img.c index d3ac0c883..b5b38daf9 100644 --- a/src/lv_objx/lv_img.c +++ b/src/lv_objx/lv_img.c @@ -98,6 +98,7 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_click(new_img, false); + lv_obj_set_adv_hittest(new_img, true); /*Images have fast hit-testing*/ /* Enable auto size for non screens * because image screens are wallpapers * and must be screen sized*/ @@ -502,6 +503,8 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area cover = lv_area_is_in(clip_area, &img->coords, 0) ? LV_DESIGN_RES_COVER : LV_DESIGN_RES_NOT_COVER; } + if(lv_obj_get_style_opa(img, LV_IMG_PART_MAIN, LV_STYLE_IMAGE_OPA) < LV_OPA_MAX) return false; + return cover; } else if(mode == LV_DESIGN_DRAW_MAIN) { if(ext->h == 0 || ext->w == 0) return true; @@ -599,6 +602,26 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param) lv_coord_t d = ds.i / 2; img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, d); } + } else if(sign == LV_SIGNAL_HIT_TEST) { + lv_hit_test_info_t *info = param; + if(ext->zoom != 256 && ext->angle == 0) { + lv_coord_t origin_width = lv_area_get_width(&img->coords); + lv_coord_t origin_height = lv_area_get_height(&img->coords); + lv_coord_t scaled_width = (origin_width * ext->zoom + 255) / 256; + lv_coord_t scaled_height = (origin_height * ext->zoom + 255) / 256; + + lv_coord_t width_offset = (origin_width - scaled_width) / 2; + lv_coord_t height_offset = (origin_height - scaled_height) / 2; + + lv_area_t coords; + lv_area_copy(&coords, &img->coords); + coords.x1 += width_offset; + coords.x2 -= width_offset; + coords.y1 += height_offset; + coords.y2 -= height_offset; + info->result = lv_area_is_point_on(&coords, info->point, 0); + } else + info->result = lv_obj_is_point_on_coords(img, info->point); } return res;