improve scroll_view(fix issue #515)

This commit is contained in:
lixianjing 2021-01-26 18:09:29 +08:00
parent 2ff1fe3b8e
commit 3c6f397b78
4 changed files with 73 additions and 5 deletions

View File

@ -1,6 +1,6 @@
<window anim_hint="htranslate">
<list_view_h x="center" y="10" w="90%" h="90%" item_width="200" spacing="5">
<scroll_view name="view" w="100%" h="-20" children_layout="list_view(item_height=120,cols=3,spacing=2,hl=true)" snap_to_page="true" >
<scroll_view name="test" w="100%" h="-20" children_layout="list_view(item_height=120,cols=3,spacing=2,hl=true)" snap_to_page="true" move_to_page="true" >
<image style="border" draw_type="auto" image="1" text="1"/>
<image style="border" draw_type="auto" image="2" text="2"/>
<image style="border" draw_type="auto" image="3" text="3"/>

View File

@ -33,6 +33,7 @@
#define SCROLL_VIEW_DEFAULT_YSPEED_SCALE 2.0f
static uint32_t scroll_view_get_curr_page(widget_t* widget);
static uint32_t scroll_view_get_page_max_number(widget_t* widget);
static ret_t scroll_view_get_item_rect(widget_t* parent, widget_t* widget, rect_t* item_rect) {
rect_t r;
@ -97,6 +98,20 @@ static ret_t scroll_view_on_layout_children(widget_t* widget) {
tk_min(scroll_view->xoffset, (scroll_view->virtual_w - widget->w)),
tk_min(scroll_view->yoffset, (scroll_view->virtual_h - widget->h)));
}
if (scroll_view->snap_to_page) {
int32_t curr_page = scroll_view_get_curr_page(widget);
uint32_t max_page = scroll_view_get_page_max_number(widget);
scroll_view->xoffset_end = scroll_view->xoffset;
scroll_view->yoffset_end = scroll_view->yoffset;
scroll_view->fix_end_offset(widget);
scroll_view->xoffset = scroll_view->xoffset_end;
scroll_view->yoffset = scroll_view->yoffset_end;
if (scroll_view->curr_page != curr_page || scroll_view->max_page != max_page) {
scroll_view->max_page = max_page;
scroll_view->curr_page = curr_page;
widget_dispatch_simple_event(widget, EVT_PAGE_CHANGED);
}
}
return RET_OK;
}
@ -123,7 +138,7 @@ static ret_t scroll_view_on_scroll_done(void* ctx, event_t* e) {
return_value_if_fail(widget != NULL && scroll_view != NULL, RET_BAD_PARAMS);
scroll_view->wa = NULL;
scroll_view_get_curr_page(widget);
scroll_view->curr_page = scroll_view_get_curr_page(widget);
widget_invalidate_force(widget, NULL);
widget_dispatch_simple_event(widget, EVT_SCROLL_END);
widget_dispatch_simple_event(widget, EVT_PAGE_CHANGED);
@ -170,6 +185,13 @@ static int32_t scroll_view_get_snap_to_page_offset_value(widget_t* widget, int32
}
if (tmp != 0) {
int32_t n = (int32_t)((offset_end + tmp * 0.5f) / tmp);
if (scroll_view->move_to_page) {
if (scroll_view->curr_page - n > 1) {
n = scroll_view->curr_page - 1;
} else if (n - scroll_view->curr_page > 1) {
n = scroll_view->curr_page + 1;
}
}
offset_end = n * tmp;
}
return offset_end;
@ -505,11 +527,11 @@ static uint32_t scroll_view_get_curr_page(widget_t* widget) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
return_value_if_fail(widget != NULL && scroll_view != NULL, 0);
if (scroll_view->xslidable && !scroll_view->yslidable) {
scroll_view->curr_page = scroll_view->xoffset / widget->w;
return scroll_view->xoffset / widget->w;
} else if (!scroll_view->xslidable && scroll_view->yslidable) {
scroll_view->curr_page = scroll_view->yoffset / widget->h;
return scroll_view->yoffset / widget->h;
}
return scroll_view->curr_page;
return 0;
}
static ret_t scroll_view_set_curr_page(widget_t* widget, int32_t new_page) {
@ -556,6 +578,12 @@ static ret_t scroll_view_get_prop(widget_t* widget, const char* name, value_t* v
} else if (tk_str_eq(name, SCROLL_VIEW_Y_SPEED_SCALE)) {
value_set_float(v, scroll_view->yspeed_scale);
return RET_OK;
} else if (tk_str_eq(name, SCROLL_VIEW_RECURSIVE)) {
value_set_bool(v, scroll_view->recursive);
return RET_OK;
} else if (tk_str_eq(name, SCROLL_VIEW_MOVE_TO_PAGE)) {
value_set_bool(v, scroll_view->move_to_page);
return RET_OK;
} else if (tk_str_eq(name, SCROLL_VIEW_SNAP_TO_PAGE)) {
value_set_bool(v, scroll_view->snap_to_page);
return RET_OK;
@ -607,6 +635,8 @@ static ret_t scroll_view_set_prop(widget_t* widget, const char* name, const valu
return RET_OK;
} else if (tk_str_eq(name, SCROLL_VIEW_RECURSIVE)) {
return scroll_view_set_recursive(widget, value_bool(v));
} else if (tk_str_eq(name, SCROLL_VIEW_MOVE_TO_PAGE)) {
return scroll_view_set_move_to_page(widget, value_bool(v));
} else if (tk_str_eq(name, SCROLL_VIEW_SNAP_TO_PAGE)) {
return scroll_view_set_snap_to_page(widget, value_bool(v));
} else if (scroll_view->snap_to_page && tk_str_eq(name, WIDGET_PROP_CURR_PAGE)) {
@ -621,6 +651,7 @@ static const char* s_scroll_view_clone_properties[] = {
WIDGET_PROP_XSLIDABLE, WIDGET_PROP_YSLIDABLE,
WIDGET_PROP_XOFFSET, WIDGET_PROP_YOFFSET,
SCROLL_VIEW_X_SPEED_SCALE, SCROLL_VIEW_Y_SPEED_SCALE,
SCROLL_VIEW_RECURSIVE, SCROLL_VIEW_MOVE_TO_PAGE,
SCROLL_VIEW_SNAP_TO_PAGE, NULL};
TK_DECL_VTABLE(scroll_view) = {.size = sizeof(scroll_view_t),
.type = WIDGET_TYPE_SCROLL_VIEW,
@ -712,6 +743,14 @@ ret_t scroll_view_set_yslidable(widget_t* widget, bool_t yslidable) {
return RET_OK;
}
ret_t scroll_view_set_move_to_page(widget_t* widget, bool_t move_to_page) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
return_value_if_fail(scroll_view != NULL, RET_FAIL);
scroll_view->move_to_page = move_to_page;
return RET_OK;
}
ret_t scroll_view_set_snap_to_page(widget_t* widget, bool_t snap_to_page) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
return_value_if_fail(scroll_view != NULL, RET_FAIL);

View File

@ -128,6 +128,12 @@ typedef struct _scroll_view_t {
* offset是否按页面对齐
*/
bool_t snap_to_page;
/**
* @property {bool_t} snap_to_page
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* snap_to_page ture
*/
bool_t move_to_page;
/**
* @property {bool_t} recursive
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
@ -145,6 +151,7 @@ typedef struct _scroll_view_t {
int32_t yoffset_save;
int32_t curr_page;
uint32_t max_page;
velocity_t velocity;
widget_animator_t* wa;
@ -252,6 +259,18 @@ ret_t scroll_view_set_yslidable(widget_t* widget, bool_t yslidable);
*/
ret_t scroll_view_set_snap_to_page(widget_t* widget, bool_t snap_to_page);
/**
* @method scroll_view_set_move_to_page
*
* snap_to_page ture
* @annotation ["scriptable"]
* @param {widget_t*} widget
* @param {bool_t} move_to_page
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_view_set_move_to_page(widget_t* widget, bool_t move_to_page);
/**
* @method scroll_view_set_recursive
*
@ -330,6 +349,7 @@ ret_t scroll_view_scroll_delta_to(widget_t* widget, int32_t xoffset_delta, int32
#define SCROLL_VIEW_RECURSIVE "recursive"
#define SCROLL_VIEW_SNAP_TO_PAGE "snap_to_page"
#define SCROLL_VIEW_MOVE_TO_PAGE "move_to_page"
#define SCROLL_VIEW_X_SPEED_SCALE "xspeed_scale"
#define SCROLL_VIEW_Y_SPEED_SCALE "yspeed_scale"

View File

@ -494,6 +494,15 @@ static ret_t slide_indicator_target_on_value_changed(void* ctx, event_t* e) {
slide_indicator_set_value(indicator, value_int(&v));
}
if (widget_get_prop(widget, WIDGET_PROP_PAGE_MAX_NUMBER, &v) != RET_OK) {
uint32_t max = value_int(&v);
if (slide_indicator->max != max) {
slide_indicator->max = max;
}
}
widget_invalidate(widget, NULL);
return RET_OK;
}