From 60b645681b3b5164ba1d0ad26afdcdcba29c86c9 Mon Sep 17 00:00:00 2001 From: lixianjing Date: Mon, 19 Feb 2024 17:46:51 +0800 Subject: [PATCH] improve scripts --- docs/changes.md | 3 +- docs/fscript_widget.md | 44 ++++++++++++++++++++ src/fscript_ext/fscript_widget.c | 71 ++++++++++++++++++++------------ tests/fscript_widget_test.cc | 46 ++++++++++++++++++--- 4 files changed, 131 insertions(+), 33 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index 1e8f63f9f..8528dc1b0 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -2,7 +2,8 @@ 2024/02/19 * 补充事件名(感谢兆坤提供补丁) - * 增加widget 通过 get_prop/set_prop函数设置state属性的功能。(感谢兆坤提供补丁) + * 增加widget 通过 get\_prop/set\_prop函数设置state属性的功能(感谢兆坤提供补丁) + * fscript 增加 widget\_get\_child 和 widget\_count\_children函数(感谢兆坤提供补丁) 2024/02/07 * 增加函数tk\_bits\_data\_to\_bytes\_data/tk\_bits\_data\_from\_bytes\_data diff --git a/docs/fscript_widget.md b/docs/fscript_widget.md index b351426f3..0fe2b4b3a 100644 --- a/docs/fscript_widget.md +++ b/docs/fscript_widget.md @@ -1293,6 +1293,50 @@ show_fps(true) show_fps(false) ``` +### 5.39 widget_get_child + +> 获取指定索引的子控件 +---------------------------- + +#### 原型 + +```js +widget_get_child(widget, index) => obj_widget +``` + +* widget 可以是 widget 对象,也可以是 widget 的路径。 +* index 索引。 +* 返回子控件对象。 + +#### 示例 + +```js +var a = widget_get_child('self', 0) +``` + +### 5.40 widget_count_children + +> 获取子控件的个数 +---------------------------- + +#### 原型 + +```js +widget_count_children(widget) => int32 +``` + +* widget 可以是 widget 对象,也可以是 widget 的路径。 +* 返回子控件的个数。 + +#### 示例 + +```js +var size = widget_count_children(widget) +for (var a = 0; a < size; a = a + 1) { + var b = widget_get_child(widget, a) +} +``` + ### 示例参考 * https://github.com/zlgopen/awtk/blob/master/design/default/ui/main_fscript.xml diff --git a/src/fscript_ext/fscript_widget.c b/src/fscript_ext/fscript_widget.c index c083fcb53..9a59c0ae3 100644 --- a/src/fscript_ext/fscript_widget.c +++ b/src/fscript_ext/fscript_widget.c @@ -55,6 +55,17 @@ static widget_t* to_widget(fscript_t* fscript, const value_t* v) { } } +static ret_t fscript_value_set_widget(value_t* v, widget_t* widget) { + tk_object_t* obj_widget = NULL; + return_value_if_fail(v != NULL && widget != NULL, RET_BAD_PARAMS); + + obj_widget = object_widget_create(widget); + value_set_object(v, obj_widget); + v->free_handle = TRUE; + + return RET_OK; +} + static ret_t func_tr(fscript_t* fscript, fscript_args_t* args, value_t* result) { locale_info_t* info = NULL; widget_t* widget = WIDGET(tk_object_get_prop_pointer(fscript->obj, STR_PROP_SELF)); @@ -74,7 +85,6 @@ static ret_t func_tr(fscript_t* fscript, fscript_args_t* args, value_t* result) static ret_t func_window_open(fscript_t* fscript, fscript_args_t* args, value_t* result) { widget_t* widget = NULL; const char* name = NULL; - tk_object_t* obj_widget = NULL; bool_t close_current = FALSE; bool_t switch_to_if_exist = FALSE; widget_t* wm = window_manager(); @@ -90,10 +100,7 @@ static ret_t func_window_open(fscript_t* fscript, fscript_args_t* args, value_t* widget_t* widget = widget_child(wm, name); if (widget != NULL) { window_manager_switch_to(wm, curr_win, widget, close_current); - obj_widget = object_widget_create(widget); - value_set_object(result, obj_widget); - result->free_handle = TRUE; - return RET_OK; + return fscript_value_set_widget(result, widget); } } @@ -103,11 +110,7 @@ static ret_t func_window_open(fscript_t* fscript, fscript_args_t* args, value_t* widget = window_open(value_str(args->args)); } - obj_widget = object_widget_create(widget); - value_set_object(result, obj_widget); - result->free_handle = TRUE; - - return RET_OK; + return fscript_value_set_widget(result, widget); } static ret_t func_window_close_and_open(fscript_t* fscript, fscript_args_t* args, value_t* result) { @@ -141,7 +144,7 @@ static ret_t widget_set(widget_t* self, const char* path, const value_t* v) { widget_t* widget = self; const char* prop = strrchr(path, '.'); if (prop != NULL) { - char name[MAX_PATH+1] = {0}; + char name[MAX_PATH + 1] = {0}; int32_t len = tk_min_int(prop - path, MAX_PATH); tk_strncpy(name, path, len); widget = widget_find_by_path(self, name, TRUE); @@ -159,7 +162,7 @@ static ret_t widget_get(widget_t* self, const char* path, value_t* v) { widget_t* widget = self; const char* prop = strrchr(path, '.'); if (prop != NULL) { - char name[MAX_PATH+1] = {0}; + char name[MAX_PATH + 1] = {0}; int32_t len = tk_min_int(prop - path, MAX_PATH); tk_strncpy(name, path, len); widget = widget_find_by_path(self, name, TRUE); @@ -231,7 +234,6 @@ static ret_t func_widget_lookup(fscript_t* fscript, fscript_args_t* args, value_ widget_t* widget = NULL; const char* path = NULL; bool_t recursive = FALSE; - tk_object_t* obj_widget = NULL; FSCRIPT_FUNC_CHECK(args->size >= 1, RET_BAD_PARAMS); if (args->size == 1) { @@ -249,10 +251,7 @@ static ret_t func_widget_lookup(fscript_t* fscript, fscript_args_t* args, value_ result->type = VALUE_TYPE_INVALID; return RET_NOT_FOUND; } else { - obj_widget = object_widget_create(widget); - value_set_object(result, obj_widget); - result->free_handle = TRUE; - return RET_OK; + return fscript_value_set_widget(result, widget); } } @@ -273,6 +272,30 @@ static ret_t func_widget_get(fscript_t* fscript, fscript_args_t* args, value_t* return widget_get(widget, path, result); } +static ret_t func_widget_get_child(fscript_t* fscript, fscript_args_t* args, value_t* result) { + value_t* v = NULL; + widget_t* widget = NULL; + widget_t* widget_child = NULL; + FSCRIPT_FUNC_CHECK(args->size == 2, RET_BAD_PARAMS); + widget = to_widget(fscript, args->args); + v = args->args + 1; + + widget_child = widget_get_child(widget, value_int32(v)); + + return fscript_value_set_widget(result, widget_child); +} + +static ret_t func_widget_count_children(fscript_t* fscript, fscript_args_t* args, value_t* result) { + widget_t* widget = NULL; + FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); + widget = to_widget(fscript, args->args); + FSCRIPT_FUNC_CHECK(widget != NULL, RET_BAD_PARAMS); + + value_set_int32(result, widget_count_children(widget)); + + return RET_OK; +} + static ret_t func_widget_eval(fscript_t* fscript, fscript_args_t* args, value_t* result) { value_t v; ret_t ret = RET_OK; @@ -345,7 +368,6 @@ static ret_t func_widget_create(fscript_t* fscript, fscript_args_t* args, value_ const char* type = NULL; widget_t* widget = NULL; widget_t* parent = NULL; - tk_object_t* obj_widget = NULL; FSCRIPT_FUNC_CHECK(args->size == 6, RET_BAD_PARAMS); type = value_str(args->args); parent = to_widget(fscript, args->args + 1); @@ -356,11 +378,7 @@ static ret_t func_widget_create(fscript_t* fscript, fscript_args_t* args, value_ h = value_int(args->args + 5); widget = widget_factory_create_widget(widget_factory(), type, parent, x, y, w, h); - obj_widget = object_widget_create(widget); - value_set_object(result, obj_widget); - result->free_handle = TRUE; - - return RET_OK; + return fscript_value_set_widget(result, widget); } static ret_t func_widget_destroy(fscript_t* fscript, fscript_args_t* args, value_t* result) { @@ -381,10 +399,7 @@ static ret_t func_widget_clone(fscript_t* fscript, fscript_args_t* args, value_t FSCRIPT_FUNC_CHECK(widget != NULL, RET_BAD_PARAMS); widget = widget_clone(widget, widget->parent); - value_set_object(result, object_widget_create(widget)); - result->free_handle = TRUE; - - return RET_OK; + return fscript_value_set_widget(result, widget); } static ret_t func_widget_destroy_children(fscript_t* fscript, fscript_args_t* args, @@ -791,6 +806,8 @@ FACTORY_TABLE_ENTRY("widget_layout", func_widget_layout) FACTORY_TABLE_ENTRY("widget_request_relayout", func_widget_request_relayout) FACTORY_TABLE_ENTRY("widget_lookup", func_widget_lookup) FACTORY_TABLE_ENTRY("widget_get", func_widget_get) +FACTORY_TABLE_ENTRY("widget_get_child", func_widget_get_child) +FACTORY_TABLE_ENTRY("widget_count_children", func_widget_count_children) FACTORY_TABLE_ENTRY("widget_eval", func_widget_eval) FACTORY_TABLE_ENTRY("widget_set", func_widget_set) FACTORY_TABLE_ENTRY("widget_add_value", func_widget_add_value) diff --git a/tests/fscript_widget_test.cc b/tests/fscript_widget_test.cc index fdae3f33e..8f1e3640e 100644 --- a/tests/fscript_widget_test.cc +++ b/tests/fscript_widget_test.cc @@ -1,13 +1,16 @@ +#include "gtest/gtest.h" + #include "tkc/fscript.h" #include "tkc/object_default.h" -#include "gtest/gtest.h" -#include "widgets/edit.h" -#include "widgets/button.h" -#include "widgets/progress_bar.h" #include "base/window.h" #include "base/window_manager.h" #include "base/object_widget.h" +#include "widgets/view.h" +#include "widgets/edit.h" +#include "widgets/button.h" +#include "widgets/progress_bar.h" + TEST(FScriptWidget, basic) { value_t v; tk_object_t* obj = object_default_create(); @@ -71,7 +74,7 @@ TEST(FScriptWidget, ulen) { fscript_eval(obj, "ulen(text)", &v); ASSERT_EQ(value_int(&v), 2); value_reset(&v); - + widget_set_text(w, L"abc"); fscript_eval(obj, "ulen(text)", &v); ASSERT_EQ(value_int(&v), 3); @@ -80,3 +83,36 @@ TEST(FScriptWidget, ulen) { widget_destroy(w); TK_OBJECT_UNREF(obj); } + +TEST(FScriptWidget, foreach) { + value_t v = {0}; + tk_object_t* obj = object_default_create(); + widget_t* w = view_create(NULL, 0, 0, 320, 240); + widget_t* children[3] = {NULL}; + tk_object_set_prop_pointer(obj, STR_PROP_SELF, w); + + children[0] = edit_create(NULL, 0, 0, 100, 20); + widget_add_child(w, children[0]); + + children[1] = button_create(NULL, 0, 20, 90, 30); + widget_add_child(w, children[1]); + + children[2] = view_create(NULL, 0, 50, 100, 100); + widget_add_child(w, children[2]); + + fscript_eval(obj, "widget_count_children('self')", &v); + ASSERT_EQ(value_int32(&v), 3); + value_reset(&v); + + for (size_t i = 0; i < ARRAY_SIZE(children); i++) { + char script[64] = {0}; + tk_snprintf(script, ARRAY_SIZE(script) - 1, "widget_get_child('self', %d)", i); + fscript_eval(obj, script, &v); + ASSERT_EQ(tk_object_get_prop_pointer(value_object(&v), OBJECT_WIDGET_PROP_NATIVE_WIDGET), + children[i]); + value_reset(&v); + } + + widget_unref(w); + TK_OBJECT_UNREF(obj); +}