diff --git a/src/core/lv_indev.c b/src/core/lv_indev.c index 064464256..9bd681e3e 100644 --- a/src/core/lv_indev.c +++ b/src/core/lv_indev.c @@ -853,8 +853,6 @@ static void indev_proc_press(_lv_indev_proc_t * proc) if(indev_reset_check(proc)) return; } - lv_obj_transform_point(indev_obj_act, &proc->types.pointer.act_point, true, true); - /*If a new object was found reset some variables and send a pressed event handler*/ if(indev_obj_act != proc->types.pointer.act_obj) { proc->types.pointer.last_point.x = proc->types.pointer.act_point.x; @@ -992,6 +990,27 @@ static void indev_proc_release(_lv_indev_proc_t * proc) proc->pr_timestamp = 0; proc->longpr_rep_timestamp = 0; + + /*Get the transformed vector with this object*/ + if(scroll_obj) { + int16_t angle = 0; + int16_t zoom = 256; + lv_point_t pivot = { 0, 0 }; + lv_obj_t * parent = scroll_obj; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); + } + + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_transform(&proc->types.pointer.scroll_throw_vect, angle, zoom, &pivot); + lv_point_transform(&proc->types.pointer.scroll_throw_vect_ori, angle, zoom, &pivot); + } + } + } if(scroll_obj) { diff --git a/src/core/lv_indev_scroll.c b/src/core/lv_indev_scroll.c index f631e5011..13407f77a 100644 --- a/src/core/lv_indev_scroll.c +++ b/src/core/lv_indev_scroll.c @@ -45,12 +45,13 @@ static lv_coord_t elastic_diff(lv_obj_t * scroll_obj, lv_coord_t diff, lv_coord_ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc) { + if(proc->types.pointer.vect.x == 0 && proc->types.pointer.vect.y == 0) { + return; + } + lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; /*If there is no scroll object yet try to find one*/ if(scroll_obj == NULL) { - proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x; - proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y; - scroll_obj = find_scroll_obj(proc); if(scroll_obj == NULL) return; @@ -61,35 +62,50 @@ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc) } /*Set new position or scroll if the vector is not zero*/ - if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) { - lv_coord_t diff_x = 0; - lv_coord_t diff_y = 0; - - if(proc->types.pointer.scroll_dir == LV_DIR_HOR) { - lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); - lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); - diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR); - } - else { - lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); - lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); - diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER); - } - - lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj); - if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; - if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; - if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; - if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; - - /*Respect the scroll limit area*/ - scroll_limit_diff(proc, &diff_x, &diff_y); - - _lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); - if(proc->reset_query) return; - proc->types.pointer.scroll_sum.x += diff_x; - proc->types.pointer.scroll_sum.y += diff_y; + int16_t angle = 0; + int16_t zoom = 256; + lv_obj_t * parent = scroll_obj; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); } + + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_t pivot = { 0, 0 }; + lv_point_transform(&proc->types.pointer.vect, angle, zoom, &pivot); + } + + + + lv_coord_t diff_x = 0; + lv_coord_t diff_y = 0; + if(proc->types.pointer.scroll_dir == LV_DIR_HOR) { + lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); + lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); + diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR); + } + else { + lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); + lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); + diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER); + } + + lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj); + if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; + if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; + if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; + if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; + + /*Respect the scroll limit area*/ + scroll_limit_diff(proc, &diff_x, &diff_y); + + _lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); + if(proc->reset_query) return; + proc->types.pointer.scroll_sum.x += diff_x; + proc->types.pointer.scroll_sum.y += diff_y; } @@ -266,14 +282,36 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) /*Decide if it's a horizontal or vertical scroll*/ bool hor_en = false; bool ver_en = false; - if(LV_ABS(proc->types.pointer.scroll_sum.x) > LV_ABS(proc->types.pointer.scroll_sum.y)) { - hor_en = true; - } - else { - ver_en = true; - } + + proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x; + proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y; while(obj_act) { + /*Get the transformed scroll_sum with this object*/ + int16_t angle = 0; + int16_t zoom = 256; + lv_point_t pivot = { 0, 0 }; + lv_obj_t * parent = obj_act; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); + } + + lv_point_t obj_scroll_sum = proc->types.pointer.scroll_sum; + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_transform(&obj_scroll_sum, angle, zoom, &pivot); + } + + if(LV_ABS(obj_scroll_sum.x) > LV_ABS(obj_scroll_sum.y)) { + hor_en = true; + } + else { + ver_en = true; + } + if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) { /*If this object don't want to chain the scroll to the parent stop searching*/ if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_HOR) == false && hor_en) break; @@ -307,15 +345,15 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) *is propagated to this object it can show at least elastic scroll effect. *But if not hor/ver scrollable do not scroll it at all (so it's not a good candidate)*/ if((st > 0 || sb > 0) && - ((up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) || - (down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit))) { + ((up_en && obj_scroll_sum.y >= scroll_limit) || + (down_en && obj_scroll_sum.y <= - scroll_limit))) { obj_candidate = obj_act; dir_candidate = LV_DIR_VER; } if((sl > 0 || sr > 0) && - ((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) || - (right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit))) { + ((left_en && obj_scroll_sum.x >= scroll_limit) || + (right_en && obj_scroll_sum.x <= - scroll_limit))) { obj_candidate = obj_act; dir_candidate = LV_DIR_HOR; } @@ -325,11 +363,11 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) if(sl <= 0) left_en = false; if(sr <= 0) right_en = false; - /*If the object really can be scrolled into the current direction the use it.*/ - if((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) || - (right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit) || - (up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) || - (down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)) { + /*If the object really can be scrolled into the current direction then use it.*/ + if((left_en && obj_scroll_sum.x >= scroll_limit) || + (right_en && obj_scroll_sum.x <= - scroll_limit) || + (up_en && obj_scroll_sum.y >= scroll_limit) || + (down_en && obj_scroll_sum.y <= - scroll_limit)) { proc->types.pointer.scroll_dir = hor_en ? LV_DIR_HOR : LV_DIR_VER; break; } diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index 24548baf1..adab8e6ad 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -1139,8 +1139,10 @@ static void transform_point(const lv_obj_t * obj, lv_point_t * p, bool inv) if(angle == 0 && zoom == LV_IMG_ZOOM_NONE) return; lv_point_t pivot; + pivot.x = obj->coords.x1 + lv_obj_get_style_transform_pivot_x(obj, 0); pivot.y = obj->coords.y1 + lv_obj_get_style_transform_pivot_y(obj, 0); + if(inv) { angle = -angle; zoom = (256 * 256) / zoom; diff --git a/src/hal/lv_hal_indev.h b/src/hal/lv_hal_indev.h index ca51a08c2..5bbcf530e 100644 --- a/src/hal/lv_hal_indev.h +++ b/src/hal/lv_hal_indev.h @@ -141,6 +141,7 @@ typedef struct _lv_indev_proc_t { struct { /*Pointer and button data*/ lv_point_t act_point; /**< Current point of input device.*/ + lv_point_t indev_point; lv_point_t last_point; /**< Last point of input device.*/ lv_point_t last_raw_point; /**< Last point read from read_cb. */ lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/