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:
parent
f445f1965b
commit
c79ada1a46
@ -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'
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user