From 336500469ae2b2d2d4655cf5361d13612b8874b3 Mon Sep 17 00:00:00 2001 From: Yeongjong Lee Date: Wed, 24 Apr 2019 20:23:52 +0900 Subject: [PATCH] ui.relative_layout: add internal clipper Summary: If there is no clipper of container, color_set and clipper_set api won't work. Test Plan: 1. elementary_test -to 'efl.ui.relative_layout' 2. Click button1 3. check that buttons color are changed. Reviewers: Jaehyun_Cho Reviewed By: Jaehyun_Cho Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8625 --- src/bin/elementary/test_ui_relative_layout.c | 16 +++ src/lib/elementary/efl_ui_relative_layout.c | 117 +++++++++++------- .../efl_ui_relative_layout_private.h | 2 + 3 files changed, 87 insertions(+), 48 deletions(-) diff --git a/src/bin/elementary/test_ui_relative_layout.c b/src/bin/elementary/test_ui_relative_layout.c index e6481ec97e..dbb1647eee 100644 --- a/src/bin/elementary/test_ui_relative_layout.c +++ b/src/bin/elementary/test_ui_relative_layout.c @@ -15,6 +15,21 @@ typedef enum { BOTTOM } Options; +static void +_btn_color_clicked_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *layout = data; + + static Eina_Bool changed = EINA_TRUE; + + if (changed) + efl_gfx_color_set(layout, 0, 88, 204, 255); + else + efl_gfx_color_set(layout, 255, 255, 255, 255); + + changed = !changed; +} + static void _btn_clicked_to_cb(void *data, const Efl_Event *event) { @@ -297,6 +312,7 @@ test_ui_relative_layout(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, vo btn1 = efl_add(EFL_UI_BUTTON_CLASS, layout, efl_text_set(efl_added, "button1"), efl_gfx_hint_align_set(efl_added, 0.0, 0.0), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_color_clicked_cb, layout), efl_ui_relative_layout_relation_right_set(layout, efl_added, layout, 0.0), efl_ui_relative_layout_relation_bottom_set(layout, efl_added, layout, 0.0)); diff --git a/src/lib/elementary/efl_ui_relative_layout.c b/src/lib/elementary/efl_ui_relative_layout.c index 66bedb87ef..17bf97d8b5 100644 --- a/src/lib/elementary/efl_ui_relative_layout.c +++ b/src/lib/elementary/efl_ui_relative_layout.c @@ -29,6 +29,9 @@ _efl_ui_relative_layout_register(Efl_Ui_Relative_Layout_Data *pd, Eo *child) { Efl_Ui_Relative_Layout_Child *rc; + if (!efl_ui_widget_sub_object_add(pd->obj, child)) + return NULL; + rc = calloc(1, sizeof(Efl_Ui_Relative_Layout_Child)); if (!rc) return NULL; @@ -43,19 +46,10 @@ _efl_ui_relative_layout_register(Efl_Ui_Relative_Layout_Data *pd, Eo *child) rc->rel[BOTTOM].to = rc->layout; rc->rel[BOTTOM].relative = 1.0; - if (pd->obj == child) - { - rc->calc.state[0] = RELATIVE_CALC_DONE; - rc->calc.state[1] = RELATIVE_CALC_DONE; - rc->calc.chain_state[0] = RELATIVE_CALC_DONE; - rc->calc.chain_state[1] = RELATIVE_CALC_DONE; - } - else - { - efl_ui_widget_sub_object_add(pd->obj, child); - efl_canvas_group_member_add(pd->obj, child); - efl_canvas_group_change(pd->obj); - } + efl_key_data_set(child, "_elm_leaveme", pd->obj); + efl_canvas_object_clipper_set(child, pd->clipper); + efl_canvas_group_member_add(pd->obj, child); + efl_canvas_group_change(pd->obj); eina_hash_add(pd->children, &child, rc); @@ -75,13 +69,19 @@ _relative_child_get(Efl_Ui_Relative_Layout_Data *pd, Eo *child) } static Efl_Ui_Relative_Layout_Child * -_relative_child_find(const Eina_Hash *children, Eo *target) +_relative_child_find(Efl_Ui_Relative_Layout_Data *pd, Eo *target) { Efl_Ui_Relative_Layout_Child *child; - child = eina_hash_find(children, &target); + if (pd->obj == target) + return pd->base; + + child = eina_hash_find(pd->children, &target); if (!child) - ERR("target(%p(%s)) is not registered", target, efl_class_name_get(target)); + { + ERR("target(%p(%s)) is not registered", target, efl_class_name_get(target)); + child = pd->base; + } return child; } @@ -353,9 +353,6 @@ _hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key E Efl_Ui_Relative_Layout_Child *child = data; Eina_Rect want; - if (child->obj == child->layout) - return EINA_TRUE; - _child_calc(child, 0); _child_calc(child, 1); @@ -370,35 +367,18 @@ _hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key E static Eina_Bool -_hash_child_init_foreach_cb(const Eina_Hash *hash, const void *key EINA_UNUSED, - void *data, void *fdata EINA_UNUSED) +_hash_child_init_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, + void *data, void *fdata) { Eina_Size2D max, min, aspect; Efl_Ui_Relative_Layout_Child *child = data; Efl_Ui_Relative_Layout_Calc *calc = &(child->calc); + Efl_Ui_Relative_Layout_Data *pd = fdata; - calc->to[LEFT] = _relative_child_find(hash, child->rel[LEFT].to); - if (!calc->to[LEFT]) calc->to[LEFT] = eina_hash_find(hash, &child->layout); - calc->to[RIGHT] = _relative_child_find(hash, child->rel[RIGHT].to); - if (!calc->to[RIGHT]) calc->to[RIGHT] = eina_hash_find(hash, &child->layout); - calc->to[TOP] = _relative_child_find(hash, child->rel[TOP].to); - if (!calc->to[TOP]) calc->to[TOP] = eina_hash_find(hash, &child->layout); - calc->to[BOTTOM] = _relative_child_find(hash, child->rel[BOTTOM].to); - if (!calc->to[BOTTOM]) calc->to[BOTTOM] = eina_hash_find(hash, &child->layout); - - if (child->obj == child->layout) - { - Eina_Rect want = efl_gfx_entity_geometry_get(child->obj); - calc->want[0].position = want.x; - calc->want[0].length = want.w; - calc->want[1].position = want.y; - calc->want[1].length = want.h; - calc->state[0] = RELATIVE_CALC_DONE; - calc->state[1] = RELATIVE_CALC_DONE; - calc->chain_state[0] = RELATIVE_CALC_DONE; - calc->chain_state[1] = RELATIVE_CALC_DONE; - return EINA_TRUE; - } + calc->to[LEFT] = _relative_child_find(pd, child->rel[LEFT].to); + calc->to[RIGHT] = _relative_child_find(pd, child->rel[RIGHT].to); + calc->to[TOP] = _relative_child_find(pd, child->rel[TOP].to); + calc->to[BOTTOM] = _relative_child_find(pd, child->rel[BOTTOM].to); calc->state[0] = RELATIVE_CALC_NONE; calc->state[1] = RELATIVE_CALC_NONE; @@ -454,7 +434,13 @@ _efl_ui_relative_layout_hints_changed_cb(void *data EINA_UNUSED, const Efl_Event EOLIAN static void _efl_ui_relative_layout_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) { - eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, NULL); + Eina_Rect want = efl_gfx_entity_geometry_get(obj); + pd->base->calc.want[0].position = want.x; + pd->base->calc.want[0].length = want.w; + pd->base->calc.want[1].position = want.y; + pd->base->calc.want[1].length = want.h; + + eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, pd); eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, NULL); efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); @@ -489,6 +475,12 @@ _efl_ui_relative_layout_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Relative_Lay EOLIAN static void _efl_ui_relative_layout_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED) { + pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS, obj); + evas_object_static_clip_set(pd->clipper, EINA_TRUE); + efl_gfx_entity_geometry_set(pd->clipper, EINA_RECT(-49999, -49999, 99999, 99999)); + efl_canvas_group_member_add(obj, pd->clipper); + efl_ui_widget_sub_object_add(obj, pd->clipper); + efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _efl_ui_relative_layout_hints_changed_cb, NULL); efl_canvas_group_add(efl_super(obj, MY_CLASS)); @@ -506,7 +498,24 @@ _efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_D pd->obj = obj; pd->children = eina_hash_pointer_new(_hash_free_cb); - _efl_ui_relative_layout_register(pd, obj); + + pd->base = calloc(1, sizeof(Efl_Ui_Relative_Layout_Child)); + if (!pd->base) return NULL; + + pd->base->obj = obj; + pd->base->layout = obj; + pd->base->rel[LEFT].to = obj; + pd->base->rel[LEFT].relative = 0.0; + pd->base->rel[RIGHT].to = obj; + pd->base->rel[RIGHT].relative = 1.0; + pd->base->rel[TOP].to = obj; + pd->base->rel[TOP].relative = 0.0; + pd->base->rel[BOTTOM].to = obj; + pd->base->rel[BOTTOM].relative = 1.0; + pd->base->calc.state[0] = RELATIVE_CALC_DONE; + pd->base->calc.state[1] = RELATIVE_CALC_DONE; + pd->base->calc.chain_state[0] = RELATIVE_CALC_DONE; + pd->base->calc.chain_state[1] = RELATIVE_CALC_DONE; return obj; } @@ -517,6 +526,7 @@ _efl_ui_relative_layout_efl_object_destructor(Eo *obj, Efl_Ui_Relative_Layout_Da efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _efl_ui_relative_layout_hints_changed_cb, NULL); eina_hash_free(pd->children); + if (pd->base) free(pd->base); efl_destructor(efl_super(obj, MY_CLASS)); } @@ -524,14 +534,25 @@ EOLIAN static void _efl_ui_relative_layout_unregister(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Efl_Object *child) { _elm_widget_sub_object_redirect_to_top(obj, child); - if (!eina_hash_del_by_key(pd->children, &child)) - ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); + if (eina_hash_del_by_key(pd->children, &child)) + { + efl_canvas_group_member_remove(obj, child); + efl_canvas_object_clipper_set(child, NULL); + efl_key_data_set(child, "_elm_leaveme", NULL); + + efl_pack_layout_request(obj); + } + else + { + ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); + } } EOLIAN static void -_efl_ui_relative_layout_unregister_all(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd) +_efl_ui_relative_layout_unregister_all(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) { eina_hash_foreach(pd->children, _hash_free_foreach_cb, NULL); + efl_pack_layout_request(obj); } EOLIAN static Eina_Iterator * diff --git a/src/lib/elementary/efl_ui_relative_layout_private.h b/src/lib/elementary/efl_ui_relative_layout_private.h index b7410efc49..c58f7b0ecc 100644 --- a/src/lib/elementary/efl_ui_relative_layout_private.h +++ b/src/lib/elementary/efl_ui_relative_layout_private.h @@ -49,7 +49,9 @@ struct _Efl_Ui_Relative_Layout_Calc struct _Efl_Ui_Relative_Layout_Data { Eo *obj; + Eo *clipper; Eina_Hash *children; + Efl_Ui_Relative_Layout_Child *base; }; struct _Efl_Ui_Relative_Layout_Relation