mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 10:38:47 +08:00
add widget_visible_in_scroll_view
This commit is contained in:
parent
365825839e
commit
48f4ea7bdb
@ -29,6 +29,7 @@ widget_t* scroll_view = NULL;
|
||||
#define SCROLL_BAR_H_WIDGT_NAME "bar_h"
|
||||
#define SCROLL_BAR_V_WIDGT_NAME "bar_v"
|
||||
#define BUTTON_SET_FOCUSE_STRING "focused:"
|
||||
#define BUTTON_SET_PROP_VISIBLE_REVEAL_IN_SCROLL_STRING "set_prop:"
|
||||
|
||||
static int32_t scroll_bar_value_to_scroll_view_offset_y(scroll_bar_t* scroll_bar,
|
||||
scroll_view_t* sv) {
|
||||
@ -94,6 +95,16 @@ static ret_t on_set_focuse_item(void* ctx, event_t* e) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t on_set_visible_reveal_in_scroll(void* ctx, event_t* e) {
|
||||
const char* name = (const char*)ctx;
|
||||
|
||||
if (name != NULL) {
|
||||
widget_set_prop_str(scroll_view, WIDGET_PROP_VISIBLE_REVEAL_IN_SCROLL, name);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t scroll_view_offset_changed(void* ctx, event_t* e) {
|
||||
scroll_view_t* sv = SCROLL_VIEW(scroll_view);
|
||||
scroll_bar_t* scroll_bar_h = SCROLL_BAR(bar_h);
|
||||
@ -133,6 +144,9 @@ static ret_t install_one(void* ctx, const void* iter) {
|
||||
if (strstr(name, BUTTON_SET_FOCUSE_STRING) != NULL) {
|
||||
widget_on(widget, EVT_CLICK, on_set_focuse_item,
|
||||
(void*)(name + tk_strlen(BUTTON_SET_FOCUSE_STRING)));
|
||||
} else if (strstr(name, BUTTON_SET_PROP_VISIBLE_REVEAL_IN_SCROLL_STRING) != NULL) {
|
||||
widget_on(widget, EVT_CLICK, on_set_visible_reveal_in_scroll,
|
||||
(void*)(name + tk_strlen(BUTTON_SET_PROP_VISIBLE_REVEAL_IN_SCROLL_STRING)));
|
||||
} else if (tk_str_eq(name, SCROLL_BAR_H_WIDGT_NAME)) {
|
||||
bar_h = widget;
|
||||
widget_on(widget, EVT_VALUE_CHANGED, scroll_bar_value_changed, widget);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<window anim_hint="htranslate">
|
||||
<view x="0" y="0" w="100%" h="70%">
|
||||
<view x="0" y="0" w="100%" h="60%">
|
||||
<scroll_view x="10%" y="10%" w="80%" h="80%" xoffset="0" yoffset="0" recursive="true" style.normal.border_color="#ff0000" >
|
||||
<view x="1" y="1" w="30" h="30" style.normal.border_color="#0000ff" >
|
||||
<view x="1" y="1" w="30" h="30" style.normal.border_color="#0000ff" style.normal.bg_color="red" >
|
||||
<image image="earth" name="earth1" x="0" y="0" w="24" h="24"/>
|
||||
</view>
|
||||
<view x="1" y="100" w="30" h="30" style.normal.border_color="#0000ff">
|
||||
@ -15,7 +15,7 @@
|
||||
</view>
|
||||
<view x="1" y="400" w="60" h="60" style.normal.border_color="#0000ff">
|
||||
<view x="0" y="5" w="50" h="50" style.normal.border_color="#ff00ff">
|
||||
<image image="earth" name="earth2" x="0" y="b" w="24" h="24"/>
|
||||
<image image="earth" name="earth2" x="0" y="b" w="24" h="24" style.normal.bg_color="red"/>
|
||||
</view>
|
||||
</view>
|
||||
<view x="100" y="100" w="30" h="30" style.normal.border_color="#0000ff">
|
||||
@ -31,19 +31,26 @@
|
||||
<image image="earth" x="0" y="0" w="24" h="24"/>
|
||||
</view>
|
||||
<view x="400" y="400" w="60" h="60" style.normal.border_color="#0000ff">
|
||||
<image image="earth" name="earth3" x="0" y="0" w="24" h="24"/>
|
||||
<image image="earth" name="earth3" x="0" y="0" w="24" h="24" style.normal.bg_color="red"/>
|
||||
</view>
|
||||
<view x="200" y="400" w="30" h="30" style.normal.border_color="#0000ff">
|
||||
<image image="earth" name="earth4" x="60" y="60" w="24" h="24"/>
|
||||
<image image="earth" name="earth4" x="60" y="60" w="24" h="24" style.normal.bg_color="red"/>
|
||||
</view>
|
||||
</scroll_view>
|
||||
<scroll_bar_d name="bar_h" x="10%" y="b" w="80%" h="10%" value="0"/>
|
||||
<scroll_bar_d name="bar_v" x="r" y="10%" w="10%" h="80%" value="0"/>
|
||||
</view>
|
||||
<view x="0" y="b" w="100%" h="30%" children_layout="default(c=2,r=4,m=5,s=5)" >
|
||||
<view style:border_color="red" x="0" y="60%" w="100%" h="15%" children_layout="default(c=2,r=2,m=5,s=5)" >
|
||||
<button name="focused:earth1" text="earth1" />
|
||||
<button name="focused:earth2" text="earth2" />
|
||||
<button name="focused:earth3" text="earth3" />
|
||||
<button name="focused:earth4" text="earth4" />
|
||||
</view>
|
||||
<view style:border_color="red" x="0" y="75%" w="100%" h="25%" children_layout="default(c=2,r=3,m=5,s=5)" >
|
||||
<button name="set_prop:default" text="default" />
|
||||
<button name="set_prop:in_center" text="in_center" />
|
||||
<button name="set_prop:in_center_if_outside_viewport" text="in_center_outside" />
|
||||
<button name="set_prop:at_top" text="at_top" />
|
||||
<button name="set_prop:no_operation" text="no_operation" />
|
||||
</view>
|
||||
</window>
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
2024/06/13
|
||||
* 去掉不必要的参数有效性检查(感谢朝泽提供补丁)
|
||||
* 增加滚动控件的子控件可视滚动属性(感谢智明提供补丁)
|
||||
|
||||
2024/06/12
|
||||
* 修复中文输入法在输入超过15位拼音后多余的字符会直接输入到编辑框的bug(感谢泽武提供补丁)
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "base/assets_manager.h"
|
||||
#include "blend/image_g2d.h"
|
||||
#include "base/style_const.h"
|
||||
#include "base/widget_visible_in_scroll_view.inc"
|
||||
|
||||
ret_t widget_focus_up(widget_t* widget);
|
||||
ret_t widget_focus_down(widget_t* widget);
|
||||
@ -4125,39 +4126,29 @@ static ret_t widget_ensure_visible_in_scroll_view(widget_t* scroll_view, widget_
|
||||
int32_t oy = 0;
|
||||
int32_t old_ox = 0;
|
||||
int32_t old_oy = 0;
|
||||
rect_t r, r_visable;
|
||||
int32_t max_w = 0;
|
||||
int32_t max_h = 0;
|
||||
rect_t r;
|
||||
widget_visible_reveal_in_scroll_func_t func;
|
||||
return_value_if_fail(widget != NULL && scroll_view != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(&p, 0x0, sizeof(point_t));
|
||||
widget_to_screen_ex(widget, scroll_view, &p);
|
||||
r = rect_init(p.x, p.y, widget->w, widget->h);
|
||||
|
||||
func = widget_get_visible_reveal_in_scroll_func(scroll_view);
|
||||
ox = widget_get_prop_int(scroll_view, WIDGET_PROP_XOFFSET, 0);
|
||||
oy = widget_get_prop_int(scroll_view, WIDGET_PROP_YOFFSET, 0);
|
||||
old_ox = ox;
|
||||
old_oy = oy;
|
||||
|
||||
r_visable = rect_init(ox, oy, scroll_view->w, scroll_view->h);
|
||||
if (rect_has_intersect(&r, &r_visable)) {
|
||||
return RET_OK;
|
||||
}
|
||||
func(&r, ox, oy, scroll_view->w, scroll_view->h, &ox, &oy);
|
||||
|
||||
if (oy > r.y) {
|
||||
oy = r.y;
|
||||
}
|
||||
|
||||
if (ox > r.x) {
|
||||
ox = r.x;
|
||||
}
|
||||
|
||||
if ((r.y + r.h) > (oy + scroll_view->h)) {
|
||||
oy = r.y + r.h - scroll_view->h;
|
||||
}
|
||||
|
||||
if ((r.x + r.w) > (ox + scroll_view->w)) {
|
||||
ox = r.x + r.w - scroll_view->w;
|
||||
}
|
||||
max_w = widget_get_prop_int(scroll_view, WIDGET_PROP_VIRTUAL_W, scroll_view->w);
|
||||
max_h = widget_get_prop_int(scroll_view, WIDGET_PROP_VIRTUAL_H, scroll_view->h);
|
||||
|
||||
ox = tk_min(ox, max_w - scroll_view->w);
|
||||
oy = tk_min(oy, max_h - scroll_view->h);
|
||||
|
||||
if (ox != old_ox) {
|
||||
widget_set_prop_int(scroll_view, WIDGET_PROP_XOFFSET, ox);
|
||||
}
|
||||
|
@ -335,6 +335,12 @@ BEGIN_C_DECLS
|
||||
*/
|
||||
#define WIDGET_PROP_ELLIPSES "ellipses"
|
||||
|
||||
/**
|
||||
* @const WIDGET_PROP_VISIBLE_REVEAL_IN_SCROLL
|
||||
* 可见控件在滚动控件中的可见处理方案。(影响 widget_ensure_visible_in_viewport 函数)
|
||||
*/
|
||||
#define WIDGET_PROP_VISIBLE_REVEAL_IN_SCROLL "visible_reveal_in_scroll"
|
||||
|
||||
/**
|
||||
* @const WIDGET_PROP_TEXT
|
||||
* 文本。
|
||||
|
107
src/base/widget_visible_in_scroll_view.inc
Normal file
107
src/base/widget_visible_in_scroll_view.inc
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
#define WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_DEFAULT "default"
|
||||
|
||||
#define WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_IN_CENTER "in_center"
|
||||
|
||||
#define WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_IN_CENTER_IF_OUTSIDE_VIEWPORT "in_center_if_outside_viewport"
|
||||
|
||||
#define WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_AT_TOP "at_top"
|
||||
|
||||
#define WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_NO_OPERATION "no_operation"
|
||||
|
||||
typedef ret_t (*widget_visible_reveal_in_scroll_func_t)(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy);
|
||||
|
||||
/**
|
||||
* 调整到最近的可视位置,即块已在可视区域内,如果显示区域比滚动区域还要大,则不做任何操作,否则选择最短的路径移到到可视区域。
|
||||
*/
|
||||
static ret_t widget_visible_reveal_in_scroll_by_default(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy) {
|
||||
return_value_if_fail(r != NULL && new_ox != NULL && new_oy != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (oy > r->y) {
|
||||
oy = r->y;
|
||||
}
|
||||
if ((r->y + r->h) > (oy + scroll_h)) {
|
||||
oy = r->y + r->h - scroll_h;
|
||||
}
|
||||
|
||||
if (ox > r->x) {
|
||||
ox = r->x;
|
||||
}
|
||||
if ((r->x + r->w) > (ox + scroll_w)) {
|
||||
ox = r->x + r->w - scroll_w;
|
||||
}
|
||||
|
||||
*new_ox = tk_max(ox, 0);
|
||||
*new_oy = tk_max(oy, 0);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整到可视区域的中心,比如块没有在可视区域的中心(即使已在可视区域内),则调整到中心。
|
||||
*/
|
||||
static ret_t widget_visible_reveal_in_scroll_by_in_center(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy) {
|
||||
return_value_if_fail(r != NULL && new_ox != NULL && new_oy != NULL, RET_BAD_PARAMS);
|
||||
(void)ox;
|
||||
(void)oy;
|
||||
*new_ox = r->x + (r->w - scroll_w) / 2;
|
||||
*new_oy = r->y + (r->h - scroll_h) / 2;
|
||||
*new_ox = tk_max(*new_ox, 0);
|
||||
*new_oy = tk_max(*new_oy, 0);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果在可视区域之外,则调整到可视区域的中心;否则,不做任何操作。
|
||||
*/
|
||||
static ret_t widget_visible_reveal_in_scroll_by_in_center_if_outside_viewport(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy) {
|
||||
rect_t rect1;
|
||||
return_value_if_fail(r != NULL && new_ox != NULL && new_oy != NULL, RET_BAD_PARAMS);
|
||||
rect1 = rect_init(ox, oy, scroll_w, scroll_h);
|
||||
if (rect_has_intersect(&rect1, r)) {
|
||||
*new_ox = ox;
|
||||
*new_oy = oy;
|
||||
return RET_OK;
|
||||
} else {
|
||||
return widget_visible_reveal_in_scroll_by_in_center(r, ox, oy, scroll_w, scroll_h, new_ox, new_oy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整到可视区域的顶端,比如块没有在可视区域的顶端(即使已在可视区域内),则调整到顶端。
|
||||
*/
|
||||
static ret_t widget_visible_reveal_in_scroll_by_at_top(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy) {
|
||||
return_value_if_fail(r != NULL && new_ox != NULL && new_oy != NULL, RET_BAD_PARAMS);
|
||||
(void)scroll_w;
|
||||
(void)scroll_h;
|
||||
|
||||
*new_ox = r->x;
|
||||
*new_oy = r->y;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/* 不做任何处理 */
|
||||
static ret_t widget_visible_reveal_in_scroll_by_no_operation(const rect_t* r, xy_t ox, xy_t oy, wh_t scroll_w, wh_t scroll_h, xy_t* new_ox, xy_t* new_oy) {
|
||||
return_value_if_fail(r != NULL && new_ox != NULL && new_oy != NULL, RET_BAD_PARAMS);
|
||||
*new_ox = ox;
|
||||
*new_oy = oy;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static widget_visible_reveal_in_scroll_func_t widget_get_visible_reveal_in_scroll_func(widget_t* scroll_view) {
|
||||
const char* str = widget_get_prop_str(scroll_view, WIDGET_PROP_VISIBLE_REVEAL_IN_SCROLL, NULL);
|
||||
if (str != NULL) {
|
||||
if (tk_stricmp(str, WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_DEFAULT) == 0) {
|
||||
return widget_visible_reveal_in_scroll_by_default;
|
||||
} else if (tk_stricmp(str, WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_IN_CENTER) == 0) {
|
||||
return widget_visible_reveal_in_scroll_by_in_center;
|
||||
} else if (tk_stricmp(str, WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_IN_CENTER_IF_OUTSIDE_VIEWPORT) == 0) {
|
||||
return widget_visible_reveal_in_scroll_by_in_center_if_outside_viewport;
|
||||
} else if (tk_stricmp(str, WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_AT_TOP) == 0) {
|
||||
return widget_visible_reveal_in_scroll_by_at_top;
|
||||
} else if (tk_stricmp(str, WIDGET_VISIBLE_REVEAL_IN_SCROLL_TYPE_NO_OPERATION) == 0) {
|
||||
return widget_visible_reveal_in_scroll_by_no_operation;
|
||||
}
|
||||
}
|
||||
return widget_visible_reveal_in_scroll_by_default;
|
||||
}
|
Loading…
Reference in New Issue
Block a user