1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

scroll propagation: start to rework

This commit is contained in:
Gabor Kiss-Vamosi 2019-09-17 14:38:55 +02:00
parent f445f1965b
commit c79ada1a46
9 changed files with 199 additions and 154 deletions

View File

@ -42,6 +42,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev);
static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj);
static void indev_drag(lv_indev_proc_t * state);
static void indev_drag_throw(lv_indev_proc_t * proc);
static lv_obj_t * get_dragged_obj(lv_obj_t * obj);
static bool indev_reset_check(lv_indev_proc_t * proc);
/**********************
@ -736,8 +737,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
proc->types.pointer.last_obj = indev_obj_act;
if(indev_obj_act != NULL) {
/* Save the time when the obj pressed.
* It is necessary to count the long press time.*/
/* Save the time when the obj pressed to count long press time.*/
proc->pr_timestamp = lv_tick_get();
proc->long_pr_sent = 0;
proc->types.pointer.drag_limit_out = 0;
@ -846,6 +846,7 @@ static void indev_proc_release(lv_indev_proc_t * proc)
/*Forget the act obj and send a released signal */
if(indev_obj_act) {
/* If the object was protected against press lost then it possible that
* the object is already not pressed but still it is the `act_obj`.
* In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if
@ -938,11 +939,8 @@ static void indev_proc_release(lv_indev_proc_t * proc)
/*Send LV_EVENT_DRAG_THROW_BEGIN if required */
/*If drag parent is active check recursively the drag_parent attribute*/
lv_obj_t * drag_obj = indev_obj_act;
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
lv_obj_t * drag_obj = get_dragged_obj(indev_obj_act);
if(drag_obj) {
if(lv_obj_get_drag_throw(drag_obj) && proc->types.pointer.drag_in_prog) {
lv_event_send(drag_obj, LV_EVENT_DRAG_THROW_BEGIN, NULL);
@ -1053,14 +1051,9 @@ static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj)
*/
static void indev_drag(lv_indev_proc_t * state)
{
lv_obj_t * drag_obj = state->types.pointer.act_obj;
lv_obj_t * drag_obj = get_dragged_obj(state->types.pointer.act_obj);
bool drag_just_started = false;
/*If drag parent is active check recursively the drag_parent attribute*/
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
if(drag_obj == NULL) return;
if(lv_obj_get_drag(drag_obj) == false) return;
@ -1068,16 +1061,34 @@ static void indev_drag(lv_indev_proc_t * state)
lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);
/*Count the movement by drag*/
state->types.pointer.drag_sum.x += state->types.pointer.vect.x;
state->types.pointer.drag_sum.y += state->types.pointer.vect.y;
if(state->types.pointer.drag_limit_out == 0) {
state->types.pointer.drag_sum.x += state->types.pointer.vect.x;
state->types.pointer.drag_sum.y += state->types.pointer.vect.y;
}
/*Enough move?*/
if(state->types.pointer.drag_limit_out == 0) {
bool hor_en = false;
bool ver_en = false;
if(allowed_dirs == LV_DRAG_DIR_HOR || allowed_dirs == LV_DRAG_DIR_ALL) {
hor_en = true;
}
if(allowed_dirs == LV_DRAG_DIR_VER || allowed_dirs == LV_DRAG_DIR_ALL) {
ver_en = true;
}
if(allowed_dirs == LV_DRAG_DIR_ONE) {
if(LV_MATH_ABS(state->types.pointer.drag_sum.x) > LV_MATH_ABS(state->types.pointer.drag_sum.y)) {
hor_en = true;
} else {
ver_en = true;
}
}
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
if(((allowed_dirs & LV_DRAG_DIR_HOR) &&
LV_MATH_ABS(state->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
((allowed_dirs & LV_DRAG_DIR_VER) &&
LV_MATH_ABS(state->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {
if((hor_en && LV_MATH_ABS(state->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
(ver_en && LV_MATH_ABS(state->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {
state->types.pointer.drag_limit_out = 1;
drag_just_started = true;
}
@ -1106,21 +1117,48 @@ static void indev_drag(lv_indev_proc_t * state)
act_y += state->types.pointer.drag_sum.y;
}
lv_obj_set_pos(drag_obj, act_x + state->types.pointer.vect.x, act_y + state->types.pointer.vect.y);
} else if(allowed_dirs & LV_DRAG_DIR_HOR) {
} else if(allowed_dirs == LV_DRAG_DIR_HOR) {
if(drag_just_started) {
state->types.pointer.drag_sum.y = 0;
act_x += state->types.pointer.drag_sum.x;
}
lv_obj_set_x(drag_obj, act_x + state->types.pointer.vect.x);
} else if(allowed_dirs & LV_DRAG_DIR_VER) {
} else if(allowed_dirs == LV_DRAG_DIR_VER) {
if(drag_just_started) {
state->types.pointer.drag_sum.x = 0;
act_y += state->types.pointer.drag_sum.y;
}
lv_obj_set_y(drag_obj, act_y + state->types.pointer.vect.y);
} else if(allowed_dirs == LV_DRAG_DIR_ONE) {
if(drag_just_started) {
if(LV_MATH_ABS(state->types.pointer.drag_sum.x) > LV_MATH_ABS(state->types.pointer.drag_sum.y)) {
state->types.pointer.drag_sum.y = 0;
} else {
state->types.pointer.drag_sum.x = 0;
}
act_x += state->types.pointer.drag_sum.x;
act_y += state->types.pointer.drag_sum.y;
}
/*The inactive direction in drag_sum is kept zero*/
if(state->types.pointer.drag_sum.x) act_x += state->types.pointer.vect.x;
if(state->types.pointer.drag_sum.y) act_y += state->types.pointer.vect.y;
lv_obj_set_pos(drag_obj, act_x, act_y);
state->types.pointer.drag_in_prog = 1;
/*Set the drag in progress flag*/
/*Send the drag begin signal on first move*/
if(drag_just_started) {
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
if(indev_reset_check(state)) return;
lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
if(indev_reset_check(state)) return;
}
}
/*If the object didn't moved then clear the invalidated areas*/
if(drag_obj->coords.x1 == prev_x && drag_obj->coords.y1 == prev_y) {
// state->types.pointer.drag_in_prog = 0;
/*In a special case if the object is moved on a page and
* the scrollable has fit == true and the object is dragged of the page then
* while its coordinate is not changing only the parent's size is reduced */
@ -1130,16 +1168,6 @@ static void indev_drag(lv_indev_proc_t * state)
uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp);
lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);
}
} else {
state->types.pointer.drag_in_prog = 1;
/*Set the drag in progress flag*/
/*Send the drag begin signal on first move*/
if(drag_just_started) {
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
if(indev_reset_check(state)) return;
lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
if(indev_reset_check(state)) return;
}
}
}
}
@ -1153,16 +1181,9 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
{
if(proc->types.pointer.drag_in_prog == 0) return;
lv_obj_t * drag_obj = proc->types.pointer.last_obj;
lv_obj_t * drag_obj = get_dragged_obj(proc->types.pointer.last_obj);
/*If drag parent is active check recursively the drag_parent attribute*/
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
if(drag_obj == NULL) {
return;
}
if(drag_obj == NULL) return;
/*Return if the drag throw is not enabled*/
if(lv_obj_get_drag_throw(drag_obj) == false) {
@ -1190,13 +1211,13 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
lv_coord_t act_x = lv_obj_get_x(drag_obj) + proc->types.pointer.drag_throw_vect.x;
lv_coord_t act_y = lv_obj_get_y(drag_obj) + proc->types.pointer.drag_throw_vect.y;
if(allowed_dirs == LV_DRAG_DIR_ALL)
lv_obj_set_pos(drag_obj, act_x, act_y);
else if(allowed_dirs & LV_DRAG_DIR_HOR)
lv_obj_set_x(drag_obj, act_x);
else if(allowed_dirs & LV_DRAG_DIR_VER)
lv_obj_set_y(drag_obj, act_y);
if(allowed_dirs == LV_DRAG_DIR_ALL) lv_obj_set_pos(drag_obj, act_x, act_y);
else if(allowed_dirs == LV_DRAG_DIR_HOR) lv_obj_set_x(drag_obj, act_x);
else if(allowed_dirs == LV_DRAG_DIR_VER) lv_obj_set_y(drag_obj, act_y);
else if(allowed_dirs == LV_DRAG_DIR_ONE) {
if(proc->types.pointer.drag_sum.x) lv_obj_set_x(drag_obj, act_x);
else lv_obj_set_y(drag_obj, act_y);
}
lv_area_t coord_new;
lv_obj_get_coords(drag_obj, &coord_new);
@ -1210,6 +1231,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
proc->types.pointer.drag_throw_vect.y = 0;
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
if(indev_reset_check(proc)) return;
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
if(indev_reset_check(proc)) return;
}
@ -1225,6 +1247,22 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
}
}
/**
* Get the really dragged object by taking `drag_parent` into account.
* @param obj the start obejct
* @return the object to really drag
*/
static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
{
lv_obj_t * drag_obj = obj;
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
return drag_obj;
}
/**
* 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'

View File

@ -184,9 +184,11 @@ typedef struct
#endif
enum {
LV_DRAG_DIR_NONE = 0x0, /**< Both directions are disabled */
LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */
LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */
LV_DRAG_DIR_ALL = 0x3, /**< Object can be dragged in all directions. */
LV_DRAG_DIR_ONE = 0x4, /**< Object can be dragged only one direction (the first move). */
};
typedef uint8_t lv_drag_dir_t;
@ -227,8 +229,10 @@ typedef struct _lv_obj_t
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 parent_event : 1; /**< 1: Send the object's events to the parent too. */
lv_drag_dir_t drag_dir : 2; /**< Which directions the object can be dragged in */
uint8_t reserved : 6; /**< Reserved for future use */
lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */
uint8_t reserved : 5; /**< Reserved for future use */
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*/

View File

@ -143,7 +143,7 @@ void lv_style_init(void)
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
lv_style_pretty.body.radius = LV_DPI / 5;
lv_style_pretty.body.radius = LV_DPI / 15;
lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_pretty.body.border.opa = LV_OPA_30;
@ -176,12 +176,12 @@ void lv_style_init(void)
/*Button released style*/
lv_style_copy(&lv_style_btn_rel, &lv_style_plain);
lv_style_btn_rel.body.main_color = LV_COLOR_LIME;//lv_color_make(0x76, 0xa2, 0xd0);
lv_style_btn_rel.body.grad_color = LV_COLOR_BLUE;//lv_color_make(0x19, 0x3a, 0x5d);
lv_style_btn_rel.body.main_color_stop = 0x80;//0x10;
lv_style_btn_rel.body.grad_color_stop = 0xd0;//0x10;
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
lv_style_btn_rel.body.main_color_stop = 0x00;
lv_style_btn_rel.body.grad_color_stop = 0xff;;
lv_style_btn_rel.body.grad_dir = LV_GRAD_DIR_VER;
lv_style_btn_rel.body.radius = 15;//LV_DPI / 15;
lv_style_btn_rel.body.radius = LV_DPI / 15;
lv_style_btn_rel.body.opa = LV_OPA_COVER;
// lv_style_btn_rel.body.blend_mode = LV_BLEND_MODE_ADDITIVE;
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
@ -190,16 +190,16 @@ void lv_style_init(void)
lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
lv_style_btn_rel.body.border.width = 0;//LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_btn_rel.body.border.opa = LV_OPA_70;
// lv_style_btn_rel.body.border.part = LV_BORDER_PART_LEFT | LV_BORDER_PART_TOP;
lv_style_btn_rel.body.shadow.color = LV_COLOR_BLACK;
lv_style_btn_rel.body.shadow.width = 10;
lv_style_btn_rel.body.shadow.width = 0;
// lv_style_btn_rel.body.shadow.spread = 5;
// lv_style_btn_rel.body.shadow.blend_mode = LV_BLEND_MODE_SUBTRACTIVE;
lv_style_btn_rel.body.shadow.opa = LV_OPA_COVER;
lv_style_btn_rel.body.shadow.offset.x = 10;
lv_style_btn_rel.body.shadow.offset.y = 20;
lv_style_btn_rel.body.shadow.offset.x = 0;
lv_style_btn_rel.body.shadow.offset.y = 0;
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);

View File

@ -877,7 +877,6 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
if(sign == LV_SIGNAL_RELEASED) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->page.scroll_prop_ip = 0;
#if LV_USE_GROUP
lv_group_t * g = lv_obj_get_group(list);
@ -905,10 +904,6 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode) {
lv_list_btn_single_select(btn);
}
} else if(sign == LV_SIGNAL_PRESS_LOST) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->page.scroll_prop_ip = 0;
} else if(sign == LV_SIGNAL_CLEANUP) {
#if LV_USE_GROUP

View File

@ -159,9 +159,9 @@ static inline void lv_list_set_sb_mode(lv_obj_t * list, lv_sb_mode_t mode)
* @param list pointer to a List
* @param en true or false to enable/disable scroll propagation
*/
static inline void lv_list_set_scroll_propagation(lv_obj_t * list, bool en)
static inline void lv_list_set_scroll_propagation(lv_obj_t * list, lv_drag_dir_t dir)
{
lv_page_set_scroll_propagation(list, en);
lv_page_set_scroll_propagation(list, dir);
}
/**

View File

@ -103,8 +103,8 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
ext->edge_flash.style = &lv_style_plain_color;
ext->anim_time = LV_PAGE_DEF_ANIM_TIME;
#endif
ext->scroll_prop = 0;
ext->scroll_prop_ip = 0;
ext->scroll_prop_dir = 0;
ext->scroll_prop_obj = NULL;
/*Init the new page object*/
if(copy == NULL) {
@ -232,10 +232,10 @@ void lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time)
* @param page pointer to a Page
* @param en true or false to enable/disable scroll propagation
*/
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en)
void lv_page_set_scroll_propagation(lv_obj_t * page, lv_drag_dir_t dir)
{
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
ext->scroll_prop = en ? 1 : 0;
ext->scroll_prop_dir = dir;
}
/**
@ -329,10 +329,10 @@ lv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page)
* @param page pointer to a Page
* @return true or false
*/
bool lv_page_get_scroll_propagation(lv_obj_t * page)
lv_drag_dir_t lv_page_get_scroll_propagation(lv_obj_t * page)
{
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->scroll_prop == 0 ? false : true;
return ext->scroll_prop_dir;
}
/**
@ -931,21 +931,34 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
lv_coord_t vpad = page_style->body.padding.top + page_style->body.padding.bottom;
lv_obj_t * page_parent = lv_obj_get_parent(page);
/*Handle scroll propagation*/
lv_indev_t * indev = lv_indev_get_act();
lv_point_t drag_vect;
lv_indev_get_vect(indev, &drag_vect);
/* Start the scroll propagation if there is drag vector on the indev, but the drag is not
* started yet and the scrollable is in a corner. It will enable the scroll propagation only
* when a new scroll begins and not when the scrollable is already being scrolled.*/
if(page_ext->scroll_prop && page_ext->scroll_prop_ip == 0 && lv_indev_is_dragging(indev) == false) {
if(((drag_vect.y > 0 && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) ||
(drag_vect.y < 0 && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom)) &&
((drag_vect.x > 0 && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) ||
(drag_vect.x < 0 && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right))) {
if(lv_obj_get_parent(page_parent) != NULL) { /*Do not propagate the scroll to a screen*/
page_ext->scroll_prop_ip = 1;
if(page_ext->scroll_prop_dir != LV_DRAG_DIR_NONE && indev) {
lv_point_t * drag_sum = &indev->proc.types.pointer.drag_sum;
lv_page_ext_t * parent_ext = lv_obj_get_ext_attr(lv_obj_get_parent(page_parent));
if(parent_ext->scroll_prop_obj == NULL) {
/*If the dragging just started enable the scroll propagation if the conditions are met*/
if(lv_indev_is_dragging(indev) == false && (drag_sum->y || drag_sum->x)) {
/*Propagate vertically?*/
if(page_ext->scroll_prop_dir == LV_DRAG_DIR_ALL || page_ext->scroll_prop_dir == LV_DRAG_DIR_VER || page_ext->scroll_prop_dir == LV_DRAG_DIR_ONE) {
if((drag_sum->y > 0 && lv_page_on_edge(page, LV_PAGE_EDGE_TOP)) ||
(drag_sum->y < 0 && lv_page_on_edge(page, LV_PAGE_EDGE_BOTTOM))) {
lv_obj_set_drag_parent(page, true);
lv_obj_set_drag_parent(scrl, true);
parent_ext->scroll_prop_obj = page;
printf("prop_start ver\n");
}
}
/*Propagate horizontally?*/
if(page_ext->scroll_prop_dir == LV_DRAG_DIR_ALL || page_ext->scroll_prop_dir == LV_DRAG_DIR_HOR || page_ext->scroll_prop_dir == LV_DRAG_DIR_ONE) {
if((drag_sum->x > 0 && lv_page_on_edge(page, LV_PAGE_EDGE_LEFT)) ||
(drag_sum->x < 0 && lv_page_on_edge(page, LV_PAGE_EDGE_RIGHT))) {
lv_obj_set_drag_parent(page, true);
lv_obj_set_drag_parent(scrl, true);
parent_ext->scroll_prop_obj = page;
printf("prop_start hor\n");
}
}
}
}
}
@ -957,17 +970,8 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
refr_x = true;
}
} else {
/*If the scroll propagation is in progress revert the original coordinates (don't let
* the page scroll)*/
if(page_ext->scroll_prop_ip) {
if(drag_vect.x == diff_x) { /*`scrl` is bouncing: drag pos. it somewhere and here it
is reverted. Handle only the pos. because of drag*/
new_x = ori_coords->x1 - page_coords.x1;
refr_x = true;
}
}
/*The edges of the scrollable can not be in the page (minus hpad) */
else if(scrl_coords.x2 < page_coords.x2 - page_style->body.padding.right) {
if(scrl_coords.x2 < page_coords.x2 - page_style->body.padding.right) {
new_x = lv_area_get_width(&page_coords) - lv_area_get_width(&scrl_coords) -
page_style->body.padding.right; /* Right align */
refr_x = true;
@ -1000,17 +1004,8 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
refr_y = true;
}
} else {
/*If the scroll propagation is in progress revert the original coordinates (don't let
* the page scroll)*/
if(page_ext->scroll_prop_ip) {
if(drag_vect.y == diff_y) { /*`scrl` is bouncing: drag pos. it somewhere and here it
is reverted. Handle only the pos. because of drag*/
new_y = ori_coords->y1 - page_coords.y1;
refr_y = true;
}
}
/*The edges of the scrollable can not be in the page (minus vpad) */
else if(scrl_coords.y2 < page_coords.y2 - page_style->body.padding.bottom) {
if(scrl_coords.y2 < page_coords.y2 - page_style->body.padding.bottom) {
new_y = lv_area_get_height(&page_coords) - lv_area_get_height(&scrl_coords) -
page_style->body.padding.bottom; /* Bottom align */
refr_y = true;
@ -1039,17 +1034,30 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
if(refr_x || refr_y) {
lv_obj_set_pos(scrl, new_x, new_y);
if(page_ext->scroll_prop_ip) {
if(refr_y) lv_obj_set_y(page_parent, lv_obj_get_y(page_parent) + diff_y);
if(refr_x) lv_obj_set_x(page_parent, lv_obj_get_x(page_parent) + diff_x);
/* If an object is propagating scroll to this object but
* it can scroll further to the desired direction
* stop scroll propagation*/
if(page_ext->scroll_prop_obj) {
// if(refr_y && ) {
// lv_obj_set_drag_parent(page_ext->scroll_prop_obj, false);
// lv_obj_set_drag_parent(lv_page_get_scrl(page_ext->scroll_prop_obj), false);
// page_ext->scroll_prop_obj = NULL;
// printf("remove prop\n");
// }
}
}
lv_page_sb_refresh(page);
} else if(sign == LV_SIGNAL_DRAG_END) {
printf("drag_end\n");
/*Scroll propagation is finished on drag end*/
page_ext->scroll_prop_ip = 0;
if(page_ext->scroll_prop_obj) {
printf("prop_end\n");
lv_obj_set_drag_parent(page_ext->scroll_prop_obj, false);
lv_obj_set_drag_parent(lv_page_get_scrl(page_ext->scroll_prop_obj), false);
page_ext->scroll_prop_obj = NULL;
}
/*Hide scrollbars if required*/
if(page_ext->sb.mode == LV_SB_MODE_DRAG) {

View File

@ -86,9 +86,8 @@ typedef struct
uint16_t anim_time; /*Scroll animation time*/
#endif
uint8_t scroll_prop : 1; /*1: Propagate the scrolling the the parent if the edge is reached*/
uint8_t scroll_prop_ip : 1; /*1: Scroll propagation is in progress (used by the library)*/
lv_obj_t * scroll_prop_obj; /*Pointer to child page from where the scroll is being propagated */
lv_drag_dir_t scroll_prop_dir :3; /*The direction of the scroll propagation*/
} lv_page_ext_t;
enum {
@ -155,7 +154,7 @@ void lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time);
* @param page pointer to a Page
* @param en true or false to enable/disable scroll propagation
*/
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en);
void lv_page_set_scroll_propagation(lv_obj_t * page, lv_drag_dir_t dir);
/**
* Enable the edge flash effect. (Show an arc when the an edge is reached)
@ -255,7 +254,7 @@ lv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page);
* @param page pointer to a Page
* @return true or false
*/
bool lv_page_get_scroll_propagation(lv_obj_t * page);
lv_drag_dir_t lv_page_get_scroll_propagation(lv_obj_t * page);
/**
* Get the edge flash effect property.

View File

@ -246,9 +246,9 @@ static inline void lv_ta_set_sb_mode(lv_obj_t * ta, lv_sb_mode_t mode)
* @param ta pointer to a Text area
* @param en true or false to enable/disable scroll propagation
*/
static inline void lv_ta_set_scroll_propagation(lv_obj_t * ta, bool en)
static inline void lv_ta_set_scroll_propagation(lv_obj_t * ta, lv_drag_dir_t dir)
{
lv_page_set_scroll_propagation(ta, en);
lv_page_set_scroll_propagation(ta, dir);
}
/**

View File

@ -34,7 +34,6 @@
**********************/
static lv_res_t lv_tileview_signal(lv_obj_t * tileview, lv_signal_t sign, void * param);
static lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);
static void tileview_scrl_event_cb(lv_obj_t * scrl, lv_event_t event);
static void drag_end_handler(lv_obj_t * tileview);
static bool set_valid_drag_dirs(lv_obj_t * tileview);
@ -99,7 +98,6 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_set_drag_throw(lv_page_get_scrl(new_tileview), false);
lv_page_set_scrl_fit(new_tileview, LV_FIT_TIGHT);
lv_obj_set_event_cb(ext->page.scrl, tileview_scrl_event_cb);
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
if(th) {
@ -142,16 +140,18 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
*/
void lv_tileview_add_element(lv_obj_t * tileview, lv_obj_t * element)
{
/* Let the objects event to propagate to the scrollable part of the tileview.
* It is required the handle dargging of the tileview with the element.*/
element->parent_event = 1;
lv_obj_set_drag_parent(element, true);
lv_page_glue_obj(element, true);
/* When adding a new element the coordinates may shift.
* For example y=1 can become y=1 if an element is added to the top.
* So be sure the current tile is correctly shown*/
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
lv_tileview_set_tile_act(tileview, ext->act_id.x, ext->act_id.y, false);
// /* Let the objects event to propagate to the scrollable part of the tileview.
// * It is required the handle dargging of the tileview with the element.*/
// element->parent_event = 1;
// lv_obj_set_drag_parent(element, true);
//
// /* When adding a new element the coordinates may shift.
// * For example y=1 can become y=1 if an element is added to the top.
// * So be sure the current tile is correctly shown*/
// lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
// lv_tileview_set_tile_act(tileview, ext->act_id.x, ext->act_id.y, false);
}
/*=====================
@ -353,9 +353,26 @@ static lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void
lv_obj_t * tileview = lv_obj_get_parent(scrl);
const lv_style_t * style_bg = lv_tileview_get_style(tileview, LV_TILEVIEW_STYLE_MAIN);
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
if(sign == LV_SIGNAL_DRAG_BEGIN) {
ext->drag_hor = 0;
ext->drag_ver = 0;
set_valid_drag_dirs(tileview);
}
else if(sign == LV_SIGNAL_DRAG_END) {
/* If the element was dragged and it moved the tileview finish the drag manually to
* let the tileview to finish the move.*/
lv_indev_t * indev = lv_indev_get_act();
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
if(lv_indev_is_dragging(indev) && (ext->drag_hor || ext->drag_ver)) {
indev->proc.types.pointer.drag_in_prog = 0;
}
drag_end_handler(tileview);
}
/*Apply constraint on moving of the tileview*/
if(sign == LV_SIGNAL_CORD_CHG) {
else if(sign == LV_SIGNAL_CORD_CHG && 0) {
lv_indev_t * indev = lv_indev_get_act();
if(indev) {
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
@ -458,37 +475,14 @@ static lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void
return res;
}
static void tileview_scrl_event_cb(lv_obj_t * scrl, lv_event_t event)
{
lv_obj_t * tileview = lv_obj_get_parent(scrl);
/*Initialize some variables on PRESS*/
if(event == LV_EVENT_PRESSED) {
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
ext->drag_hor = 0;
ext->drag_ver = 0;
set_valid_drag_dirs(tileview);
}
/*Animate the tabview to the correct location on RELEASE*/
else if(event == LV_EVENT_PRESS_LOST || event == LV_EVENT_RELEASED) {
/* If the element was dragged and it moved the tileview finish the drag manually to
* let the tileview to finish the move.*/
lv_indev_t * indev = lv_indev_get_act();
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
if(lv_indev_is_dragging(indev) && (ext->drag_hor || ext->drag_ver)) {
indev->proc.types.pointer.drag_in_prog = 0;
}
drag_end_handler(tileview);
}
}
/**
* Called when the user releases an element of the tileview after dragging it.
* @param tileview pointer to a tileview object
*/
static void drag_end_handler(lv_obj_t * tileview)
{
return;
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
lv_indev_t * indev = lv_indev_get_act();
lv_point_t point_act;
@ -538,6 +532,7 @@ static void drag_end_handler(lv_obj_t * tileview)
/*Set the new tile*/
lv_tileview_set_tile_act(tileview, ext->act_id.x + x_move, ext->act_id.y + y_move, true);
}
static bool set_valid_drag_dirs(lv_obj_t * tileview)
@ -546,6 +541,12 @@ static bool set_valid_drag_dirs(lv_obj_t * tileview)
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
if(ext->valid_pos == NULL) return false;
ext->drag_bottom_en = 1;
ext->drag_top_en = 1;
ext->drag_left_en = 1;
ext->drag_right_en = 1;
return true;
ext->drag_bottom_en = 0;
ext->drag_top_en = 0;
ext->drag_left_en = 0;