From 842e6e9c67a65b7193190a91511912e895a04b58 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 28 Nov 2019 17:13:07 +0100 Subject: [PATCH] efl_ui_spotlight_container: bring in min / max handling the spotlight now is setting the overall correct min and max size on itself. Additionally, the page size is now clamped to the size of the container. Correct min size of the container is defined to the MAX min size of all the content. The correct max size of the container is defined to the MIN max size of all the content. ref T7991 Differential Revision: https://phab.enlightenment.org/D10766 --- src/bin/elementary/test_ui_spotlight.c | 1 + .../elementary/efl_ui_spotlight_container.c | 89 ++++++++++++++++--- .../elementary/efl_ui_spotlight_container.eo | 1 + .../efl_ui_spotlight_indicator_icon.c | 1 + src/tests/elementary/efl_ui_test_spotlight.c | 42 +++++++++ 5 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/bin/elementary/test_ui_spotlight.c b/src/bin/elementary/test_ui_spotlight.c index 48736fe7db..281b55e510 100644 --- a/src/bin/elementary/test_ui_spotlight.c +++ b/src/bin/elementary/test_ui_spotlight.c @@ -92,6 +92,7 @@ view_add(View_Type p, Eo *parent) snprintf(buf, sizeof(buf), "List Page - Item #%d", i); elm_list_item_append(page, buf, NULL, NULL, NULL, NULL); } + efl_gfx_hint_size_min_set(page, EINA_SIZE2D(200, 200)); evas_object_size_hint_weight_set(page, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(page, EVAS_HINT_FILL, diff --git a/src/lib/elementary/efl_ui_spotlight_container.c b/src/lib/elementary/efl_ui_spotlight_container.c index b812501d6b..8f38012f0d 100644 --- a/src/lib/elementary/efl_ui_spotlight_container.c +++ b/src/lib/elementary/efl_ui_spotlight_container.c @@ -29,6 +29,7 @@ typedef struct _Efl_Ui_Spotlight_Container_Data } transition_done; Efl_Ui_Spotlight_Manager *transition; Efl_Ui_Spotlight_Indicator *indicator; + Eina_Size2D min, max; double position; Eina_Bool fill_width: 1; Eina_Bool fill_height: 1; @@ -157,27 +158,32 @@ _transition_event_emission(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Container_Data } static void -_resize_cb(void *data, const Efl_Event *ev) +_emit_page_size(Efl_Ui_Spotlight_Container *obj, Efl_Ui_Spotlight_Container_Data *pd) { - Efl_Ui_Spotlight_Container_Data *pd = data; Eina_Size2D sz; - sz = efl_gfx_entity_size_get(ev->object); + sz = efl_gfx_entity_size_get(obj); - if (pd->fill_width) pd->page_spec.sz.w = sz.w; - if (pd->fill_height) pd->page_spec.sz.h = sz.h; + if (!pd->fill_width) + sz.w = MIN(pd->page_spec.sz.w, sz.w); + + if (!pd->fill_height) + sz.h = MIN(pd->page_spec.sz.h, sz.h); if (pd->transition) - efl_ui_spotlight_manager_size_set(pd->transition, pd->page_spec.sz); + efl_ui_spotlight_manager_size_set(pd->transition, sz); +} + +static void +_resize_cb(void *data, const Efl_Event *ev) +{ + _emit_page_size(ev->object, data); } static void _position_cb(void *data, const Efl_Event *ev EINA_UNUSED) { - Efl_Ui_Spotlight_Container_Data *pd = data; - - if (pd->transition) - efl_ui_spotlight_manager_size_set(pd->transition, pd->page_spec.sz); + _emit_page_size(ev->object, data); } EFL_CALLBACKS_ARRAY_DEFINE(spotlight_resized, @@ -193,6 +199,7 @@ _efl_ui_spotlight_container_efl_object_constructor(Eo *obj, obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->max = EINA_SIZE2D(INT_MAX, INT_MAX); pd->animation_enabled = EINA_TRUE; pd->position = -1; pd->curr.page = NULL; @@ -263,9 +270,41 @@ _child_inv(void *data, const Efl_Event *ev) _unpack(data, pd, ev->object, index); } +#define ADJUST_PRIVATE_MIN_MAX(obj, subobj, pd) \ + do \ + { \ + min = efl_gfx_hint_size_combined_min_get(subobj); \ + max = efl_gfx_hint_size_combined_max_get(subobj); \ + pd->min.w = MAX(pd->min.w, min.w); \ + pd->min.h = MAX(pd->min.h, min.h); \ + pd->max.w = MIN(pd->max.w, max.w); \ + pd->max.h = MIN(pd->max.h, max.h); \ + } \ + while(0) + +#define FLUSH_MIN_MAX(obj, pd) \ + do \ + { \ + efl_gfx_hint_size_restricted_min_set(obj, pd->min); \ + efl_gfx_hint_size_restricted_max_set(obj, pd->max); \ + } \ + while(0) + +static void +_hints_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + efl_canvas_group_change(data); +} + +EFL_CALLBACKS_ARRAY_DEFINE(children_evt, + {EFL_EVENT_INVALIDATE, _child_inv}, + {EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _hints_changed_cb} +) + static Eina_Bool _register_child(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Container_Data *pd, Efl_Gfx_Entity *subobj) { + Eina_Size2D min, max; EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE); if (eina_list_data_find(pd->content_list, subobj)) { @@ -275,7 +314,10 @@ _register_child(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Container_Data *pd, Efl_Gf if (!efl_ui_widget_sub_object_add(obj, subobj)) return EINA_FALSE; - efl_event_callback_add(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj); + efl_event_callback_array_add(subobj, children_evt(), obj); + + ADJUST_PRIVATE_MIN_MAX(obj, subobj, pd); + FLUSH_MIN_MAX(obj, pd); return EINA_TRUE; } @@ -543,7 +585,8 @@ _unpack(Eo *obj, pd->indicator && !pd->transition) efl_ui_spotlight_indicator_position_update(pd->indicator, efl_pack_index_get(obj, pd->curr.page)); - efl_event_callback_del(subobj, EFL_EVENT_INVALIDATE, _child_inv, obj); + efl_event_callback_array_del(subobj, children_evt(), obj); + efl_canvas_group_change(obj); } EOLIAN static Eina_Bool @@ -755,6 +798,28 @@ _efl_ui_spotlight_container_animated_transition_get(const Eo *obj EINA_UNUSED, E return pd->animation_enabled; } +EOLIAN static void +_efl_ui_spotlight_container_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Container_Data *pd) +{ + Efl_Ui_Widget *content; + Eina_List *n; + + efl_canvas_group_calculate(efl_super(obj, MY_CLASS)); + + pd->min = EINA_SIZE2D(0,0); + pd->max = EINA_SIZE2D(INT_MAX, INT_MAX); + + EINA_LIST_FOREACH(pd->content_list, n, content) + { + Eina_Size2D min, max; + + min = efl_gfx_hint_size_combined_min_get(content); + max = efl_gfx_hint_size_combined_max_get(content); + + ADJUST_PRIVATE_MIN_MAX(obj, content, pd); + } + FLUSH_MIN_MAX(obj, pd); +} #include "efl_ui_spotlight_container.eo.c" diff --git a/src/lib/elementary/efl_ui_spotlight_container.eo b/src/lib/elementary/efl_ui_spotlight_container.eo index 2f462f50d4..766063c8f3 100644 --- a/src/lib/elementary/efl_ui_spotlight_container.eo +++ b/src/lib/elementary/efl_ui_spotlight_container.eo @@ -131,5 +131,6 @@ class @beta Efl.Ui.Spotlight.Container extends Efl.Ui.Widget implements Efl.Pack Efl.Pack_Linear.pack_content_get; Efl.Pack_Linear.pack_index_get; Efl.Pack_Linear.pack_unpack_at; + Efl.Canvas.Group.group_calculate; } } diff --git a/src/lib/elementary/efl_ui_spotlight_indicator_icon.c b/src/lib/elementary/efl_ui_spotlight_indicator_icon.c index 5f59b513cd..4ac177580d 100644 --- a/src/lib/elementary/efl_ui_spotlight_indicator_icon.c +++ b/src/lib/elementary/efl_ui_spotlight_indicator_icon.c @@ -12,6 +12,7 @@ typedef struct { Efl_Ui_Spotlight_Container *container; Efl_Canvas_Layout *layout; double last_position; + Eina_Size2D min, max; } Efl_Ui_Spotlight_Indicator_Icon_Data; static void diff --git a/src/tests/elementary/efl_ui_test_spotlight.c b/src/tests/elementary/efl_ui_test_spotlight.c index c7fd2d7d2b..8262217779 100644 --- a/src/tests/elementary/efl_ui_test_spotlight.c +++ b/src/tests/elementary/efl_ui_test_spotlight.c @@ -648,6 +648,47 @@ EFL_START_TEST (efl_ui_spotlight_animated_transition) } EFL_END_TEST +EFL_START_TEST (efl_ui_spotlight_min_max_sizing) +{ + Efl_Ui_Button *btn0, *btn1; + Eina_Size2D min, size; + + btn0 = efl_add(WIDGET_CLASS, container); + efl_gfx_hint_size_min_set(btn0, EINA_SIZE2D(20, 200)); + + btn1 = efl_add(WIDGET_CLASS, container); + efl_gfx_hint_size_min_set(btn1, EINA_SIZE2D(200, 20)); + + efl_pack_end(container, btn0); + efl_pack_end(container, btn1); + min = efl_gfx_hint_size_restricted_min_get(container); + ck_assert_int_eq(min.w, 200); + ck_assert_int_eq(min.h, 200); + + efl_gfx_hint_size_min_set(btn0, EINA_SIZE2D(20, 300)); + efl_canvas_group_calculate(container); + + min = efl_gfx_hint_size_restricted_min_get(container); + ck_assert_int_eq(min.w, 200); + ck_assert_int_eq(min.h, 300); + + efl_gfx_hint_size_min_set(btn0, EINA_SIZE2D(20, 20)); + efl_canvas_group_calculate(container); + + min = efl_gfx_hint_size_restricted_min_get(container); + ck_assert_int_eq(min.w, 200); + ck_assert_int_eq(min.h, 20); + + efl_ui_spotlight_size_set(container, EINA_SIZE2D(2000, 2000)); + + efl_gfx_entity_size_set(container, EINA_SIZE2D(200, 200)); + size = efl_gfx_entity_size_get(btn0); + ck_assert_int_eq(size.w, 200); + ck_assert_int_eq(size.h, 200); + +} +EFL_END_TEST + static void spotlight_setup() { @@ -684,4 +725,5 @@ void efl_ui_test_spotlight(TCase *tc) tcase_add_test(tc, efl_ui_spotlight_test_pop2); tcase_add_test(tc, efl_ui_spotlight_test_pop3); tcase_add_test(tc, efl_ui_spotlight_animated_transition); + tcase_add_test(tc, efl_ui_spotlight_min_max_sizing); }