add listview and refactor

This commit is contained in:
xianjimli 2018-07-04 17:27:32 +08:00
parent 7de34fc265
commit 9bda28b0e4
16 changed files with 605 additions and 190 deletions

View File

@ -0,0 +1,23 @@
<window name="main" anim_hint="htranslate">
<list_view x="0" y="0" w="100%" h="-40" item_height="60">
<scroll_view x="0" y="0" w="100%" h="100%">
<button text="0" />
<button text="1" />
<button text="2" />
<button text="3" />
<button text="4" />
<button text="5" />
<button text="6" />
<button text="7" />
<button text="8" />
<button text="9" />
<button text="10" />
<button text="11" />
<button text="12" />
<button text="13" />
<button text="14" />
</scroll_view>
<scroll_bar_d x="right" y="0" w="12" h="100%" value="0"/>
</list_view>
<button name="close" x="center" y="bottom:10" w="50%" h="30" text="close"/>
</window>

3
demos/res/raw/ui/s.xml Normal file
View File

@ -0,0 +1,3 @@
<window anim_hint="htranslate" layout="h30 c1 m:2 s:2">
<spin_box x="0" y="0" h="30" w="70%" tips="uint(0-150) auto_fix" input_type="uint" min="0" max="150" step="1" auto_fix="true" />
</window>

View File

@ -591,7 +591,7 @@ ret_t edit_get_prop(widget_t* widget, const char* name, value_t* v) {
} else if (tk_str_eq(name, WIDGET_PROP_BOTTOM_MARGIN)) {
value_set_int(v, edit->bottom_margin);
return RET_OK;
} else if (tk_str_eq(name, WIDGET_PROP_TIPS) == 0) {
} else if (tk_str_eq(name, WIDGET_PROP_TIPS)) {
value_set_wstr(v, edit->tips.str);
return RET_OK;
}

View File

