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) {
|
||||
indev->proc.types.pointer.act_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_in_prog = 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)
|
||||
{
|
||||
|
||||
bool scrollable = true;
|
||||
|
||||
/*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);
|
||||
bool just_started = false;
|
||||
|
||||
/*Get the coordinates of the object and modify them*/
|
||||
lv_coord_t act_x = lv_obj_get_x(target_obj);
|
||||
lv_coord_t act_y = lv_obj_get_y(target_obj);
|
||||
lv_coord_t act_x = 0;
|
||||
lv_coord_t act_y = 0;
|
||||
|
||||
/*Count the movement by drag*/
|
||||
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;
|
||||
|
||||
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?*/
|
||||
bool hor_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((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;
|
||||
just_started = true;
|
||||
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(!ver_en) proc->types.pointer.drag_sum.y = 0;
|
||||
|
||||
act_x += proc->types.pointer.drag_sum.x;
|
||||
act_y += proc->types.pointer.drag_sum.y;
|
||||
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;
|
||||
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(proc->types.pointer.drag_limit_out != 0) {
|
||||
/*Set new position or scroll if the vector is not zero*/
|
||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
||||
|
||||
lv_coord_t prev_x = target_obj->coords.x1;
|
||||
lv_coord_t prev_y = target_obj->coords.y1;
|
||||
lv_coord_t prev_x = obj->coords.x1;
|
||||
lv_coord_t prev_y = obj->coords.y1;
|
||||
|
||||
/*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;
|
||||
@ -1327,18 +1387,18 @@ static void indev_drag(lv_indev_proc_t * proc)
|
||||
|
||||
if(scrollable) {
|
||||
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;
|
||||
if(target_obj->scroll.y > 0 && diff_y > 0) {
|
||||
if(obj->scroll.y > 0 && diff_y > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
lv_obj_scroll_by(target_obj, 0, diff_y, LV_ANIM_OFF);
|
||||
lv_obj_scroll_by(obj, 0, diff_y, LV_ANIM_OFF);
|
||||
} 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;
|
||||
@ -1397,9 +1457,9 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
|
||||
|
||||
/*Reduce the vectors*/
|
||||
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 * (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) {
|
||||
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, proc->types.pointer.drag_throw_vect.x, proc->types.pointer.drag_throw_vect.y);
|
||||
lv_obj_scroll_by(target_obj, proc->types.pointer.drag_throw_vect.x, proc->types.pointer.drag_throw_vect.y, LV_ANIM_OFF);
|
||||
} else {
|
||||
lv_area_t 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*/
|
||||
else {
|
||||
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);
|
||||
if(indev_reset_check(proc)) return;
|
||||
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)
|
||||
{
|
||||
|
||||
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;
|
||||
lv_obj_t * drag_obj = obj;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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 * last_obj; /*The last object which was pressed (used by drag_throw and
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * drag_obj; /*The object being pressed*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
|
||||
lv_gesture_dir_t gesture_dir;
|
||||
|
Loading…
x
Reference in New Issue
Block a user