mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-21 06:53:01 +08:00
implement scroll snapping
This commit is contained in:
parent
f09d871e4c
commit
9f2526a73c
@ -1175,6 +1175,116 @@ static void indev_click_focus(lv_indev_proc_t * proc)
|
||||
|
||||
}
|
||||
|
||||
|
||||
static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
||||
{
|
||||
if(obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) return 0;
|
||||
|
||||
lv_coord_t dist = LV_COORD_MAX;
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child_back(obj, NULL);
|
||||
while(child) {
|
||||
lv_coord_t x_child = 0;
|
||||
lv_coord_t x_parent = 0;
|
||||
switch(obj->snap_align_x) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
x_child = child->coords.x1;
|
||||
x_parent = obj->coords.x1;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
x_child = child->coords.x2;
|
||||
x_parent = obj->coords.x2;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER:
|
||||
x_child = child->coords.x1 + lv_area_get_width(&child->coords) / 2;
|
||||
x_parent = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2;
|
||||
}
|
||||
|
||||
x_child += ofs;
|
||||
if(x_child >= min && x_child <= max) {
|
||||
lv_coord_t x = x_child - x_parent;
|
||||
if(LV_MATH_ABS(x) < LV_MATH_ABS(dist)) dist = x;
|
||||
}
|
||||
|
||||
child = lv_obj_get_child_back(obj, child);
|
||||
}
|
||||
|
||||
return dist == LV_COORD_MAX ? 0: -dist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for snap point in the `min` - `max` range.
|
||||
* @param obj the object on which snap point should be found
|
||||
* @param min ignore snap points smaller then this. (Absolute coordinate)
|
||||
* @param max ignore snap points greater then this. (Absolute coordinate)
|
||||
* @param ofs offset to snap points. Useful the get a snap point in an imagined case
|
||||
* what if children are already moved by this value
|
||||
* @return the distance of the snap point.
|
||||
*/
|
||||
static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs)
|
||||
{
|
||||
if(obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) return 0;
|
||||
|
||||
lv_coord_t dist = LV_COORD_MAX;
|
||||
|
||||
uint32_t cc = 0;
|
||||
lv_obj_t * child = lv_obj_get_child_back(obj, NULL);
|
||||
while(child) {
|
||||
cc++;
|
||||
lv_coord_t y_child = 0;
|
||||
lv_coord_t y_parent = 0;
|
||||
switch(obj->snap_align_y) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
y_child = child->coords.y1;
|
||||
y_parent = obj->coords.y1;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
y_child = child->coords.y2;
|
||||
y_parent = obj->coords.y2;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER:
|
||||
y_child = child->coords.y1 + lv_area_get_height(&child->coords) / 2;
|
||||
y_parent = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2;
|
||||
}
|
||||
|
||||
y_child += ofs;
|
||||
if(y_child >= min && y_child <= max) {
|
||||
lv_coord_t y = y_child - y_parent;
|
||||
if(LV_MATH_ABS(y) < LV_MATH_ABS(dist)) dist = y;
|
||||
}
|
||||
|
||||
child = lv_obj_get_child_back(obj, child);
|
||||
}
|
||||
|
||||
printf("child cnt: %d\n", cc);
|
||||
|
||||
return dist == LV_COORD_MAX ? 0 : -dist;
|
||||
}
|
||||
|
||||
static void scroll_limit(lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y)
|
||||
{
|
||||
if(diff_y) {
|
||||
if(proc->types.pointer.scroll_sum.y + *diff_y < proc->types.pointer.scroll_area.y1) {
|
||||
*diff_y = proc->types.pointer.scroll_area.y1 - proc->types.pointer.scroll_sum.y;
|
||||
}
|
||||
|
||||
if(proc->types.pointer.scroll_sum.y + *diff_y > proc->types.pointer.scroll_area.y2) {
|
||||
*diff_y = proc->types.pointer.scroll_area.y2 - proc->types.pointer.scroll_sum.y;
|
||||
}
|
||||
}
|
||||
|
||||
if(diff_x) {
|
||||
if(proc->types.pointer.scroll_sum.x + *diff_x < proc->types.pointer.scroll_area.x1) {
|
||||
*diff_x = proc->types.pointer.scroll_area.x1 - proc->types.pointer.scroll_sum.x;
|
||||
}
|
||||
|
||||
if(proc->types.pointer.scroll_sum.x + *diff_x > proc->types.pointer.scroll_area.x2) {
|
||||
*diff_x = proc->types.pointer.scroll_area.x2 - proc->types.pointer.scroll_sum.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle the scrolling
|
||||
* @param indev pointer to a input device state
|
||||
@ -1242,16 +1352,12 @@ static void indev_scroll_handler(lv_indev_proc_t * proc)
|
||||
(down_en && proc->types.pointer.scroll_sum.y <= - indev_act->driver.scroll_limit))
|
||||
{
|
||||
proc->types.pointer.scroll_dir = hor_en ? LV_SCROLL_DIR_HOR : LV_SCROLL_DIR_VER;
|
||||
|
||||
if(!hor_en) proc->types.pointer.scroll_sum.x = 0;
|
||||
if(!ver_en) proc->types.pointer.scroll_sum.y = 0;
|
||||
|
||||
break; /*It"s good scrollable object, use it*/
|
||||
break; /*It's good scrollable object, use it*/
|
||||
}
|
||||
proc->types.pointer.scroll_obj = lv_obj_get_parent(proc->types.pointer.scroll_obj);
|
||||
}
|
||||
}
|
||||
|
||||
/*Use the last candidate*/
|
||||
if(proc->types.pointer.scroll_obj == NULL) {
|
||||
if(scroll_candidate_obj) {
|
||||
proc->types.pointer.scroll_dir = dirs_candidate;
|
||||
@ -1261,6 +1367,61 @@ static void indev_scroll_handler(lv_indev_proc_t * proc)
|
||||
}
|
||||
}
|
||||
|
||||
proc->types.pointer.scroll_sum.x = 0;
|
||||
proc->types.pointer.scroll_sum.y = 0;
|
||||
|
||||
lv_obj_t * obj = proc->types.pointer.scroll_obj;
|
||||
/*If there no STOP allow scrolling anywhere*/
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_STOP) == false) {
|
||||
lv_area_set(&proc->types.pointer.scroll_area, LV_COORD_MIN, LV_COORD_MIN, LV_COORD_MAX, LV_COORD_MAX);
|
||||
}
|
||||
/*With STOP limit the scrolling to the perv and next snap point*/
|
||||
else {
|
||||
switch(obj->snap_align_y) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y1 + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y1 - 1, 0);
|
||||
printf("%d, %d\n", proc->types.pointer.scroll_area.y1, proc->types.pointer.scroll_area.y2);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y2, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y2, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER: {
|
||||
lv_coord_t y_mid = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2;
|
||||
proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, y_mid + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, y_mid - 1, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
proc->types.pointer.scroll_area.y1 = LV_COORD_MIN;
|
||||
proc->types.pointer.scroll_area.y2 = LV_COORD_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(obj->snap_align_x) {
|
||||
case LV_SCROLL_SNAP_ALIGN_START:
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x1, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_END:
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x2, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x2, 0);
|
||||
break;
|
||||
case LV_SCROLL_SNAP_ALIGN_CENTER: {
|
||||
lv_coord_t x_mid = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2;
|
||||
proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, x_mid + 1, LV_COORD_MAX, 0);
|
||||
proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, x_mid - 1, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
proc->types.pointer.scroll_area.x1 = LV_COORD_MIN;
|
||||
proc->types.pointer.scroll_area.x2 = LV_COORD_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*If there is no scroll object there is nothing to do*/
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
if(scroll_obj == NULL) return;
|
||||
@ -1279,10 +1440,39 @@ static void indev_scroll_handler(lv_indev_proc_t * proc)
|
||||
if(lv_obj_get_scroll_top(scroll_obj) < 0) diff_y = diff_y / 2;
|
||||
if(lv_obj_get_scroll_bottom(scroll_obj) < 0) diff_y = diff_y / 2;
|
||||
}
|
||||
|
||||
/*Respect the scroll limit area*/
|
||||
scroll_limit(proc, &diff_x, &diff_y);
|
||||
|
||||
lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y);
|
||||
proc->types.pointer.scroll_sum.x += diff_x;
|
||||
proc->types.pointer.scroll_sum.y += diff_y;
|
||||
}
|
||||
}
|
||||
|
||||
static lv_coord_t scroll_throw_predict_y(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_coord_t y = proc->types.pointer.scroll_throw_vect.y;
|
||||
lv_coord_t move = 0;
|
||||
while(y) {
|
||||
move += y;
|
||||
y = y * (100 - indev_act->driver.scroll_throw) / 100;
|
||||
}
|
||||
return move;
|
||||
}
|
||||
|
||||
|
||||
static lv_coord_t scroll_throw_predict_x(lv_indev_proc_t * proc)
|
||||
{
|
||||
lv_coord_t x = proc->types.pointer.scroll_throw_vect.x;
|
||||
lv_coord_t move = 0;
|
||||
while(x) {
|
||||
move += x;
|
||||
x = x * (100 - indev_act->driver.scroll_throw) / 100;
|
||||
}
|
||||
return move;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle throwing by after scrolling
|
||||
* @param indev pointer to an input device state
|
||||
@ -1292,41 +1482,94 @@ static void indev_scroll_throw_handler(lv_indev_proc_t * proc)
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
|
||||
if(scroll_obj == NULL) return;
|
||||
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) return;
|
||||
|
||||
/*Reduce the vectors*/
|
||||
proc->types.pointer.scroll_throw_vect.x =
|
||||
proc->types.pointer.scroll_throw_vect.x * (100 - indev_act->driver.scroll_throw) / 100;
|
||||
if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) {
|
||||
return;
|
||||
}
|
||||
else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_VER) {
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
/*If no snapping "throw"*/
|
||||
if(scroll_obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
proc->types.pointer.scroll_throw_vect.y =
|
||||
proc->types.pointer.scroll_throw_vect.y * (100 - indev_act->driver.scroll_throw) / 100;
|
||||
|
||||
switch(proc->types.pointer.scroll_dir) {
|
||||
case LV_SCROLL_DIR_HOR:
|
||||
{
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
/*If scrolled inside reduce faster*/
|
||||
if(sl < 0 || sr < 0) proc->types.pointer.scroll_throw_vect.x = proc->types.pointer.scroll_throw_vect.x >> 1;
|
||||
break;
|
||||
}
|
||||
case LV_SCROLL_DIR_VER:
|
||||
{
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
|
||||
/*If scrolled inside reduce faster*/
|
||||
if(st < 0 || sb < 0) proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y >> 1;
|
||||
break;
|
||||
if(st < 0 || sb < 0) {
|
||||
proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y >> 1;
|
||||
}
|
||||
|
||||
lv_obj_scroll_by_raw(scroll_obj, 0, proc->types.pointer.scroll_throw_vect.y);
|
||||
}
|
||||
/*With snapping find the nearest snap point and scroll there*/
|
||||
else {
|
||||
lv_coord_t diff_y = scroll_throw_predict_y(proc);
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
scroll_limit(proc, NULL, &diff_y);
|
||||
lv_coord_t y = find_snap_point_y(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_y);
|
||||
lv_obj_scroll_by(scroll_obj, 0, diff_y + y, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) {
|
||||
proc->types.pointer.scroll_throw_vect.y = 0;
|
||||
/*If no snapping "throw"*/
|
||||
if(scroll_obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
proc->types.pointer.scroll_throw_vect.x =
|
||||
proc->types.pointer.scroll_throw_vect.x * (100 - indev_act->driver.scroll_throw) / 100;
|
||||
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
|
||||
/*If scrolled inside reduce faster*/
|
||||
if(sl < 0 || sr < 0) {
|
||||
proc->types.pointer.scroll_throw_vect.x = proc->types.pointer.scroll_throw_vect.x >> 1;
|
||||
}
|
||||
|
||||
lv_obj_scroll_by_raw(scroll_obj, proc->types.pointer.scroll_throw_vect.x, 0);
|
||||
}
|
||||
/*With snapping find the nearest snap point and scroll there*/
|
||||
else {
|
||||
lv_coord_t diff_x = scroll_throw_predict_x(proc);
|
||||
proc->types.pointer.scroll_throw_vect.x = 0;
|
||||
scroll_limit(proc, NULL, &diff_x);
|
||||
lv_coord_t x = find_snap_point_x(scroll_obj, LV_COORD_MIN, LV_COORD_MAX, diff_x);
|
||||
lv_obj_scroll_by(scroll_obj, x + diff_x, 0, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
if((proc->types.pointer.scroll_throw_vect.x != 0 || proc->types.pointer.scroll_throw_vect.y != 0)) {
|
||||
lv_obj_scroll_by_raw(scroll_obj, proc->types.pointer.scroll_throw_vect.x, proc->types.pointer.scroll_throw_vect.y);
|
||||
|
||||
/*Check if the scroll has finished */
|
||||
if(proc->types.pointer.scroll_throw_vect.x == 0 && proc->types.pointer.scroll_throw_vect.y == 0) {
|
||||
/*Revert if scrolled in*/
|
||||
/*If vertically scrollable and not controlled by snap*/
|
||||
if(scroll_obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
if(st > 0 || sb > 0) {
|
||||
if(st < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, 0, st, LV_ANIM_ON);
|
||||
}
|
||||
/*If the vectors become 0 then finish scrolling
|
||||
signal*/
|
||||
else {
|
||||
else if(sb < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, 0, -sb, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*If horizontally scrollable and not controlled by snap*/
|
||||
if(scroll_obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) {
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
if (sl > 0 || sr > 0) {
|
||||
if(sl < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, sl, 0, LV_ANIM_ON);
|
||||
}
|
||||
else if(sr < 0) {
|
||||
lv_obj_scroll_by(scroll_obj, -sr, 0, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE;
|
||||
proc->types.pointer.scroll_obj = NULL;
|
||||
lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_END, indev_act);
|
||||
|
@ -1241,7 +1241,8 @@ void lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
obj->scroll.y += y;
|
||||
|
||||
refresh_children_position(obj, x, y);
|
||||
lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL);
|
||||
lv_res_t res = lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
/**
|
||||
@ -1331,7 +1332,7 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en)
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj)
|
||||
{
|
||||
return -obj->scroll.y;
|
||||
}
|
||||
@ -1343,7 +1344,7 @@ lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
@ -1367,7 +1368,7 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj)
|
||||
{
|
||||
return -obj->scroll.x;
|
||||
}
|
||||
@ -1379,7 +1380,7 @@ lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj)
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
@ -4006,33 +4007,10 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_SCROLL) {
|
||||
|
||||
res = lv_event_send(obj, LV_EVENT_SCROLLED, NULL);
|
||||
if(res != LV_RES_OK) return res;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_SCROLL_END) {
|
||||
|
||||
lv_coord_t st = lv_obj_get_scroll_top(obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
||||
|
||||
/*Revert if scrolled in*/
|
||||
if(st > 0 || sb > 0) { /*Is vertically scrollable*/
|
||||
if(st < 0) {
|
||||
lv_obj_scroll_by(obj, 0, st, LV_ANIM_ON);
|
||||
}
|
||||
else if(sb < 0) {
|
||||
lv_obj_scroll_by(obj, 0, -sb, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
if(sl > 0 || sr > 0) { /*Is horizontally scrollable*/
|
||||
if(sl < 0) {
|
||||
lv_obj_scroll_by(obj, sl, 0, LV_ANIM_ON);
|
||||
}
|
||||
else if(sr < 0) {
|
||||
lv_obj_scroll_by(obj, -sr, 0, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
if(lv_obj_get_scroll_mode(obj) == LV_SCROLL_MODE_ACTIVE) {
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
@ -4045,11 +4023,13 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
if(lv_obj_is_grid_item(obj)) lv_grid_full_refr(obj);
|
||||
|
||||
// lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
// while(child) {
|
||||
// lv_obj_set_pos(child, child->x_set, child->y_set);
|
||||
// child = lv_obj_get_child(obj, child);
|
||||
// }
|
||||
lv_obj_t * child = lv_obj_get_child(obj, NULL);
|
||||
while(child) {
|
||||
if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) {
|
||||
lv_obj_set_pos(child, child->x_set, child->y_set);
|
||||
}
|
||||
child = lv_obj_get_child(obj, child);
|
||||
}
|
||||
|
||||
|
||||
if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) {
|
||||
|
@ -95,7 +95,7 @@ enum {
|
||||
LV_EVENT_SCROLL_BEGIN,
|
||||
LV_EVENT_SCROLL_THROW_BEGIN,
|
||||
LV_EVENT_SCROLL_END,
|
||||
LV_EVENT_SCROLL,
|
||||
LV_EVENT_SCROLLED,
|
||||
LV_EVENT_GESTURE, /**< The object has been gesture*/
|
||||
LV_EVENT_KEY,
|
||||
LV_EVENT_FOCUSED,
|
||||
@ -172,14 +172,7 @@ enum {
|
||||
typedef uint8_t lv_state_t;
|
||||
|
||||
enum {
|
||||
LV_SCROLL_SNAP_OFF,
|
||||
LV_SCROLL_SNAP_NORMAL,
|
||||
LV_SCROLL_SNAP_ALWAYS,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_scroll_snap_t;
|
||||
|
||||
enum {
|
||||
LV_SCROLL_SNAP_ALIGN_NONE,
|
||||
LV_SCROLL_SNAP_ALIGN_START,
|
||||
LV_SCROLL_SNAP_ALIGN_END,
|
||||
LV_SCROLL_SNAP_ALIGN_CENTER
|
||||
@ -188,15 +181,16 @@ typedef uint8_t lv_scroll_snap_align_t;
|
||||
|
||||
|
||||
enum {
|
||||
LV_OBJ_FLAG_HIDDEN,
|
||||
LV_OBJ_FLAG_CLICKABLE,
|
||||
LV_OBJ_FLAG_SCROLLABLE,
|
||||
LV_OBJ_FLAG_SCROLL_ELASTIC,
|
||||
LV_OBJ_FLAG_SCROLL_MOMENTUM,
|
||||
LV_OBJ_FLAG_PRESS_LOCK,
|
||||
LV_OBJ_FLAG_EVENT_BUBBLE,
|
||||
LV_OBJ_FLAG_GESTURE_BUBBLE,
|
||||
LV_OBJ_FLAG_FOCUS_BUBBLE,
|
||||
LV_OBJ_FLAG_HIDDEN = (1 << 0),
|
||||
LV_OBJ_FLAG_CLICKABLE = (1 << 1),
|
||||
LV_OBJ_FLAG_SCROLLABLE = (1 << 2),
|
||||
LV_OBJ_FLAG_SCROLL_ELASTIC = (1 << 3),
|
||||
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1 << 4),
|
||||
LV_OBJ_FLAG_SCROLL_STOP = (1 << 5),
|
||||
LV_OBJ_FLAG_PRESS_LOCK = (1 << 6),
|
||||
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 7),
|
||||
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 8),
|
||||
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 9),
|
||||
};
|
||||
typedef uint16_t lv_obj_flag_t;
|
||||
|
||||
@ -235,12 +229,11 @@ typedef struct _lv_obj_t {
|
||||
/*Attributes and states*/
|
||||
lv_obj_flag_t flags : 9;
|
||||
lv_scroll_mode_t scroll_mode :2; /**< How to display scrollbars*/
|
||||
lv_scroll_snap_t snap_x : 2;
|
||||
lv_scroll_snap_t snap_y : 2;
|
||||
lv_scroll_snap_align_t snap_align_x : 2;
|
||||
lv_scroll_snap_align_t snap_align_y : 2;
|
||||
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
|
||||
uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */
|
||||
|
||||
lv_state_t state;
|
||||
|
||||
lv_coord_t x_set;
|
||||
@ -548,7 +541,7 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the height of the area below the parent.
|
||||
@ -557,7 +550,7 @@ lv_coord_t lv_obj_get_scroll_top(lv_obj_t * obj);
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
@ -567,7 +560,7 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj);
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the width of the area below the object.
|
||||
@ -576,7 +569,7 @@ lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj);
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the size of an extended clickable area
|
||||
|
@ -139,6 +139,7 @@ typedef struct _lv_indev_proc_t {
|
||||
other post-release event)*/
|
||||
struct _lv_obj_t * scroll_obj; /*The object being scrolled*/
|
||||
struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
|
||||
lv_area_t scroll_area;
|
||||
|
||||
lv_gesture_dir_t gesture_dir;
|
||||
lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user