@ -55,6 +55,7 @@ static const key_type_value_t widget_type_value[] = {
{WIDGET_TYPE_VIEW, 0, WIDGET_VIEW},
{WIDGET_TYPE_SCROLL_BAR, 0, WIDGET_SCROLL_BAR},
{WIDGET_TYPE_SCROLL_VIEW, 0, WIDGET_SCROLL_VIEW},
{WIDGET_TYPE_LIST_VIEW, 0, WIDGET_LIST_VIEW},
{WIDGET_TYPE_DIALOG_CLIENT, 0, WIDGET_DIALOG_CLIENT}};
static const key_type_value_t style_id_name_value[] = {

View File

@ -293,10 +293,6 @@ ret_t widget_layout_children_default(widget_t* widget) {
layout_h = widget->h;
}
if (widget->vt->on_layout_children != NULL) {
return widget->vt->on_layout_children(widget);
}
n = widget->children->size;
children = (widget_t**)(widget->children->elms);

153
src/base/list_view.c Normal file
View File

@ -0,0 +1,153 @@
/**
* File: list_view.h
* Author: AWTK Develop Team
* Brief: list_view
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-07-04 Li XianJing <xianjimli@hotmail.com> created
*
*/
#include "base/mem.h"
#include "base/utils.h"
#include "base/layout.h"
#include "base/list_view.h"
#include "base/scroll_bar.h"
#include "base/scroll_view.h"
static ret_t list_view_on_add_child(widget_t* widget, widget_t* child);
static ret_t list_view_on_paint_self(widget_t* widget, canvas_t* c) {
return widget_paint_helper(widget, c, NULL, NULL);
}
static ret_t list_view_get_prop(widget_t* widget, const char* name, value_t* v) {
list_view_t* list_view = LIST_VIEW(widget);
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
if (tk_str_eq(name, WIDGET_PROP_ITEM_HEIGHT)) {
value_set_uint8(v, list_view->item_height);
return RET_OK;
}
return RET_NOT_FOUND;
}
static ret_t list_view_set_prop(widget_t* widget, const char* name, const value_t* v) {
list_view_t* list_view = LIST_VIEW(widget);
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
if (tk_str_eq(name, WIDGET_PROP_ITEM_HEIGHT)) {
list_view->item_height = value_int(v);
return RET_OK;
}
return RET_NOT_FOUND;
}
static const widget_vtable_t s_list_view_vtable = {.type_name = WIDGET_TYPE_LIST_VIEW,
.set_prop = list_view_set_prop,
.get_prop = list_view_get_prop,
.on_add_child = list_view_on_add_child,
.on_paint_self = list_view_on_paint_self};
static ret_t list_view_on_layout_children(widget_t* widget) {
list_view_t* list_view = LIST_VIEW(widget->parent);
int32_t virtual_h = widget->h;
int32_t item_height = list_view->item_height;
if (widget->children != NULL) {
int32_t i = 0;
int32_t n = 0;
int32_t x = 0;
int32_t y = 0;
int32_t w = widget->w;
int32_t h = item_height;
for (i = 0, n = widget->children->size; i < n; i++) {
widget_t* iter = (widget_t*)(widget->children->elms[i]);
if (item_height <= 0) {
h = iter->h;
}
widget_move_resize(iter, x, y, w, h);
widget_layout(iter);
y = iter->y + iter->h;
if (y > virtual_h) {
virtual_h = y;
}
}
}
scroll_view_set_virtual_h(list_view->scroll_view, virtual_h);
scroll_bar_set_params(list_view->scroll_bar, virtual_h, list_view->item_height);
return RET_OK;
}
static ret_t list_view_on_scroll_bar_value_changed(void* ctx, event_t* e) {
widget_t* widget = WIDGET(ctx);
list_view_t* list_view = LIST_VIEW(widget);
scroll_view_t* scroll_view = SCROLL_VIEW(list_view->scroll_view);
scroll_bar_t* scroll_bar = SCROLL_BAR(list_view->scroll_bar);
int32_t value =
(scroll_view->virtual_h - list_view->scroll_view->h) * scroll_bar->value / scroll_bar->max;
scroll_view_set_offset(list_view->scroll_view, 0, value);
return RET_OK;
}
static ret_t list_view_on_add_child(widget_t* widget, widget_t* child) {
list_view_t* list_view = LIST_VIEW(widget);
if (child->type == WIDGET_SCROLL_VIEW) {
scroll_view_t* scroll_view = SCROLL_VIEW(child);
list_view->scroll_view = child;
scroll_view->on_layout_children = list_view_on_layout_children;
} else if (child->type == WIDGET_SCROLL_BAR) {
list_view->scroll_bar = child;
widget_on(list_view->scroll_bar, EVT_VALUE_CHANGED, list_view_on_scroll_bar_value_changed,
widget);
}
return RET_FAIL;
}
widget_t* list_view_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
widget_t* widget = NULL;
list_view_t* list_view = TKMEM_ZALLOC(list_view_t);
return_value_if_fail(list_view != NULL, NULL);
widget = WIDGET(list_view);
widget->vt = &s_list_view_vtable;
widget_init(widget, parent, WIDGET_LIST_VIEW);
widget_move_resize(widget, x, y, w, h);
widget_set_state(widget, WIDGET_STATE_NORMAL);
return widget;
}
ret_t list_view_set_item_height(widget_t* widget, int32_t item_height) {
list_view_t* list_view = LIST_VIEW(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
list_view->item_height = item_height;
return RET_OK;
}

77
src/base/list_view.h Normal file
View File

@ -0,0 +1,77 @@
/**
* File: list_view.h
* Author: AWTK Develop Team
* Brief: list_view
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-07-04 Li XianJing <xianjimli@hotmail.com> created
*
*/
#ifndef TK_LIST_VIEW_H
#define TK_LIST_VIEW_H
#include "base/widget.h"
BEGIN_C_DECLS
/**
* @class list_view_t
* @parent widget_t
* @scriptable
* ListView控件
*/
typedef struct _list_view_t {
widget_t widget;
/**
* @property {int32_t} item_height
* @readonly
*
*/
int32_t item_height;
/*private*/
widget_t* scroll_view;
widget_t* scroll_bar;
} list_view_t;
/**
* @method list_view_create
* @constructor
* list_view对象
* @param {widget_t*} parent
* @param {xy_t} x x坐标
* @param {xy_t} y y坐标
* @param {wh_t} w
* @param {wh_t} h
*
* @return {widget_t*}
*/
widget_t* list_view_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
/**
* @method list_view_set_item_height
*
* @param {widget_t*} widget
* @param {int32_t} item_height
*
* @return {ret_t} RET_OK表示成功
*/
ret_t list_view_set_item_height(widget_t* widget, int32_t item_height);
#define LIST_VIEW(widget) ((list_view_t*)(widget))
END_C_DECLS
#endif /*TK_LIST_VIEW_H*/

View File

@ -170,13 +170,13 @@ static ret_t progress_bar_get_prop(widget_t* widget, const char* name, value_t*
progress_bar_t* progress_bar = PROGRESS_BAR(widget);
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
if (strcmp(name, WIDGET_PROP_VALUE) == 0) {
if (tk_str_eq(name, WIDGET_PROP_VALUE)) {
value_set_uint8(v, progress_bar->value);
return RET_OK;
} else if (strcmp(name, WIDGET_PROP_VERTICAL) == 0) {
} else if (tk_str_eq(name, WIDGET_PROP_VERTICAL)) {
value_set_bool(v, progress_bar->vertical);
return RET_OK;
} else if (strcmp(name, WIDGET_PROP_SHOW_TEXT) == 0) {
} else if (tk_str_eq(name, WIDGET_PROP_SHOW_TEXT)) {
value_set_bool(v, progress_bar->show_text);
return RET_OK;
}
@ -187,11 +187,11 @@ static ret_t progress_bar_get_prop(widget_t* widget, const char* name, value_t*
static ret_t progress_bar_set_prop(widget_t* widget, const char* name, const value_t* v) {
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
if (strcmp(name, WIDGET_PROP_VALUE) == 0) {
if (tk_str_eq(name, WIDGET_PROP_VALUE)) {
return progress_bar_set_value(widget, value_int(v));
} else if (strcmp(name, WIDGET_PROP_VERTICAL) == 0) {
} else if (tk_str_eq(name, WIDGET_PROP_VERTICAL)) {
return progress_bar_set_vertical(widget, value_bool(v));
} else if (strcmp(name, WIDGET_PROP_SHOW_TEXT) == 0) {
} else if (tk_str_eq(name, WIDGET_PROP_SHOW_TEXT)) {
return progress_bar_set_show_text(widget, value_bool(v));
}

175
src/base/scroll_bar.c Executable file → Normal file
View File

@ -32,8 +32,7 @@ static bool_t scroll_bar_is_mobile(widget_t* widget);
static ret_t scroll_bar_update_dragger(widget_t* widget);
static ret_t scroll_bar_add_delta(scroll_bar_t* scroll_bar, int32_t delta);
/*destkop*/
/*mobile*/
static ret_t scroll_bar_mobile_get_dragger_size(widget_t* widget, rect_t* r) {
int32_t x = 0;
int32_t y = 0;
@ -87,45 +86,7 @@ static ret_t scroll_bar_mobile_on_paint_self(widget_t* widget, canvas_t* c) {
return RET_OK;
}
static ret_t scroll_bar_mobile_on_event(widget_t* widget, event_t* e) {
/*
uint16_t type = e->type;
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
switch (type) {
case EVT_POINTER_DOWN: {
widget_set_opacity(widget, 0xff);
widget_set_visible(widget, TRUE, FALSE);
widget_invalidate_force(widget);
break;
}
case EVT_POINTER_UP: {
pointer_event_t* pointer_event = (pointer_event_t*)(e);
if (pointer_event->y > 200) {
scroll_bar_scroll_to(widget, scroll_bar->value + 200, 1000);
} else {
scroll_bar_scroll_to(widget, scroll_bar->value - 200, 1000);
}
break;
}
default:
break;
}
*/
(void)widget;
(void)e;
return RET_OK;
}
/*destkop*/
static ret_t scroll_bar_desktop_on_paint_self(widget_t* widget, canvas_t* c) {
(void)widget;
(void)c;
return RET_OK;
}
static ret_t scroll_bar_desktop_on_click(widget_t* widget, pointer_event_t* e) {
point_t p = {e->x, e->y};
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
@ -214,39 +175,38 @@ static ret_t scroll_bar_destop_get_dragger_size(widget_t* widget, rect_t* r) {
return RET_OK;
}
static ret_t scroll_bar_add_delta(scroll_bar_t* scroll_bar, int32_t delta) {
static ret_t scroll_bar_add_delta(scroll_bar_t* scroll_bar, int32_t d) {
int32_t delta = 0;
int32_t new_value = 0;
widget_t* widget = WIDGET(scroll_bar);
int32_t new_value = scroll_bar->value + delta;
if (scroll_bar->max > 0) {
if (widget->w > widget->h) {
delta = d * (widget->w + scroll_bar->max) / scroll_bar->max;
} else {
delta = d * (widget->h + scroll_bar->max) / scroll_bar->max;
}
} else {
delta = 0;
}
new_value = scroll_bar->value + delta;
new_value = tk_max(new_value, 0);
new_value = tk_min(new_value, scroll_bar->max);
delta = tk_abs((int)(scroll_bar->value) - new_value);
if (delta > scroll_bar->row) {
if (scroll_bar->value != new_value) {
scroll_bar_scroll_to(widget, new_value, 500);
} else {
scroll_bar_set_value(widget, new_value);
scroll_bar_update_dragger(widget);
}
return RET_OK;
}
static ret_t scroll_bar_on_up_button_clicked(void* ctx, event_t* e) {
scroll_bar_t* scroll_bar = SCROLL_BAR(ctx);
scroll_bar_add_delta(scroll_bar, -scroll_bar->row);
return RET_OK;
return scroll_bar_add_delta(SCROLL_BAR(ctx), -SCROLL_BAR(ctx)->row);
}
static ret_t scroll_bar_on_down_button_clicked(void* ctx, event_t* e) {
scroll_bar_t* scroll_bar = SCROLL_BAR(ctx);
scroll_bar_add_delta(scroll_bar, scroll_bar->row);
return RET_OK;
return scroll_bar_add_delta(SCROLL_BAR(ctx), SCROLL_BAR(ctx)->row);
}
static ret_t scroll_bar_on_drag(void* ctx, event_t* e) {
@ -266,22 +226,46 @@ static ret_t scroll_bar_on_drag(void* ctx, event_t* e) {
int32_t max_y = (widget_h - 2 * widget_w - dragger->h);
value = (y - widget_w) * scroll_bar->max / max_y;
}
log_debug("value=%d\n", value);
scroll_bar_set_value(widget, value);
return RET_OK;
}
static ret_t scroll_bar_create_children(widget_t* widget) {
static ret_t scroll_bar_layout_children(widget_t* widget) {
rect_t r;
int32_t widget_w = widget->w;
int32_t widget_h = widget->h;
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
widget_t* dragger = scroll_bar->dragger;
return_value_if_fail(scroll_bar_destop_get_dragger_size(widget, &r) == RET_OK, RET_FAIL);
if (widget->w > widget->h) {
int32_t max_x = widget_h + (widget_w - 2 * widget_h - r.w);
dragger_set_range(dragger, widget_h, r.y, max_x, r.y);
} else {
int32_t max_y = widget_w + (widget_h - 2 * widget_w - r.h);
dragger_set_range(dragger, r.x, widget_w, r.x, max_y);
}
widget_move_resize(WIDGET(dragger), r.x, r.y, r.w, r.h);
widget_layout(widget);
widget_invalidate_force(widget);
return RET_OK;
}
static ret_t scroll_bar_create_children(widget_t* widget) {
char str[16];
widget_t* up = NULL;
widget_t* down = NULL;
widget_t* dragger = NULL;
int32_t widget_w = widget->w;
int32_t widget_h = widget->h;
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
return_value_if_fail(scroll_bar_destop_get_dragger_size(widget, &r) == RET_OK, RET_FAIL);
if (scroll_bar->dragger != NULL) {
return RET_OK;
}
up = button_create(widget, 0, 0, 0, 0);
widget_set_name(up, "up");
@ -291,14 +275,12 @@ static ret_t scroll_bar_create_children(widget_t* widget) {
widget_set_name(down, "down");
widget_on(down, EVT_CLICK, scroll_bar_on_down_button_clicked, widget);
dragger = dragger_create(widget, r.x, r.y, r.w, r.h);
dragger = dragger_create(widget, 0, 0, 0, 0);
widget_set_name(dragger, "dragger");
widget_use_style(dragger, "1:scroll_bar");
widget_on(dragger, EVT_DRAG, scroll_bar_on_drag, widget);
if (widget->w > widget->h) {
int32_t max_x = widget_h + (widget_w - 2 * widget_h - r.w);
tk_snprintf(str, sizeof(str) - 1, "%d", (int)(widget->h));
widget_use_style(up, "13:scroll_left");
@ -306,41 +288,30 @@ static ret_t scroll_bar_create_children(widget_t* widget) {
widget_use_style(down, "14:scroll_right");
widget_set_self_layout_params(down, "right", "0", str, "100%");
dragger_set_range(dragger, widget_h, r.y, max_x, r.y);
} else {
int32_t max_y = widget_w + (widget_h - 2 * widget_w - r.h);
tk_snprintf(str, sizeof(str) - 1, "%d", (int)(widget->w));
widget_use_style(up, "12:scroll_up");
tk_snprintf(str, sizeof(str) - 1, "%d", (int)(widget->w));
widget_set_self_layout_params(up, "0", "0", "100%", str);
widget_use_style(down, "11:scroll_down");
widget_set_self_layout_params(down, "0", "bottom", "100%", str);
dragger_set_range(dragger, r.x, widget_w, r.x, max_y);
}
scroll_bar->dragger = dragger;
widget_layout(widget);
widget_invalidate_force(widget);
scroll_bar_layout_children(widget);
return RET_OK;
}
static ret_t scroll_bar_on_window_open(void* ctx, event_t* e) {
scroll_bar_create_children(WIDGET(ctx));
(void)e;
return RET_REMOVE;
}
/*share*/
ret_t scroll_bar_set_params(widget_t* widget, uint32_t max, uint32_t row) {
ret_t scroll_bar_set_params(widget_t* widget, int32_t max, int32_t row) {
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
scroll_bar->max = max;
scroll_bar->row = row;
scroll_bar_layout_children(widget);
return RET_OK;
}
@ -382,17 +353,14 @@ static ret_t scroll_bar_set_prop(widget_t* widget, const char* name, const value
static const widget_vtable_t s_scroll_bar_mobile_vtable = {
.type_name = WIDGET_TYPE_SCROLL_BAR,
.on_event = scroll_bar_mobile_on_event,
.set_prop = scroll_bar_set_prop,
.get_prop = scroll_bar_get_prop,
.on_paint_self = scroll_bar_mobile_on_paint_self};
static const widget_vtable_t s_scroll_bar_desktop_vtable = {
.type_name = WIDGET_TYPE_SCROLL_BAR,
.on_event = scroll_bar_desktop_on_event,
.set_prop = scroll_bar_set_prop,
.get_prop = scroll_bar_get_prop,
.on_paint_self = scroll_bar_desktop_on_paint_self};
static const widget_vtable_t s_scroll_bar_desktop_vtable = {.type_name = WIDGET_TYPE_SCROLL_BAR,
.on_event = scroll_bar_desktop_on_event,
.set_prop = scroll_bar_set_prop,
.get_prop = scroll_bar_get_prop};
static bool_t scroll_bar_is_mobile(widget_t* widget) {
return widget->vt == &s_scroll_bar_mobile_vtable;
@ -412,7 +380,7 @@ static ret_t scroll_bar_on_animate_end(void* ctx, event_t* e) {
return RET_REMOVE;
}
ret_t scroll_bar_scroll_to(widget_t* widget, uint32_t value, uint32_t duration) {
ret_t scroll_bar_scroll_to(widget_t* widget, int32_t value, int32_t duration) {
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
@ -467,6 +435,21 @@ ret_t scroll_bar_set_value(widget_t* widget, int32_t value) {
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
if (scroll_bar->value != value) {
event_t e = event_init(EVT_VALUE_CHANGED, widget);
scroll_bar_set_value_only(widget, value);
widget_dispatch(widget, &e);
widget_invalidate(widget, NULL);
}
return RET_OK;
}
ret_t scroll_bar_set_value_only(widget_t* widget, int32_t value) {
scroll_bar_t* scroll_bar = SCROLL_BAR(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
if (value < 0) {
value = 0;
}
@ -475,13 +458,8 @@ ret_t scroll_bar_set_value(widget_t* widget, int32_t value) {
value = scroll_bar->max;
}
if (scroll_bar->value != value) {
event_t e = event_init(EVT_VALUE_CHANGED, widget);
scroll_bar->value = value;
widget_dispatch(widget, &e);
widget_invalidate(widget, NULL);
}
scroll_bar->value = value;
scroll_bar_layout_children(widget);
return RET_OK;
}
@ -510,7 +488,8 @@ widget_t* scroll_bar_create_mobile(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_
widget_t* scroll_bar_create_desktop(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
widget_t* win = widget_get_window(parent);
widget_t* widget = scroll_bar_create_internal(parent, x, y, w, h, &s_scroll_bar_desktop_vtable);
widget_on(win, EVT_WINDOW_OPEN, scroll_bar_on_window_open, widget);
scroll_bar_create_children(widget);
widget_use_style(widget, "1:destkop");
return widget;

View File

@ -35,9 +35,24 @@ BEGIN_C_DECLS
*/
typedef struct _scroll_bar_t {
widget_t widget;
uint32_t max;
uint32_t value;
uint32_t row;
/**
* @property {int32_t} max
* @readonly
*
*/
int32_t max;
/**
* @property {int32_t} value
* @readonly
*
*/
int32_t value;
/**
* @property {int32_t} row
* @readonly
*
*/
int32_t row;
widget_t* dragger;
widget_animator_t* wa_value;
widget_animator_t* wa_opactiy;
@ -56,23 +71,77 @@ typedef struct _scroll_bar_t {
* @return {widget_t*}
*/
widget_t* scroll_bar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
widget_t* scroll_bar_create_mobile(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
widget_t* scroll_bar_create_desktop(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
/**
* @method scroll_bar_set_range
* scroll_bar对象
* @param {widget_t*} widget scroll_bar控件
* @param {uint32_t} max
* @param {uint32_t} row
* @method scroll_bar_create_mobile
* @constructor
* mobile风格的scroll_bar对象
* @param {widget_t*} parent
* @param {xy_t} x x坐标
* @param {xy_t} y y坐标
* @param {wh_t} w
* @param {wh_t} h
*
* @return {widget_t*}
*/
ret_t scroll_bar_set_params(widget_t* widget, uint32_t max, uint32_t row);
widget_t* scroll_bar_create_mobile(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
ret_t scroll_bar_scroll_to(widget_t* widget, uint32_t value, uint32_t duration);
/**
* @method scroll_bar_create_desktop
* @constructor
* desktop风格的scroll_bar对象
* @param {widget_t*} parent
* @param {xy_t} x x坐标
* @param {xy_t} y y坐标
* @param {wh_t} w
* @param {wh_t} h
*
* @return {widget_t*}
*/
widget_t* scroll_bar_create_desktop(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
/**
* @method scroll_bar_set_params
*
* @param {widget_t*} widget scroll_bar控件
* @param {int32_t} max
* @param {int32_t} row
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_bar_set_params(widget_t* widget, int32_t max, int32_t row);
/**
* @method scroll_bar_scroll_to
*
* @param {widget_t*} widget scroll_bar控件
* @param {int32_t} value
* @param {int32_t} duration
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_bar_scroll_to(widget_t* widget, int32_t value, int32_t duration);
/**
* @method scroll_bar_set_value
* EVT_VALUE_CHANGED事件
* @param {widget_t*} widget scroll_bar控件
* @param {int32_t} value
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_bar_set_value(widget_t* widget, int32_t value);
/**
* @method scroll_bar_set_value_only
* EVT_VALUE_CHANGED事件
* @param {widget_t*} widget scroll_bar控件
* @param {int32_t} value
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_bar_set_value_only(widget_t* widget, int32_t value);
#define SCROLL_BAR(widget) ((scroll_bar_t*)(widget))
END_C_DECLS

View File

@ -21,6 +21,7 @@
#include "base/mem.h"
#include "base/utils.h"
#include "base/layout.h"
#include "base/velocity.h"
#include "base/scroll_view.h"
#include "base/widget_vtable.h"
@ -52,6 +53,47 @@ ret_t scroll_view_invalidate(widget_t* widget, rect_t* r) {
return RET_OK;
}
static ret_t scroll_view_update_virtual_size(widget_t* widget) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
int32_t virtual_w = tk_max(scroll_view->virtual_w, widget->w);
int32_t virtual_h = tk_max(scroll_view->virtual_h, widget->h);
if (widget->children != NULL) {
int32_t i = 0;
int32_t n = 0;
for (i = 0, n = widget->children->size; i < n; i++) {
widget_t* iter = (widget_t*)(widget->children->elms[i]);
int32_t r = iter->x + iter->w;
int32_t b = iter->y + iter->h;
if (r > virtual_w) {
virtual_w = r;
}
if (b > virtual_h) {
virtual_h = b;
}
}
}
scroll_view->virtual_w = virtual_w;
scroll_view->virtual_h = virtual_h;
return RET_OK;
}
static ret_t scroll_view_on_layout_children(widget_t* widget) {
ret_t ret = RET_OK;
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
if (scroll_view->on_layout_children) {
ret = scroll_view->on_layout_children(widget);
} else {
ret = widget_layout_children_default(widget);
}
return scroll_view_update_virtual_size(widget);
}
ret_t scroll_view_invalidate_self(widget_t* widget) {
rect_t r = rect_init(widget->x, widget->y, widget->w, widget->h);
@ -83,6 +125,30 @@ static ret_t scroll_view_on_scroll_done(void* ctx, event_t* e) {
return RET_REMOVE;
}
static ret_t scroll_view_fix_end_offset_default(widget_t* widget) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
int32_t xoffset_end = scroll_view->xoffset_end;
int32_t yoffset_end = scroll_view->yoffset_end;
xoffset_end = tk_max(xoffset_end, 0);
yoffset_end = tk_max(yoffset_end, 0);
xoffset_end = tk_min(xoffset_end, (scroll_view->virtual_w - widget->w));
yoffset_end = tk_min(yoffset_end, (scroll_view->virtual_h - widget->h));
if (scroll_view->virtual_w <= widget->w) {
xoffset_end = 0;
}
if (scroll_view->virtual_h <= widget->h) {
yoffset_end = 0;
}
scroll_view->xoffset_end = xoffset_end;
scroll_view->yoffset_end = yoffset_end;
return RET_OK;
}
static ret_t scroll_view_on_pointer_up(scroll_view_t* scroll_view, pointer_event_t* e) {
widget_t* widget = WIDGET(scroll_view);
velocity_t* v = &(scroll_view->velocity);
@ -93,8 +159,8 @@ static ret_t scroll_view_on_pointer_up(scroll_view_t* scroll_view, pointer_event
int xv = v->xv;
int32_t xoffset = scroll_view->xoffset;
int32_t yoffset = scroll_view->yoffset;
int32_t xoffset_end = xoffset - xv;
int32_t yoffset_end = yoffset - yv;
scroll_view->xoffset_end = xoffset - xv;
scroll_view->yoffset_end = yoffset - yv;
if (scroll_view->wa != NULL) {
widget_animator_destroy(scroll_view->wa);
@ -102,23 +168,14 @@ static ret_t scroll_view_on_pointer_up(scroll_view_t* scroll_view, pointer_event
}
scroll_view->wa = widget_animator_scroll_create(widget, ANIMATING_TIME, 0, EASING_SIN_INOUT);
return_value_if_fail(scroll_view->wa != NULL, RET_OOM);
xoffset_end = tk_max(xoffset_end, 0);
yoffset_end = tk_max(yoffset_end, 0);
xoffset_end = tk_min(xoffset_end, (scroll_view->virtual_w - widget->w));
yoffset_end = tk_min(yoffset_end, (scroll_view->virtual_h - widget->h));
if (scroll_view->virtual_w <= widget->w) {
xoffset_end = 0;
if (scroll_view->fix_end_offset) {
scroll_view->fix_end_offset(widget);
}
if (scroll_view->virtual_h <= widget->h) {
yoffset_end = 0;
}
widget_animator_scroll_set_params(scroll_view->wa, xoffset, yoffset, xoffset_end, yoffset_end);
widget_animator_scroll_set_params(scroll_view->wa, xoffset, yoffset, scroll_view->xoffset_end,
scroll_view->yoffset_end);
widget_animator_on(scroll_view->wa, EVT_ANIM_END, scroll_view_on_scroll_done, scroll_view);
widget_animator_start(scroll_view->wa);
}
@ -248,6 +305,7 @@ static const widget_vtable_t s_scroll_view_vtable = {
.type_name = WIDGET_TYPE_SCROLL_VIEW,
.on_event = scroll_view_on_event,
.invalidate = scroll_view_invalidate,
.on_layout_children = scroll_view_on_layout_children,
.on_paint_children = scroll_view_on_paint_children,
.get_prop = scroll_view_get_prop,
.set_prop = scroll_view_set_prop};
@ -261,6 +319,7 @@ widget_t* scroll_view_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
widget->vt = &s_scroll_view_vtable;
widget_init(widget, parent, WIDGET_SCROLL_VIEW);
widget_move_resize(widget, x, y, w, h);
scroll_view->fix_end_offset = scroll_view_fix_end_offset_default;
return widget;
}
@ -282,3 +341,14 @@ ret_t scroll_view_set_virtual_h(widget_t* widget, wh_t h) {
return RET_OK;
}
ret_t scroll_view_set_offset(widget_t* widget, int32_t xoffset, int32_t yoffset) {
scroll_view_t* scroll_view = SCROLL_VIEW(widget);
scroll_view->xoffset = xoffset;
scroll_view->yoffset = yoffset;
scroll_view_invalidate_self(widget);
return RET_OK;
}

View File

@ -28,6 +28,8 @@
BEGIN_C_DECLS
typedef ret_t (*scroll_view_fix_end_offset_t)(widget_t* widget);
/**
* @class scroll_view_t
* @parent widget_t
@ -37,20 +39,42 @@ BEGIN_C_DECLS
typedef struct _scroll_view_t {
widget_t widget;
/**
* @property {wh_t} virtual_w
* @readonly
*
*/
wh_t virtual_w;
/**
* @property {wh_t} virtual_h
* @readonly
*
*/
wh_t virtual_h;
/**
* @property {int32_t_t} xoffset
* @readonly
* x偏移量
*/
int32_t xoffset;
/**
* @property {int32_t_t} yoffset
* @readonly
* y偏移量
*/
int32_t yoffset;
/*private*/
point_t down;
int32_t xoffset;
int32_t yoffset;
int32_t xoffset_end;
int32_t yoffset_end;
int32_t xoffset_save;
int32_t yoffset_save;
uint32_t timer_id;
velocity_t velocity;
widget_animator_t* wa;
scroll_view_fix_end_offset_t fix_end_offset;
widget_on_layout_children_t on_layout_children;
} scroll_view_t;
/**
@ -87,6 +111,17 @@ ret_t scroll_view_set_virtual_w(widget_t* widget, wh_t w);
*/
ret_t scroll_view_set_virtual_h(widget_t* widget, wh_t h);
/**
* @method scroll_view_set_offset
*
* @param {widget_t*} widget
* @param {xy_t} xoffset x偏移量
* @param {xy_t} yoffset x偏移量
*
* @return {ret_t} RET_OK表示成功
*/
ret_t scroll_view_set_offset(widget_t* widget, int32_t xoffset, int32_t yoffset);
#define SCROLL_VIEW(widget) ((scroll_view_t*)(widget))
END_C_DECLS

View File

@ -70,7 +70,7 @@ ret_t widget_move_resize(widget_t* widget, xy_t x, xy_t y, wh_t w, wh_t h) {
return RET_OK;
}
ret_t widget_set_value(widget_t* widget, uint32_t value) {
ret_t widget_set_value(widget_t* widget, int32_t value) {
value_t v;
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
@ -123,8 +123,8 @@ ret_t widget_re_translate_text(widget_t* widget) {
}
if (widget->children != NULL) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
for (i = 0, n = widget->children->size; i < n; i++) {
widget_t* iter = (widget_t*)(widget->children->elms[i]);
widget_re_translate_text(iter);
@ -137,7 +137,7 @@ ret_t widget_re_translate_text(widget_t* widget) {
#endif /*WITH_DYNAMIC_TR*/
}
uint32_t widget_get_value(widget_t* widget) {
int32_t widget_get_value(widget_t* widget) {
value_t v;
return_value_if_fail(widget != NULL, 0);
@ -244,8 +244,8 @@ ret_t widget_set_anchor(widget_t* widget, float_t anchor_x, float_t anchor_y) {
}
ret_t widget_destroy_children(widget_t* widget) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
if (widget->children != NULL) {
@ -267,8 +267,8 @@ ret_t widget_add_child(widget_t* widget, widget_t* child) {
widget->children = array_create(4);
}
if (widget->vt->add_child) {
if (widget->vt->add_child(widget, child) == RET_OK) {
if (widget->vt->on_add_child) {
if (widget->vt->on_add_child(widget, child) == RET_OK) {
return RET_OK;
}
}
@ -287,8 +287,8 @@ ret_t widget_remove_child(widget_t* widget, widget_t* child) {
widget->key_target = NULL;
}
if (widget->vt->remove_child) {
if (widget->vt->remove_child(widget, child) == RET_OK) {
if (widget->vt->on_remove_child) {
if (widget->vt->on_remove_child(widget, child) == RET_OK) {
return RET_OK;
}
}
@ -297,8 +297,8 @@ ret_t widget_remove_child(widget_t* widget, widget_t* child) {
}
static widget_t* widget_lookup_child(widget_t* widget, const char* name) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
return_value_if_fail(widget != NULL && name != NULL, NULL);
if (widget->children != NULL) {
@ -318,8 +318,8 @@ static widget_t* widget_lookup_child(widget_t* widget, const char* name) {
}
static widget_t* widget_lookup_all(widget_t* widget, const char* name) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
return_value_if_fail(widget != NULL && name != NULL, NULL);
if (widget->children != NULL) {
@ -360,8 +360,8 @@ static ret_t widget_set_visible_self(widget_t* widget, bool_t visible) {
}
static ret_t widget_set_visible_recursive(widget_t* widget, bool_t visible) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
widget->visible = visible;
@ -413,7 +413,7 @@ ret_t widget_dispatch(widget_t* widget, event_t* e) {
return ret;
}
uint32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx) {
int32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx) {
return_value_if_fail(widget != NULL && on_event != NULL, RET_BAD_PARAMS);
if (widget->emitter == NULL) {
widget->emitter = emitter_create();
@ -422,12 +422,12 @@ uint32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, v
return emitter_on(widget->emitter, type, on_event, ctx);
}
uint32_t widget_child_on(widget_t* widget, const char* name, event_type_t type,
event_func_t on_event, void* ctx) {
int32_t widget_child_on(widget_t* widget, const char* name, event_type_t type,
event_func_t on_event, void* ctx) {
return widget_on(widget_lookup(widget, name, TRUE), type, on_event, ctx);
}
ret_t widget_off(widget_t* widget, uint32_t id) {
ret_t widget_off(widget_t* widget, int32_t id) {
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
return_value_if_fail(widget->emitter != NULL, RET_BAD_PARAMS);
@ -511,7 +511,7 @@ ret_t widget_draw_background(widget_t* widget, canvas_t* c) {
dst = rect_init(0, 0, widget->w, widget->h);
image_draw_type_t draw_type =
(image_draw_type_t)style_get_int(style, STYLE_ID_BG_IMAGE_DRAW_TYPE, IMAGE_DRAW_CENTER);
uint32_t start_time = time_now_ms();
int32_t start_time = time_now_ms();
canvas_draw_image_ex(c, &img, draw_type, &dst);
dst.w = time_now_ms() - start_time;
}
@ -524,7 +524,7 @@ ret_t widget_draw_border(widget_t* widget, canvas_t* c) {
style_t* style = &(widget->style);
color_t trans = color_init(0, 0, 0, 0);
color_t bd = style_get_color(style, STYLE_ID_BORDER_COLOR, trans);
uint32_t border = style_get_int(style, STYLE_ID_BORDER, BORDER_ALL);
int32_t border = style_get_int(style, STYLE_ID_BORDER, BORDER_ALL);
if (bd.rgba.a) {
wh_t w = widget->w;
@ -993,8 +993,8 @@ ret_t widget_ungrab(widget_t* widget, widget_t* child) {
}
ret_t widget_foreach(widget_t* widget, tk_visit_t visit, void* ctx) {
uint32_t i = 0;
uint32_t nr = 0;
int32_t i = 0;
int32_t nr = 0;
widget_t** children = NULL;
return_value_if_fail(widget != NULL && visit != NULL, RET_BAD_PARAMS);
@ -1063,8 +1063,8 @@ ret_t widget_destroy(widget_t* widget) {
}
static ret_t widget_set_dirty(widget_t* widget) {
uint32_t i = 0;
uint32_t n = 0;
int32_t i = 0;
int32_t n = 0;
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
widget->dirty = TRUE;
@ -1230,13 +1230,13 @@ ret_t widget_to_global(widget_t* widget, point_t* p) {
return RET_OK;
}
uint32_t widget_count_children(widget_t* widget) {
int32_t widget_count_children(widget_t* widget) {
return_value_if_fail(widget != NULL, 0);
return widget->children != NULL ? widget->children->size : 0;
}
widget_t* widget_get_child(widget_t* widget, uint32_t index) {
widget_t* widget_get_child(widget_t* widget, int32_t index) {
return_value_if_fail(widget != NULL && widget->children != NULL, NULL);
return_value_if_fail(index < widget->children->size, NULL);
@ -1257,7 +1257,7 @@ ret_t widget_to_xml(widget_t* widget) {
}
if (widget->children) {
uint32_t i = 0;
int32_t i = 0;
log_debug(">\n");
for (i = 0; i < widget_count_children(widget); i++) {
widget_t* iter = widget_get_child(widget, i);

View File

@ -109,8 +109,8 @@ typedef ret_t (*widget_on_click_t)(widget_t* widget, pointer_event_t* e);
typedef ret_t (*widget_on_pointer_down_t)(widget_t* widget, pointer_event_t* e);
typedef ret_t (*widget_on_pointer_move_t)(widget_t* widget, pointer_event_t* e);
typedef ret_t (*widget_on_pointer_up_t)(widget_t* widget, pointer_event_t* e);
typedef ret_t (*widget_on_add_child)(widget_t* widget, widget_t* child);
typedef ret_t (*widget_on_remove_child)(widget_t* widget, widget_t* child);
typedef ret_t (*widget_on_add_child_t)(widget_t* widget, widget_t* child);
typedef ret_t (*widget_on_remove_child_t)(widget_t* widget, widget_t* child);
typedef ret_t (*widget_on_layout_children_t)(widget_t* widget);
typedef ret_t (*widget_get_prop_t)(widget_t* widget, const char* name, value_t* v);
typedef ret_t (*widget_set_prop_t)(widget_t* widget, const char* name, const value_t* v);
@ -136,8 +136,8 @@ typedef struct _widget_vtable_t {
widget_on_pointer_up_t on_pointer_up;
widget_on_layout_children_t on_layout_children;
widget_invalidate_t invalidate;
widget_on_add_child add_child;
widget_on_remove_child remove_child;
widget_on_add_child_t on_add_child;
widget_on_remove_child_t on_remove_child;
widget_on_event_t on_event;
widget_grab_t grab;
widget_ungrab_t ungrab;
@ -378,19 +378,19 @@ ret_t widget_update_style(widget_t* widget);
*
* @param {widget_t*} widget
*
* @return {uint32_t}
* @return {int32_t}
*/
uint32_t widget_count_children(widget_t* widget);
int32_t widget_count_children(widget_t* widget);
/**
* @method widget_get_child
*
* @param {widget_t*} widget
* @param {uint32_t} index
* @param {int32_t} index
*
* @return {widget_t*}
*/
widget_t* widget_get_child(widget_t* widget, uint32_t index);
widget_t* widget_get_child(widget_t* widget, int32_t index);
/**
* @method widget_move
@ -431,11 +431,11 @@ ret_t widget_move_resize(widget_t* widget, xy_t x, xy_t y, wh_t w, wh_t h);
* @method widget_set_value
* widget_set_prop的包装
* @param {widget_t*} widget
* @param {uint32_t} value
* @param {int32_t} value
*
* @return {ret_t} RET_OK表示成功
*/
ret_t widget_set_value(widget_t* widget, uint32_t value);
ret_t widget_set_value(widget_t* widget, int32_t value);
/**
* @method widget_use_style
@ -491,9 +491,9 @@ ret_t widget_re_translate_text(widget_t* widget);
* widget_get_prop的包装
* @param {widget_t*} widget
*
* @return {uint32_t}
* @return {int32_t}
*/
uint32_t widget_get_value(widget_t* widget);
int32_t widget_get_value(widget_t* widget);
/**
* @method widget_get_text
@ -678,20 +678,20 @@ ret_t widget_set_visible(widget_t* widget, bool_t visible, bool_t recursive);
* @param {event_func_t} on_event
* @param {void*} ctx
*
* @return {uint32_t} idwidget_off
* @return {int32_t} idwidget_off
*/
uint32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
int32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
/**
* @method widget_off
*
* @scriptable custom
* @param {widget_t*} widget
* @param {uint32_t} id widget_on返回的ID
* @param {int32_t} id widget_on返回的ID
*
* @return {ret_t} RET_OK表示成功
*/
ret_t widget_off(widget_t* widget, uint32_t id);
ret_t widget_off(widget_t* widget, int32_t id);
/**
* @method widget_child_on
@ -703,10 +703,10 @@ ret_t widget_off(widget_t* widget, uint32_t id);
* @param {event_func_t} on_event
* @param {void*} ctx
*
* @return {uint32_t} idwidget_off
* @return {int32_t} idwidget_off
*/
uint32_t widget_child_on(widget_t* widget, const char* name, event_type_t type,
event_func_t on_event, void* ctx);
int32_t widget_child_on(widget_t* widget, const char* name, event_type_t type,
event_func_t on_event, void* ctx);
/**
* @method widget_on
@ -717,9 +717,9 @@ uint32_t widget_child_on(widget_t* widget, const char* name, event_type_t type,
* @param {event_func_t} on_event
* @param {void*} ctx
*
* @return {uint32_t} idwidget_off
* @return {int32_t} idwidget_off
*/
uint32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
int32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
/**
* @method widget_off_by_func
*

View File

@ -71,6 +71,7 @@ BEGIN_C_DECLS
#define WIDGET_PROP_ROW "row"
#define WIDGET_PROP_THEME "theme"
#define WIDGET_PROP_SCRIPT "script"
#define WIDGET_PROP_ITEM_HEIGHT "item_height"
/*widget type name*/
#define WIDGET_TYPE_NONE "widget"
@ -103,6 +104,7 @@ BEGIN_C_DECLS
#define WIDGET_TYPE_SCROLL_BAR_DESKTOP "scroll_bar_d"
#define WIDGET_TYPE_SCROLL_BAR_MOBILE "scroll_bar_m"
#define WIDGET_TYPE_SCROLL_VIEW "scroll_view"
#define WIDGET_TYPE_LIST_VIEW "list_view"
/**
* @enum widget_type_t
@ -250,6 +252,11 @@ typedef enum _widget_type_t {
* Scroll View
*/
WIDGET_SCROLL_VIEW,
/**
* @const WIDGET_LIST_VIEW
* Scroll View
*/
WIDGET_LIST_VIEW,
WIDGET_NR,
WIDGET_USER_START = 100

View File

@ -38,6 +38,7 @@
#include "base/group_box.h"
#include "base/scroll_bar.h"
#include "base/scroll_view.h"
#include "base/list_view.h"
#include "base/slide_view.h"
#include "base/check_button.h"
#include "base/progress_bar.h"
@ -68,6 +69,7 @@ static const creator_item_t s_builtin_creators[] = {
{WIDGET_TYPE_DRAGGER, dragger_create},
#ifndef WITH_LOW_RES
{WIDGET_TYPE_SCROLL_VIEW, scroll_view_create},
{WIDGET_TYPE_LIST_VIEW, list_view_create},
{WIDGET_TYPE_SCROLL_BAR, scroll_bar_create},
{WIDGET_TYPE_SCROLL_BAR_DESKTOP, scroll_bar_create_desktop},
{WIDGET_TYPE_SCROLL_BAR_MOBILE, scroll_bar_create_mobile},