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

scroll propagaton reworked to use drag_parent

This commit is contained in:
Gabor Kiss-Vamosi 2019-09-17 16:07:30 +02:00
parent c79ada1a46
commit e523070d0f
8 changed files with 177 additions and 265 deletions

View File

@ -40,7 +40,7 @@ static void indev_proc_press(lv_indev_proc_t * proc);
static void indev_proc_release(lv_indev_proc_t * proc);
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(lv_indev_proc_t * proc);
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);
@ -744,6 +744,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
proc->types.pointer.drag_in_prog = 0;
proc->types.pointer.drag_sum.x = 0;
proc->types.pointer.drag_sum.y = 0;
proc->types.pointer.drag_dir = LV_DRAG_DIR_NONE;
proc->types.pointer.vect.x = 0;
proc->types.pointer.vect.y = 0;
@ -981,6 +982,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
indev->proc.longpr_rep_timestamp = 0;
indev->proc.types.pointer.drag_sum.x = 0;
indev->proc.types.pointer.drag_sum.y = 0;
indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_NONE;
indev->proc.types.pointer.drag_throw_vect.x = 0;
indev->proc.types.pointer.drag_throw_vect.y = 0;
indev->proc.reset_query = 0;
@ -1049,9 +1051,9 @@ static lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj)
* Handle the dragging of indev_proc_p->types.pointer.act_obj
* @param indev pointer to a input device state
*/
static void indev_drag(lv_indev_proc_t * state)
static void indev_drag(lv_indev_proc_t * proc)
{
lv_obj_t * drag_obj = get_dragged_obj(state->types.pointer.act_obj);
lv_obj_t * drag_obj = get_dragged_obj(proc->types.pointer.act_obj);
bool drag_just_started = false;
if(drag_obj == NULL) return;
@ -1061,25 +1063,25 @@ 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*/
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;
if(proc->types.pointer.drag_limit_out == 0) {
proc->types.pointer.drag_sum.x += proc->types.pointer.vect.x;
proc->types.pointer.drag_sum.y += proc->types.pointer.vect.y;
}
/*Enough move?*/
if(state->types.pointer.drag_limit_out == 0) {
if(proc->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) {
if(allowed_dirs == LV_DRAG_DIR_HOR || allowed_dirs == LV_DRAG_DIR_BOTH) {
hor_en = true;
}
if(allowed_dirs == LV_DRAG_DIR_VER || allowed_dirs == LV_DRAG_DIR_ALL) {
if(allowed_dirs == LV_DRAG_DIR_VER || allowed_dirs == LV_DRAG_DIR_BOTH) {
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)) {
if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) {
hor_en = true;
} else {
ver_en = true;
@ -1087,17 +1089,17 @@ static void indev_drag(lv_indev_proc_t * state)
}
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
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;
if((hor_en && LV_MATH_ABS(proc->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
(ver_en && LV_MATH_ABS(proc->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {
proc->types.pointer.drag_limit_out = 1;
drag_just_started = true;
}
}
/*If the drag limit is exceeded handle the dragging*/
if(state->types.pointer.drag_limit_out != 0) {
if(proc->types.pointer.drag_limit_out != 0) {
/*Set new position if the vector is not zero*/
if(state->types.pointer.vect.x != 0 || state->types.pointer.vect.y != 0) {
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
uint16_t inv_buf_size =
lv_disp_get_inv_buf_size(indev_act->driver.disp); /*Get the number of currently invalidated areas*/
@ -1111,49 +1113,54 @@ static void indev_drag(lv_indev_proc_t * state)
lv_coord_t act_x = lv_obj_get_x(drag_obj);
lv_coord_t act_y = lv_obj_get_y(drag_obj);
if(allowed_dirs == LV_DRAG_DIR_ALL) {
if(allowed_dirs == LV_DRAG_DIR_BOTH) {
if(drag_just_started) {
act_x += state->types.pointer.drag_sum.x;
act_y += state->types.pointer.drag_sum.y;
proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
act_x += proc->types.pointer.drag_sum.x;
act_y += proc->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);
lv_obj_set_pos(drag_obj, act_x + proc->types.pointer.vect.x, act_y + proc->types.pointer.vect.y);
} 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;
proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
proc->types.pointer.drag_sum.y = 0;
act_x += proc->types.pointer.drag_sum.x;
}
lv_obj_set_x(drag_obj, act_x + state->types.pointer.vect.x);
lv_obj_set_x(drag_obj, act_x + proc->types.pointer.vect.x);
} 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;
proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
proc->types.pointer.drag_sum.x = 0;
act_y += proc->types.pointer.drag_sum.y;
}
lv_obj_set_y(drag_obj, act_y + state->types.pointer.vect.y);
lv_obj_set_y(drag_obj, act_y + proc->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;
if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) {
proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
proc->types.pointer.drag_sum.y = 0;
act_x += proc->types.pointer.drag_sum.x;
} else {
state->types.pointer.drag_sum.x = 0;
proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
proc->types.pointer.drag_sum.x = 0;
act_y += proc->types.pointer.drag_sum.y;
}
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;
/*In the inactive direction `drag_sum` is kept zero*/
if(proc->types.pointer.drag_sum.x) act_x += proc->types.pointer.vect.x;
if(proc->types.pointer.drag_sum.y) act_y += proc->types.pointer.vect.y;
lv_obj_set_pos(drag_obj, act_x, act_y);
state->types.pointer.drag_in_prog = 1;
proc->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;
if(indev_reset_check(proc)) return;
lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
if(indev_reset_check(state)) return;
if(indev_reset_check(proc)) return;
}
}
@ -1211,7 +1218,7 @@ 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);
if(allowed_dirs == LV_DRAG_DIR_BOTH) 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) {

View File

@ -280,7 +280,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
/*Set attributes*/
new_obj->click = 1;
new_obj->drag = 0;
new_obj->drag_dir = LV_DRAG_DIR_ALL;
new_obj->drag_dir = LV_DRAG_DIR_BOTH;
new_obj->drag_throw = 0;
new_obj->drag_parent = 0;
new_obj->hidden = 0;

View File

@ -183,16 +183,6 @@ typedef struct
} lv_reailgn_t;
#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;
typedef struct _lv_obj_t
{
struct _lv_obj_t * par; /**< Pointer to the parent object*/

View File

@ -54,6 +54,18 @@ typedef uint8_t lv_indev_type_t;
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
typedef uint8_t lv_indev_state_t;
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_BOTH = 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;
/** Data structure passed to an input driver to fill */
typedef struct
{
@ -65,6 +77,7 @@ typedef struct
lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
} lv_indev_data_t;
/** Initialized by the user and registered by 'lv_indev_add()'*/
typedef struct _lv_indev_drv_t
{
@ -127,6 +140,7 @@ typedef struct _lv_indev_proc_t
/*Flags*/
uint8_t drag_limit_out : 1;
uint8_t drag_in_prog : 1;
lv_drag_dir_t drag_dir : 3;
} pointer;
struct
{ /*Keypad data*/

View File

@ -103,7 +103,7 @@ 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_dir = 0;
ext->scroll_prop = 0;
ext->scroll_prop_obj = NULL;
/*Init the new page object*/
@ -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, lv_drag_dir_t dir)
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en)
{
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
ext->scroll_prop_dir = dir;
ext->scroll_prop = en ? 1 : 0;
}
/**
@ -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
*/
lv_drag_dir_t lv_page_get_scroll_propagation(lv_obj_t * page)
bool lv_page_get_scroll_propagation(lv_obj_t * page)
{
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
return ext->scroll_prop_dir;
return ext->scroll_prop ? true : false;
}
/**
@ -596,29 +596,45 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist)
/**
* Not intended to use directly by the user but by other object types internally.
* Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set
* Start an edge flash animation.
* @param page
* @param edge the edge to flash. Can be `LV_PAGE_EDGE_LEFT/RIGHT/TOP/BOTTOM`
*/
void lv_page_start_edge_flash(lv_obj_t * page)
void lv_page_start_edge_flash(lv_obj_t * page, lv_page_edge_t edge)
{
#if LV_USE_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
if(ext->edge_flash.enabled) {
lv_anim_t a;
a.var = page;
a.start = 0;
a.end = LV_PAGE_END_FLASH_SIZE;
a.exec_cb = (lv_anim_exec_xcb_t)edge_flash_anim;
a.path_cb = lv_anim_path_linear;
a.ready_cb = edge_flash_anim_end;
a.act_time = 0;
a.time = LV_PAGE_END_ANIM_TIME;
a.playback = 1;
a.playback_pause = LV_PAGE_END_ANIM_WAIT_TIME;
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
if(ext->edge_flash.enabled == 0) return;
if(ext->edge_flash.left_ip ||
ext->edge_flash.right_ip ||
ext->edge_flash.top_ip ||
ext->edge_flash.bottom_ip) {
return;
}
lv_anim_t a;
a.var = page;
a.start = 0;
a.end = LV_PAGE_END_FLASH_SIZE;
a.exec_cb = (lv_anim_exec_xcb_t)edge_flash_anim;
a.path_cb = lv_anim_path_linear;
a.ready_cb = edge_flash_anim_end;
a.act_time = 0;
a.time = LV_PAGE_END_ANIM_TIME;
a.playback = 1;
a.playback_pause = LV_PAGE_END_ANIM_WAIT_TIME;
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
switch(edge) {
case LV_PAGE_EDGE_BOTTOM: ext->edge_flash.bottom_ip = 1; break;
case LV_PAGE_EDGE_TOP: ext->edge_flash.top_ip = 1; break;
case LV_PAGE_EDGE_LEFT: ext->edge_flash.left_ip = 1; break;
case LV_PAGE_EDGE_RIGHT: ext->edge_flash.right_ip = 1; break;
}
#else
(void)page; /*Unused*/
#endif
@ -806,8 +822,19 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
if(res != LV_RES_OK) return res;
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_obj_t * child;
if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/
if(sign == LV_SIGNAL_CLEANUP) {
/*Check whether the object being deleted is propagating scroll to the parent */
if(ext->scroll_prop) {
lv_obj_t * parent_page = lv_obj_get_parent(lv_obj_get_parent(page));
lv_page_ext_t * parent_ext = lv_obj_get_ext_attr(parent_page);
if(parent_ext->scroll_prop_obj == page) {
parent_ext->scroll_prop_obj = NULL;
}
}
}
/*Automatically move children to the scrollable object*/
else if(sign == LV_SIGNAL_CHILD_CHG) {
lv_obj_t * child;
const lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
lv_fit_t fit_left = lv_page_get_scrl_fit_left(page);
lv_fit_t fit_top = lv_page_get_scrl_fit_top(page);
@ -924,40 +951,31 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
lv_obj_get_coords(scrl, &scrl_coords);
lv_obj_get_coords(page, &page_coords);
lv_area_t * ori_coords = (lv_area_t *)param;
lv_coord_t diff_x = scrl->coords.x1 - ori_coords->x1;
lv_coord_t diff_y = scrl->coords.y1 - ori_coords->y1;
lv_coord_t hpad = page_style->body.padding.left + page_style->body.padding.right;
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();
if(page_ext->scroll_prop_dir != LV_DRAG_DIR_NONE && indev) {
if(page_ext->scroll_prop && 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");
}
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;
}
/*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");
}
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;
}
}
}
@ -975,25 +993,11 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
new_x = lv_area_get_width(&page_coords) - lv_area_get_width(&scrl_coords) -
page_style->body.padding.right; /* Right align */
refr_x = true;
#if LV_USE_ANIMATION
if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&
page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&
page_ext->edge_flash.bottom_ip == 0) {
lv_page_start_edge_flash(page);
page_ext->edge_flash.right_ip = 1;
}
#endif
lv_page_start_edge_flash(page, LV_PAGE_EDGE_RIGHT);
} else if(scrl_coords.x1 > page_coords.x1 + page_style->body.padding.left) {
new_x = page_style->body.padding.left; /*Left align*/
refr_x = true;
#if LV_USE_ANIMATION
if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&
page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&
page_ext->edge_flash.bottom_ip == 0) {
lv_page_start_edge_flash(page);
page_ext->edge_flash.left_ip = 1;
}
#endif
lv_page_start_edge_flash(page, LV_PAGE_EDGE_LEFT);
}
}
@ -1009,54 +1013,40 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
new_y = lv_area_get_height(&page_coords) - lv_area_get_height(&scrl_coords) -
page_style->body.padding.bottom; /* Bottom align */
refr_y = true;
#if LV_USE_ANIMATION
if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&
page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&
page_ext->edge_flash.bottom_ip == 0) {
lv_page_start_edge_flash(page);
page_ext->edge_flash.bottom_ip = 1;
}
#endif
lv_page_start_edge_flash(page, LV_PAGE_EDGE_BOTTOM);
} else if(scrl_coords.y1 > page_coords.y1 + page_style->body.padding.top) {
new_y = page_style->body.padding.top; /*Top align*/
refr_y = true;
#if LV_USE_ANIMATION
if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&
page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&
page_ext->edge_flash.bottom_ip == 0) {
lv_page_start_edge_flash(page);
page_ext->edge_flash.top_ip = 1;
}
#endif
lv_page_start_edge_flash(page, LV_PAGE_EDGE_TOP);
}
}
if(refr_x || refr_y) {
lv_obj_set_pos(scrl, new_x, new_y);
/* 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*/
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);
lv_obj_t * scroller_page = page_ext->scroll_prop_obj;
page_ext->scroll_prop_obj = NULL;
lv_obj_set_drag_parent(scroller_page, false);
lv_obj_set_drag_parent(lv_page_get_scrl(scroller_page), false);
/*The scrolling can be chained so stop all of them*/
lv_page_ext_t * scroller_ext = lv_obj_get_ext_attr(scroller_page);
while(scroller_ext->scroll_prop_obj) {
scroller_page = scroller_ext->scroll_prop_obj;
scroller_ext->scroll_prop_obj = NULL;
lv_obj_set_drag_parent(scroller_page, false);
lv_obj_set_drag_parent(lv_page_get_scrl(scroller_page), false);
scroller_ext = lv_obj_get_ext_attr(scroller_page);
}
}
/*Hide scrollbars if required*/

