mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-21 06:53:01 +08:00
scroll: wip
This commit is contained in:
parent
9cfd399fb3
commit
0cea8b2c08
@ -1095,6 +1095,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
|
|||||||
if(indev->proc.reset_query) {
|
if(indev->proc.reset_query) {
|
||||||
indev->proc.types.pointer.act_obj = NULL;
|
indev->proc.types.pointer.act_obj = NULL;
|
||||||
indev->proc.types.pointer.last_obj = NULL;
|
indev->proc.types.pointer.last_obj = NULL;
|
||||||
|
indev->proc.types.pointer.drag_obj = NULL;
|
||||||
indev->proc.types.pointer.drag_limit_out = 0;
|
indev->proc.types.pointer.drag_limit_out = 0;
|
||||||
indev->proc.types.pointer.drag_in_prog = 0;
|
indev->proc.types.pointer.drag_in_prog = 0;
|
||||||
indev->proc.long_pr_sent = 0;
|
indev->proc.long_pr_sent = 0;
|
||||||
@ -1251,25 +1252,26 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
|||||||
*/
|
*/
|
||||||
static void indev_drag(lv_indev_proc_t * proc)
|
static void indev_drag(lv_indev_proc_t * proc)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool scrollable = true;
|
bool scrollable = true;
|
||||||
|
|
||||||
/*Get which object to drad/scroll*/
|
/*Get which object to drad/scroll*/
|
||||||
lv_obj_t * target_obj = get_dragged_obj(proc->types.pointer.act_obj);
|
|
||||||
if(target_obj == NULL) return;
|
|
||||||
|
|
||||||
lv_drag_dir_t dirs = LV_DRAG_DIR_VER; //scrollable ? lv_obj_get_scroll_dir(target_obj) : lv_obj_get_drag_dir(target_obj);
|
lv_drag_dir_t dirs = LV_DRAG_DIR_VER; //scrollable ? lv_obj_get_scroll_dir(target_obj) : lv_obj_get_drag_dir(target_obj);
|
||||||
bool just_started = false;
|
bool just_started = false;
|
||||||
|
|
||||||
/*Get the coordinates of the object and modify them*/
|
lv_coord_t act_x = 0;
|
||||||
lv_coord_t act_x = lv_obj_get_x(target_obj);
|
lv_coord_t act_y = 0;
|
||||||
lv_coord_t act_y = lv_obj_get_y(target_obj);
|
|
||||||
|
|
||||||
/*Count the movement by drag*/
|
/*Count the movement by drag*/
|
||||||
if(proc->types.pointer.drag_limit_out == 0) {
|
if(proc->types.pointer.drag_limit_out == 0) {
|
||||||
proc->types.pointer.drag_sum.x += proc->types.pointer.vect.x;
|
proc->types.pointer.drag_sum.x += proc->types.pointer.vect.x;
|
||||||
proc->types.pointer.drag_sum.y += proc->types.pointer.vect.y;
|
proc->types.pointer.drag_sum.y += proc->types.pointer.vect.y;
|
||||||
|
|
||||||
|
proc->types.pointer.drag_obj = proc->types.pointer.act_obj;
|
||||||
|
|
||||||
|
/*Go until find the object or parent scrollable in this direction*/
|
||||||
|
while(proc->types.pointer.drag_obj) {
|
||||||
|
dirs = LV_DRAG_DIR_VER;
|
||||||
|
|
||||||
/*Enough move?*/
|
/*Enough move?*/
|
||||||
bool hor_en = false;
|
bool hor_en = false;
|
||||||
bool ver_en = false;
|
bool ver_en = false;
|
||||||
@ -1290,9 +1292,16 @@ static void indev_drag(lv_indev_proc_t * proc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool up_en = ver_en;
|
||||||
|
bool down_en = ver_en;
|
||||||
|
|
||||||
|
if(lv_obj_get_scroll_top(proc->types.pointer.drag_obj) <= 0) up_en = false;
|
||||||
|
if(lv_obj_get_scroll_bottom(proc->types.pointer.drag_obj) <= 0) down_en = false;
|
||||||
|
|
||||||
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
|
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
|
||||||
if((hor_en && LV_MATH_ABS(proc->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
|
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)) {
|
(up_en && proc->types.pointer.drag_sum.y >= indev_act->driver.drag_limit) ||
|
||||||
|
(down_en && proc->types.pointer.drag_sum.y <= -indev_act->driver.drag_limit)) {
|
||||||
proc->types.pointer.drag_limit_out = 1;
|
proc->types.pointer.drag_limit_out = 1;
|
||||||
just_started = true;
|
just_started = true;
|
||||||
if(dirs == LV_DRAG_DIR_ONE) {
|
if(dirs == LV_DRAG_DIR_ONE) {
|
||||||
@ -1305,18 +1314,69 @@ static void indev_drag(lv_indev_proc_t * proc)
|
|||||||
if(!hor_en) proc->types.pointer.drag_sum.x = 0;
|
if(!hor_en) proc->types.pointer.drag_sum.x = 0;
|
||||||
if(!ver_en) proc->types.pointer.drag_sum.y = 0;
|
if(!ver_en) proc->types.pointer.drag_sum.y = 0;
|
||||||
|
|
||||||
act_x += proc->types.pointer.drag_sum.x;
|
act_x = lv_obj_get_x(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.x;
|
||||||
act_y += proc->types.pointer.drag_sum.y;
|
act_y = lv_obj_get_y(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
proc->types.pointer.drag_obj = lv_obj_get_parent(proc->types.pointer.drag_obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*If the drag/scroll can't be propagated to any parent show an elastic scroll in the original object*/
|
||||||
|
if(proc->types.pointer.drag_obj == NULL) {
|
||||||
|
proc->types.pointer.drag_obj = proc->types.pointer.act_obj;
|
||||||
|
//
|
||||||
|
// dirs = LV_DRAG_DIR_VER;
|
||||||
|
//
|
||||||
|
// /*Enough move?*/
|
||||||
|
// bool hor_en = false;
|
||||||
|
// bool ver_en = false;
|
||||||
|
// if(dirs == LV_DRAG_DIR_HOR || dirs == LV_DRAG_DIR_BOTH) {
|
||||||
|
// hor_en = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(dirs == LV_DRAG_DIR_VER || dirs == LV_DRAG_DIR_BOTH) {
|
||||||
|
// ver_en = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(dirs == LV_DRAG_DIR_ONE) {
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
|
||||||
|
// 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;
|
||||||
|
// just_started = true;
|
||||||
|
// if(dirs == LV_DRAG_DIR_ONE) {
|
||||||
|
// proc->types.pointer.drag_dir = hor_en ? LV_DRAG_DIR_HOR : LV_DRAG_DIR_VER;
|
||||||
|
// } else {
|
||||||
|
// proc->types.pointer.drag_dir = dirs;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*The was no move due to drag limit. Compensate it now.*/
|
||||||
|
// if(!hor_en) proc->types.pointer.drag_sum.x = 0;
|
||||||
|
// if(!ver_en) proc->types.pointer.drag_sum.y = 0;
|
||||||
|
//
|
||||||
|
// act_x = lv_obj_get_x(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.x;
|
||||||
|
// act_y = lv_obj_get_y(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.y;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
lv_obj_t * obj = proc->types.pointer.drag_obj;
|
||||||
|
|
||||||
/*If the drag limit is exceeded handle the dragging*/
|
/*If the drag limit is exceeded handle the dragging*/
|
||||||
if(proc->types.pointer.drag_limit_out != 0) {
|
if(proc->types.pointer.drag_limit_out != 0) {
|
||||||
/*Set new position or scroll if the vector is not zero*/
|
/*Set new position or scroll if the vector is not zero*/
|
||||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
||||||
|
|
||||||
lv_coord_t prev_x = target_obj->coords.x1;
|
lv_coord_t prev_x = obj->coords.x1;
|
||||||
lv_coord_t prev_y = target_obj->coords.y1;
|
lv_coord_t prev_y = obj->coords.y1;
|
||||||
|
|
||||||
/*Move the object. `drag_sum` is zerod out for *disabled direction*/
|
/*Move the object. `drag_sum` is zerod out for *disabled direction*/
|
||||||
if(proc->types.pointer.drag_sum.x) act_x += proc->types.pointer.vect.x;
|
if(proc->types.pointer.drag_sum.x) act_x += proc->types.pointer.vect.x;
|
||||||
@ -1327,18 +1387,18 @@ static void indev_drag(lv_indev_proc_t * proc)
|
|||||||
|
|
||||||
if(scrollable) {
|
if(scrollable) {
|
||||||
lv_area_t child_box;
|
lv_area_t child_box;
|
||||||
lv_obj_get_children_box(target_obj, &child_box);
|
lv_obj_get_children_box(obj, &child_box);
|
||||||
lv_coord_t diff_y = proc->types.pointer.vect.y;
|
lv_coord_t diff_y = proc->types.pointer.vect.y;
|
||||||
if(target_obj->scroll.y > 0 && diff_y > 0) {
|
if(obj->scroll.y > 0 && diff_y > 0) {
|
||||||
diff_y = diff_y / 2;
|
diff_y = diff_y / 2;
|
||||||
}
|
}
|
||||||
if(child_box.y2 < target_obj->coords.y2 && diff_y < 0) {
|
if(child_box.y2 < obj->coords.y2 && diff_y < 0) {
|
||||||
diff_y = diff_y / 2;
|
diff_y = diff_y / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_obj_scroll_by(target_obj, 0, diff_y, LV_ANIM_OFF);
|
lv_obj_scroll_by(obj, 0, diff_y, LV_ANIM_OFF);
|
||||||
} else {
|
} else {
|
||||||
lv_obj_set_pos(target_obj, act_x, act_y);
|
lv_obj_set_pos(obj, act_x, act_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->types.pointer.drag_in_prog = 1;
|
proc->types.pointer.drag_in_prog = 1;
|
||||||
@ -1397,9 +1457,9 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
|||||||
|
|
||||||
/*Reduce the vectors*/
|
/*Reduce the vectors*/
|
||||||
proc->types.pointer.drag_throw_vect.x =
|
proc->types.pointer.drag_throw_vect.x =
|
||||||
proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 30;
|
proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100;
|
||||||
proc->types.pointer.drag_throw_vect.y =
|
proc->types.pointer.drag_throw_vect.y =
|
||||||
proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 30;
|
proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100;
|
||||||
|
|
||||||
switch(proc->types.pointer.drag_dir) {
|
switch(proc->types.pointer.drag_dir) {
|
||||||
case LV_DRAG_DIR_HOR:
|
case LV_DRAG_DIR_HOR:
|
||||||
@ -1428,8 +1488,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
|||||||
lv_obj_scroll_by(target_obj, 0, -(child_box.y2 - target_obj->coords.y2), LV_ANIM_OFF);
|
lv_obj_scroll_by(target_obj, 0, -(child_box.y2 - target_obj->coords.y2), LV_ANIM_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_obj_scroll_by(target_obj, proc->types.pointer.drag_throw_vect.x, proc->types.pointer.drag_throw_vect.y, LV_ANIM_OFF);
|
||||||
lv_obj_scroll_by(target_obj, proc->types.pointer.drag_throw_vect.x, proc->types.pointer.drag_throw_vect.y);
|
|
||||||
} else {
|
} else {
|
||||||
lv_area_t coords_ori;
|
lv_area_t coords_ori;
|
||||||
lv_obj_get_coords(target_obj, &coords_ori);
|
lv_obj_get_coords(target_obj, &coords_ori);
|
||||||
@ -1463,6 +1522,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
|||||||
signal*/
|
signal*/
|
||||||
else {
|
else {
|
||||||
proc->types.pointer.drag_in_prog = 0;
|
proc->types.pointer.drag_in_prog = 0;
|
||||||
|
proc->types.pointer.drag_obj = NULL;
|
||||||
target_obj->signal_cb(target_obj, scrollable ? LV_SIGNAL_SCROLL_END : LV_SIGNAL_DRAG_END, indev_act);
|
target_obj->signal_cb(target_obj, scrollable ? LV_SIGNAL_SCROLL_END : LV_SIGNAL_DRAG_END, indev_act);
|
||||||
if(indev_reset_check(proc)) return;
|
if(indev_reset_check(proc)) return;
|
||||||
lv_event_send(target_obj, LV_EVENT_DRAG_END, NULL);
|
lv_event_send(target_obj, LV_EVENT_DRAG_END, NULL);
|
||||||
@ -1478,9 +1538,20 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
|||||||
*/
|
*/
|
||||||
static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
|
static lv_obj_t * get_dragged_obj(lv_obj_t * obj)
|
||||||
{
|
{
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
|
if(indev_act->proc.types.pointer.drag_obj) {
|
||||||
|
return indev_act->proc.types.pointer.drag_obj;
|
||||||
|
} else {
|
||||||
|
lv_area_t child_box;
|
||||||
|
lv_obj_get_children_box(obj, &child_box);
|
||||||
|
if(child_box.y2 == obj->coords.y2) indev_act->proc.types.pointer.drag_obj = lv_obj_get_parent(obj);
|
||||||
|
else indev_act->proc.types.pointer.drag_obj = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return indev_act->proc.types.pointer.drag_obj;
|
||||||
|
|
||||||
|
|
||||||
if(obj == NULL) return NULL;
|
if(obj == NULL) return NULL;
|
||||||
lv_obj_t * drag_obj = obj;
|
lv_obj_t * drag_obj = obj;
|
||||||
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
|
while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {
|
||||||
|
@ -1157,6 +1157,43 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en)
|
|||||||
lv_obj_scroll_by(obj, 0, y - obj->scroll.y, anim_en);
|
lv_obj_scroll_by(obj, 0, y - obj->scroll.y, anim_en);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the height of the area above the parent.
|
||||||
|
* That is the number of pixels the object can be scrolled down.
|
||||||
|
* Normally positive but can be negative when scrolled inside.
|
||||||
|
* @param obj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
return -obj->scroll.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the height of the area below the parent.
|
||||||
|
* That is the number of pixels the object can be scrolled up.
|
||||||
|
* Normally positive but can be negative when scrolled inside.
|
||||||
|
* @param obj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||||
|
|
||||||
|
lv_coord_t y2 = LV_COORD_MIN;
|
||||||
|
|
||||||
|
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||||
|
if(child == NULL) return 0;
|
||||||
|
|
||||||
|
while(child) {
|
||||||
|
y2 = LV_MATH_MAX(y2, child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN));
|
||||||
|
child = lv_obj_get_child(obj, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return y2 - obj->coords.y2;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the size of an extended clickable area
|
* Set the size of an extended clickable area
|
||||||
* If TINY mode is used, only the largest of the horizontal and vertical padding
|
* If TINY mode is used, only the largest of the horizontal and vertical padding
|
||||||
|
@ -534,6 +534,66 @@ void lv_obj_realign(lv_obj_t * obj);
|
|||||||
*/
|
*/
|
||||||
void lv_obj_set_auto_realign(lv_obj_t * obj, bool en);
|
void lv_obj_set_auto_realign(lv_obj_t * obj, bool en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves all children with horizontally or vertically.
|
||||||
|
* It doesn't take into account any limits so any values are possible
|
||||||
|
* @param obj pointer to an object whose children should be moved
|
||||||
|
* @param x pixel to move horizontally
|
||||||
|
* @param y pixels to move vertically
|
||||||
|
*/
|
||||||
|
void lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves all children with horizontally or vertically.
|
||||||
|
* Limits the scroll to the bounding box of the children.
|
||||||
|
* @param obj pointer to an object whose children should be moved
|
||||||
|
* @param x pixel to move horizontally
|
||||||
|
* @param y pixels to move vertically
|
||||||
|
*/
|
||||||
|
void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the a given x coordinate to the left side of obj.
|
||||||
|
* @param obj pointer to an object which should be scrolled
|
||||||
|
* @param x the x coordinate to scroll to
|
||||||
|
* @param y the y coordinate to scroll to
|
||||||
|
*/
|
||||||
|
void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the a given x coordinate to the left side of obj.
|
||||||
|
* @param obj pointer to an object which should be scrolled
|
||||||
|
* @param x the x coordinate to scroll to
|
||||||
|
*/
|
||||||
|
void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the a given y coordinate to the top side of obj.
|
||||||
|
* @param obj pointer to an object which should be scrolled
|
||||||
|
* @param y the y coordinate to scroll to
|
||||||
|
*/
|
||||||
|
void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the height of the area above the parent.
|
||||||
|
* That is the number of pixels the object can be scrolled down.
|
||||||
|
* Normally positive but can be negative when scrolled inside.
|
||||||
|
* @param obj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the height of the area below the parent.
|
||||||
|
* That is the number of pixels the object can be scrolled up.
|
||||||
|
* Normally positive but can be negative when scrolled inside.
|
||||||
|
* @param obj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the size of an extended clickable area
|
* Set the size of an extended clickable area
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
|
@ -139,6 +139,7 @@ typedef struct _lv_indev_proc_t {
|
|||||||
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
struct _lv_obj_t * act_obj; /*The object being pressed*/
|
||||||
struct _lv_obj_t * last_obj; /*The last object which was pressed (used by drag_throw and
|
struct _lv_obj_t * last_obj; /*The last object which was pressed (used by drag_throw and
|
||||||
other post-release event)*/
|
other post-release event)*/
|
||||||
|
struct _lv_obj_t * drag_obj; /*The object being pressed*/
|
||||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||||
|
|
||||||
lv_gesture_dir_t gesture_dir;
|
lv_gesture_dir_t gesture_dir;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user