diff --git a/src/base/pages.c b/src/base/pages.c index d9999e325..15843a865 100644 --- a/src/base/pages.c +++ b/src/base/pages.c @@ -38,22 +38,13 @@ ret_t pages_set_active(widget_t* widget, uint32_t index) { } ret_t pages_set_active_by_name(widget_t* widget, const char* name) { - uint32_t i = 0; - uint32_t nr = 0; - widget_t** children = NULL; return_value_if_fail(widget != NULL && name != NULL, RET_BAD_PARAMS); - if (widget->children && widget->children->elms) { - nr = widget->children->size; - children = (widget_t**)(widget->children->elms); - - for (i = 0; i < nr; i++) { - widget_t* iter = children[i]; - if (iter->name.str && tk_str_eq(iter->name.str, name)) { - return pages_set_active(widget, i); - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + if (tk_str_eq(iter->name.str, name)) { + return pages_set_active(widget, i); } + WIDGET_FOR_EACH_CHILD_END(); return RET_NOT_FOUND; } diff --git a/src/base/scroll_view.c b/src/base/scroll_view.c index e603a4bc6..44acca152 100755 --- a/src/base/scroll_view.c +++ b/src/base/scroll_view.c @@ -65,24 +65,16 @@ static ret_t scroll_view_update_virtual_size(widget_t* 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; - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, 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; + } + WIDGET_FOR_EACH_CHILD_END(); scroll_view->virtual_w = virtual_w; scroll_view->virtual_h = virtual_h; diff --git a/src/base/utils.h b/src/base/utils.h index 5d1fd840f..58f70a92a 100644 --- a/src/base/utils.h +++ b/src/base/utils.h @@ -43,7 +43,8 @@ void* tk_pixel_copy(void* dst, const void* src, uint32_t size, uint8_t bpp); int tk_snprintf(char* str, size_t size, const char* format, ...); ret_t filename_to_name(const char* filename, char* str, uint32_t size); -#define tk_str_eq(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) +#define tk_str_eq(s1, s2) \ + ((s1) != NULL) && ((s2) != NULL) && (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) #define tk_fequal(f1, f2) (fabs((f1) - (f2)) < 0.0000001) END_C_DECLS diff --git a/src/base/widget.c b/src/base/widget.c index e21e38f4f..40bef2824 100644 --- a/src/base/widget.c +++ b/src/base/widget.c @@ -136,14 +136,9 @@ ret_t widget_re_translate_text(widget_t* widget) { widget_invalidate(widget, NULL); } - 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]); - widget_re_translate_text(iter); - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + widget_re_translate_text(iter); + WIDGET_FOR_EACH_CHILD_END(); return RET_OK; #else @@ -258,17 +253,12 @@ ret_t widget_set_anchor(widget_t* widget, float_t anchor_x, float_t anchor_y) { } ret_t widget_destroy_children(widget_t* widget) { - int32_t i = 0; - int32_t n = 0; return_value_if_fail(widget != NULL, RET_BAD_PARAMS); - if (widget->children != NULL) { - for (i = 0, n = widget->children->size; i < n; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - widget_destroy_only(iter); - } - widget->children->size = 0; - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + widget_destroy_only(iter); + WIDGET_FOR_EACH_CHILD_END(); + widget->children->size = 0; return RET_OK; } @@ -301,55 +291,41 @@ ret_t widget_remove_child(widget_t* widget, widget_t* child) { widget->key_target = NULL; } - child->parent = NULL; if (widget->vt->on_remove_child) { if (widget->vt->on_remove_child(widget, child) == RET_OK) { return RET_OK; } } + child->parent = NULL; return array_remove(widget->children, NULL, child, NULL); } static widget_t* widget_lookup_child(widget_t* widget, const char* name) { - int32_t i = 0; - int32_t n = 0; return_value_if_fail(widget != NULL && name != NULL, NULL); - if (widget->children != NULL) { - for (i = 0, n = widget->children->size; i < n; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - if (iter->name.str == NULL) { - continue; - } - - if (str_eq(&(iter->name), name)) { - return iter; - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + if (iter->name.str != NULL && str_eq(&(iter->name), name)) { + return iter; } + WIDGET_FOR_EACH_CHILD_END() return NULL; } static widget_t* widget_lookup_all(widget_t* widget, const char* name) { - int32_t i = 0; - int32_t n = 0; return_value_if_fail(widget != NULL && name != NULL, NULL); - if (widget->children != NULL) { - for (i = 0, n = widget->children->size; i < n; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - if (str_eq(&(iter->name), name)) { - return iter; - } else { - iter = widget_lookup_all(iter, name); - if (iter != NULL) { - return iter; - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + if (iter->name.str != NULL && str_eq(&(iter->name), name)) { + return iter; + } else { + iter = widget_lookup_all(iter, name); + if (iter != NULL) { + return iter; } } + WIDGET_FOR_EACH_CHILD_END(); return NULL; } @@ -375,17 +351,12 @@ 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) { - int32_t i = 0; - int32_t n = 0; return_value_if_fail(widget != NULL, RET_BAD_PARAMS); widget->visible = visible; - if (widget->children != NULL) { - for (i = 0, n = widget->children->size; i < n; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - widget_set_visible_recursive(iter, visible); - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + widget_set_visible_recursive(iter, visible); + WIDGET_FOR_EACH_CHILD_END() return RET_OK; } @@ -1045,24 +1016,15 @@ ret_t widget_ungrab(widget_t* widget, widget_t* child) { } ret_t widget_foreach(widget_t* widget, tk_visit_t visit, void* ctx) { - int32_t i = 0; - int32_t nr = 0; - widget_t** children = NULL; return_value_if_fail(widget != NULL && visit != NULL, RET_BAD_PARAMS); if (visit(ctx, widget) != RET_OK) { return RET_DONE; } - if (widget->children && widget->children->elms) { - nr = widget->children->size; - children = (widget_t**)(widget->children->elms); - - for (i = 0; i < nr; i++) { - widget_t* iter = children[i]; - widget_foreach(iter, visit, ctx); - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + widget_foreach(iter, visit, ctx); + WIDGET_FOR_EACH_CHILD_END() return RET_OK; } @@ -1125,17 +1087,12 @@ ret_t widget_destroy(widget_t* widget) { } static ret_t widget_set_dirty(widget_t* widget) { - int32_t i = 0; - int32_t n = 0; return_value_if_fail(widget != NULL, RET_BAD_PARAMS); widget->dirty = TRUE; - if (widget->children != NULL) { - for (i = 0, n = widget->children->size; i < n; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - widget_set_dirty(iter); - } - } + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + widget_set_dirty(iter); + WIDGET_FOR_EACH_CHILD_END(); return RET_OK; } diff --git a/src/base/widget_vtable.c b/src/base/widget_vtable.c index 7fbaf7440..acc99e7ab 100644 --- a/src/base/widget_vtable.c +++ b/src/base/widget_vtable.c @@ -59,33 +59,28 @@ ret_t widget_on_paint_self_default(widget_t* widget, canvas_t* c) { } ret_t widget_on_paint_children_default(widget_t* widget, canvas_t* c) { - uint32_t i = 0; - uint32_t nr = 0; return_value_if_fail(widget != NULL && c != NULL, RET_BAD_PARAMS); - if (widget->children != NULL) { - for (i = 0, nr = widget->children->size; i < nr; i++) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - int32_t left = c->ox + iter->x; - int32_t top = c->oy + iter->y; - int32_t bottom = top + iter->h; - int32_t right = left + iter->w; + WIDGET_FOR_EACH_CHILD_BEGIN(widget, iter, i) + int32_t left = c->ox + iter->x; + int32_t top = c->oy + iter->y; + int32_t bottom = top + iter->h; + int32_t right = left + iter->w; - if (!iter->visible) { - iter->dirty = FALSE; - continue; - } - - if (left > c->clip_right || right < c->clip_left || top > c->clip_bottom || - bottom < c->clip_top) { - iter->dirty = FALSE; - continue; - } - - widget_paint(iter, c); - } + if (!iter->visible) { + iter->dirty = FALSE; + continue; } + if (left > c->clip_right || right < c->clip_left || top > c->clip_bottom || + bottom < c->clip_top) { + iter->dirty = FALSE; + continue; + } + + widget_paint(iter, c); + WIDGET_FOR_EACH_CHILD_END(); + return RET_OK; } @@ -180,26 +175,20 @@ static ret_t point_to_local(widget_t* widget, point_t* p) { return RET_OK; } widget_t* widget_find_target_default(widget_t* widget, xy_t x, xy_t y) { - uint32_t i = 0; - uint32_t n = 0; point_t p = {x, y}; return_value_if_fail(widget != NULL, NULL); point_to_local(widget, &p); - if (widget->children != NULL && widget->children->size > 0) { - xy_t xx = p.x; - xy_t yy = p.y; - n = widget->children->size; - for (i = n; i > 0; i--) { - widget_t* iter = (widget_t*)(widget->children->elms[i - 1]); - xy_t r = iter->x + iter->w; - xy_t b = iter->y + iter->h; + WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i) + xy_t xx = p.x; + xy_t yy = p.y; + xy_t r = iter->x + iter->w; + xy_t b = iter->y + iter->h; - if (iter->enable && xx >= iter->x && yy >= iter->y && xx <= r && yy <= b) { - return iter; - } - } + if (iter->enable && xx >= iter->x && yy >= iter->y && xx <= r && yy <= b) { + return iter; } + WIDGET_FOR_EACH_CHILD_END(); return NULL; } diff --git a/src/base/window_manager.c b/src/base/window_manager.c index a75826f4b..e6cb72667 100644 --- a/src/base/window_manager.c +++ b/src/base/window_manager.c @@ -159,17 +159,6 @@ static ret_t window_manager_idle_destroy_window(const idle_info_t* info) { return RET_OK; } -static int compare_win(void* a, void* b) { - widget_t* win = WIDGET(b); - widget_t* widget = WIDGET(a); - - if (widget_get_window(widget) == win) { - return 0; - } else { - return 1; - } -} - ret_t window_manager_close_window(widget_t* widget, widget_t* window) { ret_t ret = RET_OK; window_manager_t* wm = WINDOW_MANAGER(widget); @@ -182,7 +171,11 @@ ret_t window_manager_close_window(widget_t* widget, widget_t* window) { if (widget->key_target == window) { widget->key_target = NULL; } - array_remove_all(&(wm->grab_widgets), compare_win, window, NULL); + if (wm->grab_widget != NULL) { + if (widget_get_window(wm->grab_widget) == window) { + wm->grab_widget = NULL; + } + } if (wm->animator) { wm->pending_close_window = window; @@ -199,38 +192,30 @@ ret_t window_manager_close_window(widget_t* widget, widget_t* window) { } widget_t* window_manager_find_target(widget_t* widget, xy_t x, xy_t y) { - uint32_t i = 0; - uint32_t n = 0; point_t p = {x, y}; window_manager_t* wm = WINDOW_MANAGER(widget); return_value_if_fail(widget != NULL, NULL); - if (wm->grab_widgets.size > 0) { - widget_t* target = WIDGET(wm->grab_widgets.elms[wm->grab_widgets.size - 1]); + if (wm->grab_widget != NULL) { + widget_t* target = wm->grab_widget; /*log_debug("target=%s\n", target->vt->type_name);*/ return target; } widget_to_local(widget, &p); - if (widget->children != NULL && widget->children->size > 0) { - xy_t xx = p.x; - xy_t yy = p.y; - n = widget->children->size; - for (i = n; i > 0; i--) { - widget_t* iter = (widget_t*)(widget->children->elms[i - 1]); - xy_t r = iter->x + iter->w; - xy_t b = iter->y + iter->h; + WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i) + xy_t r = iter->x + iter->w; + xy_t b = iter->y + iter->h; - if (xx >= iter->x && yy >= iter->y && xx <= r && yy <= b) { - return iter; - } - - if (iter->type == WIDGET_NORMAL_WINDOW || iter->type == WIDGET_DIALOG) { - return iter; - } - } + if (p.x >= iter->x && p.y >= iter->y && p.x <= r && p.y <= b) { + return iter; } + if (iter->type == WIDGET_NORMAL_WINDOW || iter->type == WIDGET_DIALOG) { + return iter; + } + WIDGET_FOR_EACH_CHILD_END() + return NULL; } @@ -371,16 +356,21 @@ static ret_t window_manager_grab(widget_t* widget, widget_t* child) { window_manager_t* wm = WINDOW_MANAGER(widget); return_value_if_fail(widget != NULL && child != NULL, RET_BAD_PARAMS); - log_debug("grab: %s\n", child->vt->type_name); - return array_push(&(wm->grab_widgets), child); + wm->grab_widget = child; + + return RET_OK; } static ret_t window_manager_ungrab(widget_t* widget, widget_t* child) { window_manager_t* wm = WINDOW_MANAGER(widget); return_value_if_fail(widget != NULL && child != NULL, RET_BAD_PARAMS); - log_debug("ungrab: %s\n", child->vt->type_name); - return array_remove_all(&(wm->grab_widgets), NULL, child, NULL); + if (wm->grab_widget == child) { + wm->grab_widget = NULL; + log_debug("ungrab: %s\n", child->vt->type_name); + } + + return RET_OK; } static ret_t window_manager_invalidate(widget_t* widget, rect_t* r) { @@ -393,19 +383,13 @@ static ret_t window_manager_invalidate(widget_t* widget, rect_t* r) { } int32_t window_manager_find_top_window_index(widget_t* widget) { - int32_t i = 0; - int32_t nr = 0; return_value_if_fail(widget != NULL, -1); - if (widget->children != NULL && widget->children->size > 0) { - nr = widget->children->size; - for (i = nr - 1; i >= 0; i--) { - widget_t* iter = (widget_t*)(widget->children->elms[i]); - if (iter->type == WIDGET_NORMAL_WINDOW) { - return i; - } - } + WIDGET_FOR_EACH_CHILD_BEGIN_R(widget, iter, i) + if (iter->type == WIDGET_NORMAL_WINDOW) { + return i; } + WIDGET_FOR_EACH_CHILD_END(); return -1; } @@ -476,7 +460,6 @@ widget_t* window_manager_init(window_manager_t* wm) { w->vt = &s_wm_vtable; widget_init(w, NULL, WIDGET_WINDOW_MANAGER); - array_init(&(wm->grab_widgets), 5); #ifdef WITH_DYNAMIC_TR locale_on(locale(), EVT_LOCALE_CHANGED, wm_on_locale_changed, wm); diff --git a/src/base/window_manager.h b/src/base/window_manager.h index 5878f7512..7dec226e7 100644 --- a/src/base/window_manager.h +++ b/src/base/window_manager.h @@ -36,7 +36,7 @@ BEGIN_C_DECLS typedef struct _window_manager_t { widget_t widget; - array_t grab_widgets; + widget_t* grab_widget; rect_t dirty_rect; rect_t last_dirty_rect; diff --git a/tests/widget_test.cc b/tests/widget_test.cc index 0a99f3aea..c2bb18456 100644 --- a/tests/widget_test.cc +++ b/tests/widget_test.cc @@ -287,3 +287,15 @@ TEST(Widget, prop) { widget_destroy(w); } + +TEST(Widget, dirty) { + widget_t* w = window_create(NULL, 0, 0, 400, 300); + widget_t* b1 = button_create(w, 0, 0, 100, 100); + widget_invalidate(w, NULL); + ASSERT_EQ(w->dirty, TRUE); + ASSERT_EQ(b1->dirty, TRUE); + widget_destroy_children(w); + ASSERT_EQ(w->children->size, 0); + + widget_destroy(w); +}