View File

@ -87,7 +87,7 @@ typedef struct
uint16_t anim_time; /*Scroll animation time*/
#endif
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*/
uint8_t scroll_prop :1; /*The direction of the scroll propagation*/
} lv_page_ext_t;
enum {
@ -154,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, lv_drag_dir_t dir);
void lv_page_set_scroll_propagation(lv_obj_t * page, bool en);
/**
* Enable the edge flash effect. (Show an arc when the an edge is reached)
@ -254,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
*/
lv_drag_dir_t lv_page_get_scroll_propagation(lv_obj_t * page);
bool lv_page_get_scroll_propagation(lv_obj_t * page);
/**
* Get the edge flash effect property.
@ -398,10 +398,12 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist);
/**
* Not intended to use directly by the user but by other object types internally.
* Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set
* Start an edge flash animation.
* @param page
* @param edge the edge to flash. Can be `LV_PAGE_EDGE_LEFT/RIGHT/TOP/BOTTOM`
*/
void lv_page_start_edge_flash(lv_obj_t * page);
void lv_page_start_edge_flash(lv_obj_t * page, lv_page_edge_t edge);
/**********************
* MACROS
**********************/

View File

@ -75,7 +75,7 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_tileview));
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_tileview);
/*Initialize the allocated 'ext' */
/*Initialize the allocated 'ext' */
#if LV_USE_ANIMATION
ext->anim_time = LV_TILEVIEW_DEF_ANIM_TIME;
#endif
@ -94,7 +94,7 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
* Don't use `par` directly because if the tileview is created on a page it is moved to the
* scrollable so the parent has changed */
lv_obj_set_size(new_tileview, lv_obj_get_width_fit(lv_obj_get_parent(new_tileview)),
lv_obj_get_height_fit(lv_obj_get_parent(new_tileview)));
lv_obj_get_height_fit(lv_obj_get_parent(new_tileview)));
lv_obj_set_drag_throw(lv_page_get_scrl(new_tileview), false);
lv_page_set_scrl_fit(new_tileview, LV_FIT_TIGHT);
@ -141,17 +141,6 @@ 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)
{
lv_page_glue_obj(element, true);
// /* 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);
}
/*=====================
@ -171,6 +160,8 @@ void lv_tileview_set_valid_positions(lv_obj_t * tileview, const lv_point_t * val
ext->valid_pos = valid_pos;
ext->valid_pos_cnt = valid_pos_cnt;
set_valid_drag_dirs(tileview);
/*If valid pos. is selected do nothing*/
uint16_t i;
for(i = 0; i < valid_pos_cnt; i++) {
@ -253,6 +244,8 @@ void lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, l
lv_res_t res = LV_RES_OK;
res = lv_event_send(tileview, LV_EVENT_VALUE_CHANGED, &tile_id);
if(res != LV_RES_OK) return; /*Prevent the tile loading*/
set_valid_drag_dirs(tileview);
}
/**
@ -265,7 +258,7 @@ void lv_tileview_set_style(lv_obj_t * tileview, lv_tileview_style_t type, const
{
switch(type) {
case LV_TILEVIEW_STYLE_MAIN: lv_obj_set_style(tileview, style); break;
case LV_TILEVIEW_STYLE_MAIN: lv_obj_set_style(tileview, style); break;
}
}
@ -287,8 +280,8 @@ const lv_style_t * lv_tileview_get_style(const lv_obj_t * tileview, lv_tileview_
{
const lv_style_t * style = NULL;
switch(type) {
case LV_TILEVIEW_STYLE_MAIN: style = lv_obj_get_style(tileview); break;
default: style = NULL;
case LV_TILEVIEW_STYLE_MAIN: style = lv_obj_get_style(tileview); break;
default: style = NULL;
}
return style;
@ -353,122 +346,48 @@ 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);
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*/
else if(sign == LV_SIGNAL_CORD_CHG && 0) {
else if(sign == LV_SIGNAL_CORD_CHG) {
lv_indev_t * indev = lv_indev_get_act();
if(indev) {
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
/*Set horizontal drag constraint if no vertical constraint an dragged to valid x
* direction */
if(ext->drag_ver == 0 &&
((ext->drag_right_en && indev->proc.types.pointer.drag_sum.x <= -LV_INDEV_DEF_DRAG_LIMIT) ||
(ext->drag_left_en && indev->proc.types.pointer.drag_sum.x >= LV_INDEV_DEF_DRAG_LIMIT))) {
ext->drag_hor = 1;
}
/*Set vertical drag constraint if no horizontal constraint an dragged to valid y
* direction */
if(ext->drag_hor == 0 &&
((ext->drag_bottom_en && indev->proc.types.pointer.drag_sum.y <= -LV_INDEV_DEF_DRAG_LIMIT) ||
(ext->drag_top_en && indev->proc.types.pointer.drag_sum.y >= LV_INDEV_DEF_DRAG_LIMIT))) {
ext->drag_ver = 1;
}
#if LV_USE_ANIMATION
if(ext->drag_hor) {
ext->page.edge_flash.top_ip = 0;
ext->page.edge_flash.bottom_ip = 0;
}
if(ext->drag_ver) {
ext->page.edge_flash.right_ip = 0;
ext->page.edge_flash.left_ip = 0;
}
#endif
lv_coord_t x = lv_obj_get_x(scrl);
lv_coord_t y = lv_obj_get_y(scrl);
lv_coord_t h = lv_obj_get_height(tileview);
lv_coord_t w = lv_obj_get_width(tileview);
if(ext->drag_top_en == 0) {
if(y > -(ext->act_id.y * h) && indev->proc.types.pointer.vect.y > 0 && ext->drag_hor == 0) {
#if LV_USE_ANIMATION
if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&
ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&
ext->page.edge_flash.bottom_ip == 0) {
ext->page.edge_flash.top_ip = 1;
lv_page_start_edge_flash(tileview);
}
#endif
lv_obj_set_y(scrl, -ext->act_id.y * h + style_bg->body.padding.top);
}
}
if(ext->drag_bottom_en == 0 && indev->proc.types.pointer.vect.y < 0 && ext->drag_hor == 0) {
if(y < -(ext->act_id.y * h)) {
#if LV_USE_ANIMATION
if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&
ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&
ext->page.edge_flash.bottom_ip == 0) {
ext->page.edge_flash.bottom_ip = 1;
lv_page_start_edge_flash(tileview);
}
#endif
}
if(!ext->drag_top_en && y > -(ext->act_id.y * h) && indev->proc.types.pointer.vect.y > 0) {
lv_page_start_edge_flash(tileview, LV_PAGE_EDGE_TOP);
lv_obj_set_y(scrl, -ext->act_id.y * h + style_bg->body.padding.top);
}
if(ext->drag_left_en == 0) {
if(x > -(ext->act_id.x * w) && indev->proc.types.pointer.vect.x > 0 && ext->drag_ver == 0) {
#if LV_USE_ANIMATION
if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&
ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&
ext->page.edge_flash.bottom_ip == 0) {
ext->page.edge_flash.left_ip = 1;
lv_page_start_edge_flash(tileview);
}
#endif
lv_obj_set_x(scrl, -ext->act_id.x * w + style_bg->body.padding.left);
}
if(!ext->drag_bottom_en && indev->proc.types.pointer.vect.y < 0 && y < -(ext->act_id.y * h)) {
lv_page_start_edge_flash(tileview, LV_PAGE_EDGE_BOTTOM);
lv_obj_set_y(scrl, -ext->act_id.y * h + style_bg->body.padding.top);
}
if(ext->drag_right_en == 0 && indev->proc.types.pointer.vect.x < 0 && ext->drag_ver == 0) {
if(x < -(ext->act_id.x * w)) {
#if LV_USE_ANIMATION
if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&
ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&
ext->page.edge_flash.bottom_ip == 0) {
ext->page.edge_flash.right_ip = 1;
lv_page_start_edge_flash(tileview);
}
#endif
}
if(!ext->drag_left_en && x > -(ext->act_id.x * w) && indev->proc.types.pointer.vect.x > 0) {
lv_page_start_edge_flash(tileview, LV_PAGE_EDGE_LEFT);
lv_obj_set_x(scrl, -ext->act_id.x * w + style_bg->body.padding.left);
}
if(!ext->drag_right_en && indev->proc.types.pointer.vect.x < 0 && x < -(ext->act_id.x * w)) {
lv_page_start_edge_flash(tileview, LV_PAGE_EDGE_RIGHT);
lv_obj_set_x(scrl, -ext->act_id.x * w + style_bg->body.padding.top);
}
/*Apply the drag constraints*/
if(ext->drag_ver == 0)
lv_drag_dir_t drag_dir = indev->proc.types.pointer.drag_dir;
if(drag_dir & LV_DRAG_DIR_HOR)
lv_obj_set_y(scrl, -ext->act_id.y * lv_obj_get_height(tileview) + style_bg->body.padding.top);
if(ext->drag_hor == 0)
if(drag_dir & LV_DRAG_DIR_VER)
lv_obj_set_x(scrl, -ext->act_id.x * lv_obj_get_width(tileview) + style_bg->body.padding.left);
}
}
@ -481,8 +400,6 @@ static lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void
*/
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;
@ -493,8 +410,9 @@ static void drag_end_handler(lv_obj_t * tileview)
p.x = -(scrl->coords.x1 - lv_obj_get_width(tileview) / 2);
p.y = -(scrl->coords.y1 - lv_obj_get_height(tileview) / 2);
lv_drag_dir_t drag_dir = indev->proc.types.pointer.drag_dir;
/*From the drag vector (drag throw) predict the end position*/
if(ext->drag_hor) {
if(drag_dir & LV_DRAG_DIR_HOR) {
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t predict = 0;
@ -505,7 +423,7 @@ static void drag_end_handler(lv_obj_t * tileview)
}
p.x -= predict;
} else if(ext->drag_ver) {
} else if(drag_dir & LV_DRAG_DIR_VER) {
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t predict = 0;
@ -532,7 +450,6 @@ 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)
@ -541,12 +458,6 @@ 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;

View File

@ -46,8 +46,6 @@ typedef struct
uint8_t drag_bottom_en : 1;
uint8_t drag_left_en : 1;
uint8_t drag_right_en : 1;
uint8_t drag_hor : 1;
uint8_t drag_ver : 1;
} lv_tileview_ext_t;
/*Styles*/