From 42baac2b0b9676da84cc5105cfbe774db45d2094 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 30 Nov 2017 15:04:50 +0900 Subject: __WIP__ --- src/Makefile_Elementary.am | 6 +- src/bin/elementary/test.c | 2 + src/bin/elementary/test_toolbar.c | 125 +- src/lib/ecore/efl_model_item.c | 2 +- src/lib/ecore/efl_promise.c | 7 +- src/lib/elementary/Elementary.h | 5 + src/lib/elementary/efl_ui_item.c | 352 ++++++ src/lib/elementary/efl_ui_item.eo | 51 + src/lib/elementary/efl_ui_item_list.c | 229 ++++ src/lib/elementary/efl_ui_item_list.eo | 26 + src/lib/elementary/efl_ui_toolbar.c | 1676 ++------------------------- src/lib/elementary/efl_ui_toolbar.eo | 182 +-- src/lib/elementary/efl_ui_toolbar_item.eo | 85 +- src/lib/elementary/efl_ui_toolbar_private.h | 73 -- 14 files changed, 834 insertions(+), 1987 deletions(-) create mode 100644 src/lib/elementary/efl_ui_item.c create mode 100644 src/lib/elementary/efl_ui_item.eo create mode 100644 src/lib/elementary/efl_ui_item_list.c create mode 100644 src/lib/elementary/efl_ui_item_list.eo delete mode 100644 src/lib/elementary/efl_ui_toolbar_private.h diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 2d89ee9016..3cb5c9bae3 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -72,6 +72,8 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_progressbar_part.eo \ lib/elementary/efl_ui_slider_part.eo \ lib/elementary/efl_ui_textpath_part.eo \ + lib/elementary/efl_ui_item.eo \ + lib/elementary/efl_ui_item_list.eo \ lib/elementary/efl_ui_toolbar.eo \ lib/elementary/efl_ui_toolbar_item.eo \ lib/elementary/efl_ui_widget_part.eo \ @@ -336,7 +338,6 @@ includesunstable_HEADERS = \ lib/elementary/elm_widget_table.h \ lib/elementary/elm_widget_thumb.h \ lib/elementary/elm_widget_toolbar.h \ - lib/elementary/efl_ui_toolbar_private.h \ lib/elementary/efl_ui_video_private.h \ lib/elementary/elm_widget_web.h \ lib/elementary/efl_ui_clock.h \ @@ -693,6 +694,9 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/elm_theme.c \ lib/elementary/elm_thumb.c \ lib/elementary/elm_toolbar.c \ + lib/elementary/efl_ui_item.c \ + lib/elementary/efl_ui_item_priv.h \ + lib/elementary/efl_ui_item_list.c \ lib/elementary/efl_ui_toolbar.c \ lib/elementary/elm_transit.c \ lib/elementary/elm_util.c \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index ae1967d996..ae2ceadc26 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -90,6 +90,7 @@ void test_toolbar8(void *data, Evas_Object *obj, void *event_info); void test_toolbar_vertical(void *data, Evas_Object *obj, void *event_info); void test_toolbar_focus(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_toolbar(void *data, Evas_Object *obj, void *event_info); +void test_efl_ui_toolbar_model(void *data, Evas_Object *obj, void *event_info); void test_hoversel(void *data, Evas_Object *obj, void *event_info); void test_hoversel_focus(void *data, Evas_Object *obj, void *event_info); void test_list(void *data, Evas_Object *obj, void *event_info); @@ -898,6 +899,7 @@ add_tests: ADD_TEST(NULL, "Toolbars", "Toolbar Vertical", test_toolbar_vertical); ADD_TEST(NULL, "Toolbars", "Toolbar Focus", test_toolbar_focus); ADD_TEST_EO(NULL, "Toolbars", "Efl.Ui.Toolbar", test_efl_ui_toolbar); + ADD_TEST_EO(NULL, "Toolbars", "Efl.Ui.Toolbar Model", test_efl_ui_toolbar_model); //------------------------------// ADD_TEST(NULL, "Lists - List", "List", test_list); diff --git a/src/bin/elementary/test_toolbar.c b/src/bin/elementary/test_toolbar.c index 259bb9a50a..c8e4f4e588 100644 --- a/src/bin/elementary/test_toolbar.c +++ b/src/bin/elementary/test_toolbar.c @@ -1313,74 +1313,83 @@ test_toolbar_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e evas_object_show(win); } -static void -_toolbar_selected_cb(void *data EINA_UNUSED, const Efl_Event *ev) +void +test_efl_ui_toolbar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - //FIXME: after defining item interface, this should be changed. - Elm_Object_Item *item = efl_ui_menu_selected_item_get(ev->object); - const char *str = elm_object_item_text_get(item); - if (str) - printf(" string is \"%s\"\n", str); - else - printf("\n"); + Eo *win, *tb, *it; + + win = efl_add(EFL_UI_WIN_CLASS, NULL); + efl_ui_win_autodel_set(win, 1); + + tb = efl_add(EFL_UI_TOOLBAR_CLASS, win); + efl_content_set(win, tb); + + it = efl_ui_item_list_item_add(tb, "Hello", "file"); + it = efl_ui_item_list_item_add(tb, "World", "file"); + it = efl_ui_item_list_item_add(tb, "What's going on?", "file"); + it = efl_ui_item_list_item_add(tb, "Eh?", "file"); + + efl_gfx_size_set(win, EINA_SIZE2D(200, 200)); } -void -test_efl_ui_toolbar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +static Eina_Value _eina_value_helper = EINA_VALUE_EMPTY; + +#define _EINA_VALUE_HELPER_SET(name, typ, TYP) \ +static inline const Eina_Value * \ +_value_##name(typ v) \ +{ \ + if (!_eina_value_helper.type || \ + eina_value_type_get(&_eina_value_helper) != TYP) \ + { \ + eina_value_flush(&_eina_value_helper); \ + eina_value_setup(&_eina_value_helper, TYP); \ + } \ + eina_value_set(&_eina_value_helper, v); \ + return &_eina_value_helper; \ +} + +_EINA_VALUE_HELPER_SET(string, const char*, EINA_VALUE_TYPE_STRING) +//_EINA_VALUE_HELPER_SET(bool, Eina_Bool, EINA_VALUE_TYPE_UCHAR) + +static Efl_Model * +_model_create(void) { - Evas_Object *win, *bx, *tb, *grd; - Evas_Object *ph1, *ph2, *ph3, *ph4; - char buf[PATH_MAX]; + Efl_Model *model, *child; - win = efl_add(EFL_UI_WIN_CLASS, NULL, - efl_text_set(efl_added, "Efl Ui Toolbar"), - efl_ui_win_autodel_set(efl_added, EINA_TRUE)); + model = efl_add(EFL_MODEL_ITEM_CLASS, NULL); - bx = efl_add(EFL_UI_BOX_CLASS, win, - efl_content_set(win, efl_added)); + child = efl_model_child_add(model); + efl_model_property_set(child, "text", _value_string("Hello")); + efl_model_property_set(child, "icon", _value_string("file")); - tb = efl_add(EFL_UI_TOOLBAR_CLASS, win, - efl_pack(bx, efl_added), - efl_event_callback_add(efl_added, EFL_UI_EVENT_SELECTED, _toolbar_selected_cb, NULL), - efl_gfx_size_hint_weight_set(efl_added, 0.0, 0.0), - efl_gfx_size_hint_align_set(efl_added, -1.0, 0.0)); + child = efl_model_child_add(model); + efl_model_property_set(child, "text", _value_string("World!")); + efl_model_property_set(child, "icon", _value_string("user-desktop")); - snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", elm_app_data_dir_get()); - ph1 = efl_add(EFL_UI_IMAGE_CLASS, win, - efl_file_set(efl_added, buf, NULL), - efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(40, 40)), - efl_gfx_size_hint_align_set(efl_added, 0.5, 0.5)); + child = efl_model_child_add(model); + efl_model_property_set(child, "text", _value_string("What's going on?")); + efl_model_property_set(child, "icon", _value_string("user-bookmarks")); - ph2 = efl_add(EFL_UI_IMAGE_CLASS, win, - efl_file_set(efl_added, buf, NULL), - efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(80, 80)), - efl_gfx_size_hint_align_set(efl_added, 0.5, 0.5)); + child = efl_model_child_add(model); + efl_model_property_set(child, "text", _value_string("lol")); + efl_model_property_set(child, "icon", _value_string("user-home")); - snprintf(buf, sizeof(buf), "%s/images/sky_01.jpg", elm_app_data_dir_get()); - ph3 = efl_add(EFL_UI_IMAGE_CLASS, win, - efl_file_set(efl_added, buf, NULL), - efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(20, 20)), - efl_gfx_size_hint_align_set(efl_added, 0.5, 0.5)); + return model; +} - snprintf(buf, sizeof(buf), "%s/images/sky_02.jpg", elm_app_data_dir_get()); - ph4 = efl_add(EFL_UI_IMAGE_CLASS, win, - efl_file_set(efl_added, buf, NULL), - efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(60, 60)), - efl_gfx_size_hint_align_set(efl_added, 0.5, 0.5)); - - efl_ui_toolbar_item_append(tb, "document-print", "Hello", _tb_sel1_cb, ph1); - efl_ui_toolbar_item_append(tb, "folder-new", "World", _tb_sel2_cb, ph1); - efl_ui_toolbar_item_append(tb, "object-rotate-right", "H", _tb_sel3_cb, ph4); - efl_ui_toolbar_item_append(tb, "mail-send", "Comes", _tb_sel4_cb, ph4); - efl_ui_toolbar_item_append(tb, "clock", "Elementary", _tb_sel5_cb, ph4); - - grd = efl_add(EFL_UI_GRID_CLASS, win); - efl_pack_grid(grd, ph1, 0, 0, 1, 1); - efl_pack_grid(grd, ph2, 1, 0, 1, 1); - efl_pack_grid(grd, ph3, 0, 1, 1, 1); - efl_pack_grid(grd, ph4, 1, 1, 1, 1); - - efl_pack(bx, grd); - efl_gfx_size_set(win, EINA_SIZE2D(300, 300)); +void +test_efl_ui_toolbar_model(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eo *win, *tb; + + win = efl_add(EFL_UI_WIN_CLASS, NULL); + efl_ui_win_autodel_set(win, 1); + + tb = efl_add(EFL_UI_TOOLBAR_CLASS, win); + efl_content_set(win, tb); + + efl_ui_item_list_model_set(tb, _model_create()); + + efl_gfx_size_set(win, EINA_SIZE2D(200, 200)); } diff --git a/src/lib/ecore/efl_model_item.c b/src/lib/ecore/efl_model_item.c index b4e286fbb4..1f35fb0fd5 100644 --- a/src/lib/ecore/efl_model_item.c +++ b/src/lib/ecore/efl_model_item.c @@ -72,7 +72,7 @@ _efl_model_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Item_Data { Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get()); Efl_Future* future = efl_promise_future_get(promise); - Efl_Model_Property_Event evt; + Efl_Model_Property_Event evt = { NULL, NULL }; Eina_Stringshare *sshared = eina_stringshare_add(property); Eina_Value *p_v = eina_hash_find(sd->properties, sshared); diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c index f95e12940e..635f880fb8 100644 --- a/src/lib/ecore/efl_promise.c +++ b/src/lib/ecore/efl_promise.c @@ -825,8 +825,11 @@ _efl_promise_all_die(void *data, const Efl_Event *ev EINA_UNUSED) while ((fa = eina_array_pop(&all->members))) { - EINA_REFCOUNT_UNREF(fa->d) - _efl_promise_msg_free(fa->d); + if (EINA_LIKELY(fa->d != NULL)) + { + EINA_REFCOUNT_UNREF(fa->d) + _efl_promise_msg_free(fa->d); + } assert(fa->f == NULL); free(fa); } diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 085d5bf3d6..aec49c2f9e 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -312,7 +312,12 @@ EAPI extern Elm_Version *elm_version; # include # include # include +#define _EFL_UI_ITEM_LIST_EO_CLASS_TYPE +typedef Eo Efl_Ui_Item_List; +# include +# include # include +# include #endif /* include deprecated calls last of all */ diff --git a/src/lib/elementary/efl_ui_item.c b/src/lib/elementary/efl_ui_item.c new file mode 100644 index 0000000000..55af66b118 --- /dev/null +++ b/src/lib/elementary/efl_ui_item.c @@ -0,0 +1,352 @@ +#include "efl_ui_item_priv.h" + +#define MY_CLASS EFL_UI_ITEM_CLASS + +typedef struct { + Efl_Ui_Item *self; + Efl_Ui_Item_List *parent; + Efl_Model *model; + + Eina_Stringshare *text, *icon; + Elm_Image *icon_obj; + + Eina_List *pending_futures; // Efl_Future** (wrefs) + + Eina_Bool model_owned : 1; + Eina_Bool selected : 1; +} Efl_Ui_Item_Data; + +typedef struct { + Efl_Ui_Item *object; + Eina_Array *properties; // stringshare +} Property_Update_Data; + +Eina_Value _eina_value_helper = EINA_VALUE_EMPTY; + +static inline Eina_Bool +_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool sel) +{ + if (pd->selected == sel) + return EINA_FALSE; + + pd->selected = sel; + if (efl_finalized_get(obj)) + { + if (sel) efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, NULL); + else efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, NULL); + } + return EINA_TRUE; +} + +EOLIAN static void +_efl_ui_item_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool sel) +{ + if (_selected_set(obj, pd, !!sel)) + efl_model_property_set(obj, "selected", _value_bool(sel)); +} + +EOLIAN static Eina_Bool +_efl_ui_item_selected_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd) +{ + return pd->selected; +} + +Efl_Ui_Item_List * +_efl_ui_item_item_list_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd) +{ + return pd->parent; +} + +static Eina_Bool +_text_set(Eo *obj, Efl_Ui_Item_Data *pd, const char *text) +{ + if (!eina_stringshare_replace(&pd->text, text)) + return EINA_FALSE; + + efl_text_set(efl_part(efl_ui_item_view_get(obj), "elm.text"), text); + return EINA_TRUE; +} + +EOLIAN static void +_efl_ui_item_efl_text_text_set(Eo *obj, Efl_Ui_Item_Data *pd, const char *text) +{ + if (!eina_streq(text, pd->text)) + efl_model_property_set(obj, "text", _value_string(text)); +} + +EOLIAN static const char * +_efl_ui_item_efl_text_text_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd) +{ + return pd->text; +} + +static Eina_Bool +_icon_set(Efl_Ui_Item_Data *pd, const char *icon) +{ + Eo *obj = pd->self; + + if (!eina_stringshare_replace(&pd->icon, icon)) + return EINA_FALSE; + + if (!icon) + { + ELM_SAFE_DEL(pd->icon_obj); + return EINA_TRUE; + } + + if (!pd->icon_obj || !eina_streq(efl_ui_image_icon_get(pd->icon_obj), icon)) + { + if (!pd->icon_obj) + { + Eo *view = efl_ui_item_view_get(obj); + pd->icon_obj = efl_add(EFL_UI_IMAGE_CLASS, view); + efl_content_set(efl_part(view, "elm.swallow.icon"), pd->icon_obj); + efl_wref_add(pd->icon_obj, &pd->icon_obj); + } + efl_ui_image_icon_set(pd->icon_obj, icon); + } + + return EINA_TRUE; +} + +EOLIAN static void +_efl_ui_item_icon_set(Eo *obj, Efl_Ui_Item_Data *pd, const char *icon) +{ + if (!eina_streq(icon, pd->icon)) + efl_model_property_set(obj, "icon", _value_string(icon)); +} + +EOLIAN static const char * +_efl_ui_item_icon_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd) +{ + return pd->icon; +} + +static void +_property_update_free(Property_Update_Data *update) +{ + Eina_Array_Iterator it; + Eina_Stringshare *prop; + size_t k; + + if (!update) return; + EINA_ARRAY_ITER_NEXT(update->properties, k, prop, it) + { + eina_stringshare_del(prop); + } + eina_array_free(update->properties); + free(update); +} + +#define EINA_VALUE_CHECK(_val, _type) \ + EINA_SAFETY_ON_FALSE_GOTO(eina_value_type_get(_val) == _type, end) + +static void +_pending_future_remove(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Efl_Future *future) +{ + Efl_Future **fut; + Eina_List *li; + + EINA_LIST_FOREACH(pd->pending_futures, li, fut) + if (*fut == future) + { + // WTF? where is the unuse function?? + pd->pending_futures = eina_list_remove_list(pd->pending_futures, li); + efl_wref_del(*fut, fut); + free(future); + break; + } +} + +static void +_properties_changed_success(void *data, const Efl_Event *event) +{ + Efl_Future_Event_Success *ev = event->info; + Property_Update_Data *update = data; + Eina_Accessor *prop_accessor = ev->value; + Efl_Ui_Item_Data *pd; + Efl_Ui_Item *obj; + Eina_Array_Iterator array_itr; + Eina_Stringshare *prop; + Eina_Value *val; + unsigned k; + + obj = update->object; + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_GOTO(pd, end); + + _pending_future_remove(obj, pd, event->object); + + EINA_ARRAY_ITER_NEXT(update->properties, k, prop, array_itr) + { + if (!eina_accessor_data_get(prop_accessor, k, (void **) &val) || !val) + { + ERR("Invalid response from model"); + break; + } + + if (eina_streq(prop, "selected")) + { + EINA_VALUE_CHECK(val, EINA_VALUE_TYPE_UCHAR); + _selected_set(obj, pd, _value_as_bool(val)); + } + else if (eina_streq(prop, "text")) + { + EINA_VALUE_CHECK(val, EINA_VALUE_TYPE_STRING); + _text_set(obj, pd, _value_as_string(val)); + } + else if (eina_streq(prop, "icon")) + { + EINA_VALUE_CHECK(val, EINA_VALUE_TYPE_STRING); + _icon_set(pd, _value_as_string(val)); + } + } + +end: + _property_update_free(update); +} + +static void +_properties_changed_error(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED) +{ + //Efl_Future_Event_Failure *ev = event->info; + Property_Update_Data *update = data; + Efl_Ui_Item_Data *pd; + Efl_Ui_Item *obj; + + obj = update->object; + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_GOTO(pd, end); + + _pending_future_remove(obj, pd, event->object); + +end: + ERR("Model error!"); + _property_update_free(update); + +} + +static void +_properties_update(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Array *properties) +{ + Property_Update_Data *update; + Efl_Future **futures, *all, **wfut; + Eina_Array_Iterator it; + const char *prop; + unsigned k, len; + + if (!properties) return; + len = eina_array_count(properties); + if (!len) return; + + futures = calloc(len + 1, sizeof(futures[0])); + update = calloc(1, sizeof(*update)); + update->object = obj; + update->properties = eina_array_new(len); + + EINA_ARRAY_ITER_NEXT(properties, k, prop, it) + { + Efl_Future *future = efl_model_property_get(obj, prop); + eina_array_push(update->properties, eina_stringshare_add(prop)); + futures[k] = future; + } + + all = efl_future_iterator_all(eina_carray_iterator_new((void **) futures)); + efl_future_then(all, _properties_changed_success, + _properties_changed_error, NULL, update); + free(futures); + + wfut = calloc(1, sizeof(*wfut)); + efl_future_use(wfut, all); + pd->pending_futures = eina_list_append(pd->pending_futures, wfut); +} + +static void +_properties_changed_cb(void *data, const Efl_Event *event) +{ + Efl_Model_Property_Event *ev = event->info; + //Efl_Model *model = event->object; + Efl_Ui_Item_Data *pd; + Efl_Ui_Item *obj = data; + Eina_Array_Iterator it; + const char *prop; + unsigned k; + + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_RETURN(pd); + + if (ev->invalidated_properties) + { + EINA_ARRAY_ITER_NEXT(ev->invalidated_properties, k, prop, it) + { + if (eina_streq(prop, "selected")) + _selected_set(obj, pd, EINA_FALSE); + else if (eina_streq(prop, "text")) + eina_stringshare_replace(&pd->text, NULL); + else if (eina_streq(prop, "icon")) + eina_stringshare_replace(&pd->icon, NULL); + } + } + + _properties_update(obj, pd, ev->changed_properties); +} + +EOLIAN static void +_efl_ui_item_model_set(Eo *obj, Efl_Ui_Item_Data *pd, Efl_Model *model) +{ + Eina_Array *properties; + Efl_Future **wfut; + + EINA_SAFETY_ON_NULL_RETURN(model); + if (pd->model == model) return; + + if (pd->model) + { + efl_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _properties_changed_cb, obj); + efl_composite_detach(obj, pd->model); + if (pd->model_owned) + efl_del(pd->model); + } + + EINA_LIST_FREE(pd->pending_futures, wfut) + { + efl_future_cancel(*wfut); + free(wfut); + } + + pd->model = model; + pd->model_owned = EINA_FALSE; + if (!model) return; + + efl_composite_attach(obj, pd->model); + efl_event_callback_add(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _properties_changed_cb, obj); + + properties = eina_array_new(8); + eina_array_push(properties, "text"); + eina_array_push(properties, "icon"); + eina_array_push(properties, "selected"); + _properties_update(obj, pd, properties); + eina_array_free(properties); +} + +EOLIAN static Efl_Model * +_efl_ui_item_model_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd) +{ + return pd->model; +} + +EOLIAN static Efl_Object * +_efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd) +{ + pd->self = obj; + obj = efl_constructor(efl_super(obj, MY_CLASS)); + + pd->model_owned = EINA_TRUE; + efl_ui_item_model_set(obj, efl_add(EFL_MODEL_ITEM_CLASS, obj)); + + return obj; +} + +#include "efl_ui_item.eo.c" diff --git a/src/lib/elementary/efl_ui_item.eo b/src/lib/elementary/efl_ui_item.eo new file mode 100644 index 0000000000..ffbc410dec --- /dev/null +++ b/src/lib/elementary/efl_ui_item.eo @@ -0,0 +1,51 @@ +class Efl.Ui.Item (Efl.Object, Efl.Model, Efl.Ui.Selectable, Efl.Text) +{ + [[A generic item for a list of items. + + Emits events from Efl.Ui.Selectable: + - Efl.Ui.Selectable.selected + - Efl.Ui.Selectable.unselected + ]] + methods { + @property item_list { + [[The parent item list.]] + get {} + values { + list: Efl.Ui.Item_List; [[The parent list.]] + } + } + @property item_view @protected { + get @pure_virtual {} + values { + obj: Efl.Ui.Layout; [[The real object.]] + } + } + @property icon { + [[The base icon name for this item. + + This is a standard icon name, as used in $Efl.Ui.Image. + ]] + get {} + set {} + values { + icon: string @nullable; [[An icon name.]] + } + } + @property selected { + get {} + set {} + values { + sel: bool(false); + } + } + @property model { + values { + model: Efl.Model; [[The internal model object.]] + } + } + } + implements { + Efl.Object.constructor; + Efl.Text.text { set; get; } + } +} diff --git a/src/lib/elementary/efl_ui_item_list.c b/src/lib/elementary/efl_ui_item_list.c new file mode 100644 index 0000000000..45d43adcfc --- /dev/null +++ b/src/lib/elementary/efl_ui_item_list.c @@ -0,0 +1,229 @@ +#include "efl_ui_item_priv.h" + +#define MY_CLASS EFL_UI_ITEM_LIST_CLASS + +typedef struct { + Eo *self; + Eina_List *items; /* Efl_Ui_Item* */ + Efl_Model *model; + + Eina_List *pending_futures; // Efl_Future** (wref) + + Eina_Bool model_owned : 1; +} Efl_Ui_Item_List_Data; + +static void +_item_del_cb(void *data, const Efl_Event *event) +{ + Efl_Ui_Item_List_Data *pd = efl_data_scope_safe_get(data, MY_CLASS); + if (!pd) return; + + pd->items = eina_list_remove(pd->items, event->object); +} + +EOLIAN static Efl_Ui_Item * +_efl_ui_item_list_item_add(Eo *obj, Efl_Ui_Item_List_Data *pd, + const char *text, const char *icon) +{ + const Efl_Class *klass; + Eo *item; + + klass = efl_ui_item_list_item_class_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(klass, NULL); + + item = efl_add(klass, obj, + efl_text_set(efl_added, text), + efl_ui_item_icon_set(efl_added, icon)); + pd->items = eina_list_append(pd->items, item); + efl_event_callback_add(item, EFL_EVENT_DEL, _item_del_cb, obj); + + return item; +} + +static void +_child_add_model(Eo *obj, Efl_Ui_Item_List_Data *pd, Efl_Model *model) +{ + const Efl_Class *klass; + Eo *item; + + klass = efl_ui_item_list_item_class_get(obj); + EINA_SAFETY_ON_NULL_RETURN(klass); + + item = efl_add(klass, obj, efl_ui_item_model_set(efl_added, model)); + pd->items = eina_list_append(pd->items, item); + efl_event_callback_add(item, EFL_EVENT_DEL, _item_del_cb, obj); +} + +static void +_pending_future_remove(Eo *obj EINA_UNUSED, Efl_Ui_Item_List_Data *pd, Efl_Future *future) +{ + Efl_Future **fut; + Eina_List *li; + + EINA_LIST_FOREACH(pd->pending_futures, li, fut) + if (*fut == future) + { + // WTF? where is the unuse function?? + pd->pending_futures = eina_list_remove_list(pd->pending_futures, li); + efl_wref_del(*fut, fut); + free(future); + break; + } +} + +static void +_child_added_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + Efl_Model_Children_Event *cevt = event->info; + Efl_Ui_Item_List_Data *pd; + Eo *obj = data; + + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_RETURN(pd); + + _pending_future_remove(obj, pd, event->object); + _child_add_model(obj, pd, cevt->child); +} + +static void +_child_removed_cb(void *data, const Efl_Event *event) +{ + Efl_Model_Children_Event *cevt = event->info; + Efl_Ui_Item_List_Data *pd; + Eina_List *li; + Eo *obj = data; + Eo *item, *model; + + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_RETURN(pd); + + INF("Child removed."); + + model = cevt->child; + _pending_future_remove(obj, pd, event->object); + + EINA_LIST_FOREACH(pd->items, li, item) + { + if (model == efl_ui_item_model_get(item)) + { + pd->items = eina_list_remove_list(pd->items, li); + efl_event_callback_add(item, EFL_EVENT_DEL, _item_del_cb, obj); + efl_del(item); + break; + } + } +} + +static void +_properties_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + Efl_Ui_Item_List_Data *pd; + Eo *obj = data; + + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_RETURN(pd); + + ERR("Model properties changed. Ignore."); +} + +static void +_children_slice_cb(void *data, const Efl_Event *event) +{ + Efl_Future_Event_Success *success = event->info; + Eina_Accessor *children = success->value; + Efl_Ui_Item_List_Data *pd; + Efl_Future **future; + Efl_Model *child; + Eina_List *li; + Eo *obj = data; + unsigned k; + + pd = efl_data_scope_safe_get(obj, MY_CLASS); + EINA_SAFETY_ON_NULL_RETURN(pd); + + EINA_LIST_FOREACH(pd->pending_futures, li, future) + if (*future == event->object) + { + // WTF? where is the unuse function?? + pd->pending_futures = eina_list_remove_list(pd->pending_futures, li); + efl_wref_del(*future, future); + free(future); + break; + } + + if (!children) return; + EINA_ACCESSOR_FOREACH(children, k, child) + _child_add_model(obj, pd, child); +} + +EFL_CALLBACKS_ARRAY_DEFINE(_model_callbacks, +{ EFL_MODEL_EVENT_PROPERTIES_CHANGED, _properties_changed_cb }, +{ EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb }, +{ EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb }) + +EOLIAN static void +_efl_ui_item_list_model_set(Eo *obj, Efl_Ui_Item_List_Data *pd, Efl_Model *model) +{ + Efl_Callback_Array_Item *cb; + Efl_Future **wfut, *future; + size_t k; + + EINA_SAFETY_ON_NULL_RETURN(model); + if (pd->model == model) return; + + if (pd->model) + { + Eo *item; + + EINA_LIST_FREE(pd->items, item) + efl_del(item); + + efl_composite_detach(obj, pd->model); + efl_event_callback_array_del(pd->model, _model_callbacks(), obj); + for (k = 0, cb = _model_callbacks(); cb->desc; + k++, cb = _model_callbacks() + k) + efl_event_callback_forwarder_del(pd->model, cb->desc, obj); + if (pd->model_owned) + efl_del(pd->model); + } + + EINA_LIST_FREE(pd->pending_futures, wfut) + { + efl_future_cancel(*wfut); + free(wfut); + } + + pd->model = model; + pd->model_owned = EINA_FALSE; + if (model) + { + efl_composite_attach(obj, pd->model); + efl_event_callback_array_add(pd->model, _model_callbacks(), obj); + for (k = 0, cb = _model_callbacks(); cb->desc; + k++, cb = _model_callbacks() + k) + efl_event_callback_forwarder_add(pd->model, cb->desc, obj); + future = efl_model_children_slice_get(pd->model, 0, 0); + efl_future_then(future, _children_slice_cb, NULL, NULL, obj); + pd->pending_futures = eina_list_append(pd->pending_futures, future); + } +} + +EOLIAN static Efl_Model * +_efl_ui_item_list_model_get(Eo *obj EINA_UNUSED, Efl_Ui_Item_List_Data *pd) +{ + return pd->model; +} + +EOLIAN static Eo * +_efl_ui_item_list_efl_object_constructor(Eo *obj, Efl_Ui_Item_List_Data *pd) +{ + pd->self = obj; + obj = efl_constructor(efl_super(obj, MY_CLASS)); + + pd->model_owned = EINA_TRUE; + efl_ui_item_list_model_set(obj, efl_add(EFL_MODEL_ITEM_CLASS, obj)); + + return obj; +} + +#include "efl_ui_item_list.eo.c" diff --git a/src/lib/elementary/efl_ui_item_list.eo b/src/lib/elementary/efl_ui_item_list.eo new file mode 100644 index 0000000000..c5f4999446 --- /dev/null +++ b/src/lib/elementary/efl_ui_item_list.eo @@ -0,0 +1,26 @@ +abstract Efl.Ui.Item_List (Efl.Ui.Layout, Efl.Model.Item) +{ + methods { + @property item_class @protected { + get @pure_virtual {} + values { + klass: const(Efl.Class); [[Class of item objects to create.]] + } + } + item_add { + params { + @in text: string; + @in icon: string @optional; + } + return: Efl.Ui.Item; [[A newly created item, appended to this list.]] + } + @property model { + values { + model: Efl.Model; [[The internal model.]] + } + } + } + implements { + Efl.Object.constructor; + } +} diff --git a/src/lib/elementary/efl_ui_toolbar.c b/src/lib/elementary/efl_ui_toolbar.c index 541b30badb..7e5b6d04a2 100644 --- a/src/lib/elementary/efl_ui_toolbar.c +++ b/src/lib/elementary/efl_ui_toolbar.c @@ -2,1469 +2,81 @@ # include "elementary_config.h" #endif -#define EFL_UI_FOCUS_COMPOSITION_PROTECTED -#define EFL_ACCESS_PROTECTED -#define EFL_ACCESS_SELECTION_PROTECTED -#define EFL_ACCESS_WIDGET_ACTION_PROTECTED -#define ELM_WIDGET_ITEM_PROTECTED -#define EFL_UI_TRANSLATABLE_PROTECTED -#define EFL_UI_FOCUS_OBJECT_PROTECTED - -#include -#include "elm_priv.h" -#include "efl_ui_toolbar_private.h" +#include "efl_ui_item_priv.h" #include "efl_ui_toolbar_item.eo.h" #define MY_CLASS EFL_UI_TOOLBAR_CLASS #define MY_CLASS_NAME "Efl.Ui.Toolbar" -#define EFL_UI_TOOLBAR_ITEM_FROM_INLIST(item) \ - ((item) ? EINA_INLIST_CONTAINER_GET(item, Efl_Ui_Toolbar_Item_Data) : NULL) - -static const char SIG_CLICKED[] = "clicked"; -static const char SIG_SELECTED[] = "selected"; -static const char SIG_UNSELECTED[] = "unselected"; -static const char SIG_ITEM_FOCUSED[] = "item,focused"; -static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CLICKED, ""}, - {SIG_SELECTED, ""}, - {SIG_UNSELECTED, ""}, - {SIG_ITEM_FOCUSED, ""}, - {SIG_ITEM_UNFOCUSED, ""}, - {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */ - {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */ - {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */ - {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */ - {NULL, NULL} -}; - -static Eina_Bool _key_action_select(Evas_Object *obj, const char *params); -static void _sizing_eval(Evas_Object *obj); - -static const Elm_Action key_actions[] = { - {"select", _key_action_select}, - {NULL, NULL} -}; - -static void _item_select(Efl_Ui_Toolbar_Item_Data *it); - -static void -_item_unselect(Efl_Ui_Toolbar_Item_Data *item) -{ - if ((!item) || (!item->selected)) return; - - EFL_UI_TOOLBAR_DATA_GET(WIDGET(item), sd); - - item->selected = EINA_FALSE; - sd->selected_item = NULL; - elm_layout_signal_emit(VIEW(item), "elm,state,unselected", "elm"); - if (item->icon) - elm_widget_signal_emit(item->icon, "elm,state,unselected", "elm"); - efl_event_callback_legacy_call(WIDGET(item), EFL_UI_EVENT_UNSELECTED, EO_OBJ(item)); - if (_elm_config->atspi_mode) - efl_access_state_changed_signal_emit(EO_OBJ(item), EFL_ACCESS_STATE_SELECTED, EINA_FALSE); -} - -static void -_mirrored_set(Evas_Object *obj, - Eina_Bool mirrored) -{ - Efl_Ui_Toolbar_Item_Data *it; - - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - EINA_INLIST_FOREACH(sd->items, it) - efl_ui_mirrored_set(VIEW(it), mirrored); -} - -static void -_efl_ui_toolbar_item_focused(Elm_Object_Item *eo_it) -{ - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_it, it); - Evas_Object *obj = WIDGET(it); - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - const char *focus_raise; - - if (!sd || (eo_it == sd->focused_item)) return; - - sd->focused_item = eo_it; - - if (elm_widget_focus_highlight_enabled_get(obj)) - { - elm_layout_signal_emit - (VIEW(it), "elm,state,focused", "elm"); - } - elm_layout_signal_emit - (VIEW(it), "elm,highlight,on", "elm"); - focus_raise = elm_layout_data_get(VIEW(it), "focusraise"); - if ((focus_raise) && (!strcmp(focus_raise, "on"))) - evas_object_raise(VIEW(it)); - efl_event_callback_legacy_call - (obj, EFL_UI_TOOLBAR_EVENT_ITEM_FOCUSED, EO_OBJ(it)); - if (_elm_config->atspi_mode) - efl_access_state_changed_signal_emit(EO_OBJ(it), EFL_ACCESS_STATE_FOCUSED, EINA_TRUE); -} - -static void -_efl_ui_toolbar_item_unfocused(Elm_Object_Item *eo_it) -{ - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_it, it); - Evas_Object *obj = WIDGET(it); - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - if ((!sd) || !sd->focused_item || (eo_it != sd->focused_item)) - return; - - if (elm_widget_focus_highlight_enabled_get(obj)) - { - EFL_UI_TOOLBAR_ITEM_DATA_GET(sd->focused_item, focus_it); - elm_layout_signal_emit - (VIEW(focus_it), "elm,state,unfocused", "elm"); - } - elm_layout_signal_emit - (VIEW(it), "elm,highlight,off", "elm"); - sd->focused_item = NULL; - efl_event_callback_legacy_call - (obj, EFL_UI_TOOLBAR_EVENT_ITEM_UNFOCUSED, eo_it); - if (_elm_config->atspi_mode) - efl_access_state_changed_signal_emit(eo_it, EFL_ACCESS_STATE_FOCUSED, EINA_TRUE); -} - -EOLIAN static Eina_Bool -_efl_ui_toolbar_elm_widget_on_focus_update(Eo *obj, Efl_Ui_Toolbar_Data *sd, Elm_Object_Item *item EINA_UNUSED) -{ - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - Eina_Bool int_ret = EINA_FALSE; - Elm_Object_Item *eo_it = NULL; - - int_ret = efl_ui_widget_on_focus_update(efl_super(obj, MY_CLASS), NULL); - if (!int_ret) return EINA_FALSE; - if (!sd->items) return EINA_FALSE; - - if (elm_widget_focus_get(obj)) - { - evas_object_focus_set(wd->resize_obj, EINA_TRUE); - - if (sd->last_focused_item) - eo_it = sd->last_focused_item; - else if (_elm_config->first_item_focus_on_first_focus_in) - { - eo_it = efl_ui_menu_first_item_get(obj); - } - if (eo_it) _efl_ui_toolbar_item_focused(eo_it); - } - else - { - sd->last_focused_item = sd->focused_item; - if (sd->focused_item) - _efl_ui_toolbar_item_unfocused(sd->focused_item); - evas_object_focus_set(wd->resize_obj, EINA_FALSE); - } - return EINA_TRUE; -} - -EOLIAN static void -_efl_ui_toolbar_item_elm_widget_item_focus_set(Eo *eo_it, Efl_Ui_Toolbar_Item_Data *it, Eina_Bool focused) -{ - EFL_UI_TOOLBAR_ITEM_CHECK(it); - Evas_Object *obj = WIDGET(it); - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - if (focused) - { - sd->last_focused_item = eo_it; - if (!elm_object_focus_get(obj)) - elm_object_focus_set(obj, EINA_TRUE); - - if (!elm_object_focus_get(obj)) - return; - - if (eo_it != sd->focused_item) - { - if (sd->focused_item) - _efl_ui_toolbar_item_unfocused(sd->focused_item); - _efl_ui_toolbar_item_focused(eo_it); - } - - } - else - { - if (!elm_object_focus_get(obj)) - return; - if (eo_it) - _efl_ui_toolbar_item_unfocused(eo_it); - } - - evas_object_focus_set(VIEW(it), focused); - - _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it)); - _elm_widget_highlight_in_theme_update(obj); - _elm_widget_focus_highlight_start(obj); -} - -EOLIAN static Eina_Bool -_efl_ui_toolbar_item_elm_widget_item_focus_get(Eo *eo_it, Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); - Evas_Object *obj = WIDGET(it); - EFL_UI_TOOLBAR_CHECK(obj) EINA_FALSE; - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - if (eo_it == sd->focused_item) - return EINA_TRUE; - return EINA_FALSE; -} - -static Eina_Bool -_key_action_select(Evas_Object *obj, const char *params EINA_UNUSED) -{ - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - if (!sd->items) return EINA_FALSE; - if (sd->focused_item) - { - EFL_UI_TOOLBAR_ITEM_DATA_GET(sd->focused_item, focus_it); - _item_select(focus_it); - } - - return EINA_TRUE; -} - -static void -_resizing_eval_item(Efl_Ui_Toolbar_Item_Data *it) -{ - Evas_Coord mw = -1, mh = -1; - - edje_object_size_min_restricted_calc(elm_layout_edje_get(VIEW(it)), &mw, &mh, mw, mh); - if (!it->object) - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - evas_object_size_hint_min_set(VIEW(it), mw, mh); - evas_object_size_hint_max_set(VIEW(it), -1, -1); -} - -EOLIAN static void -_efl_ui_toolbar_item_elm_widget_item_disable(Eo *eo_toolbar, Efl_Ui_Toolbar_Item_Data *toolbar_it) -{ - const char* emission; - - if (elm_wdg_item_disabled_get(eo_toolbar)) - emission = "elm,state,disabled"; - else - emission = "elm,state,enabled"; - - elm_layout_signal_emit(VIEW(toolbar_it), emission, "elm"); - if (toolbar_it->icon) - elm_widget_signal_emit(toolbar_it->icon, emission, "elm"); -} - -EOLIAN static void -_efl_ui_toolbar_item_elm_widget_item_signal_emit(Eo *eo_toolbar_it EINA_UNUSED, - Efl_Ui_Toolbar_Item_Data *toolbar_it, - const char *emission, - const char *source) -{ - elm_layout_signal_emit(VIEW(toolbar_it), emission, source); -} - -static Eina_Bool -_item_icon_set(Evas_Object *icon_obj, - const char *type, - const char *icon) -{ - char icon_str[512]; - - if ((!type) || (!*type)) goto end; - if ((!icon) || (!*icon)) return EINA_FALSE; - if ((snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0) - && (elm_icon_standard_set(icon_obj, icon_str))) - return EINA_TRUE; -end: - if (elm_icon_standard_set(icon_obj, icon)) - return EINA_TRUE; - - WRN("couldn't find icon definition for '%s'", icon); - return EINA_FALSE; -} - -static void -_item_select(Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_DATA_GET(WIDGET(it), sd); - - if (elm_wdg_item_disabled_get(EO_OBJ(it)) || (it->object)) - return; - - if (!it->selected) - { - Elm_Object_Item *eo_it2 = - efl_ui_menu_selected_item_get(WIDGET(it)); - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_it2, it2); - _item_unselect(it2); - - it->selected = EINA_TRUE; - sd->selected_item = EO_OBJ(it); - - elm_layout_signal_emit(VIEW(it), "elm,state,selected", "elm"); - if (it->icon) - elm_widget_signal_emit(it->icon, "elm,state,selected", "elm"); - - if (it->func) it->func((void *)(WIDGET_ITEM_DATA_GET(EO_OBJ(it))), WIDGET(it), EO_OBJ(it)); - efl_event_callback_legacy_call(WIDGET(it), EFL_UI_EVENT_SELECTED, EO_OBJ(it)); - if (_elm_config->atspi_mode) - efl_access_state_changed_signal_emit(EO_OBJ(it), EFL_ACCESS_STATE_SELECTED, EINA_TRUE); - } -} - -/* Send order signals when item is added/deleted. - * If the given item is on deletion, item_on_deletion should be EINA_TRUE. */ -static void -_efl_ui_toolbar_item_order_signal_emit(Efl_Ui_Toolbar_Data *sd, - Efl_Ui_Toolbar_Item_Data *it, - Eina_List *prev_list, - Eina_Bool item_on_deletion) -{ - Efl_Ui_Toolbar_Item_Data *first_it = NULL, *last_it = NULL; - Evas_Object *first_it_view = NULL, *last_it_view = NULL; - Efl_Ui_Toolbar_Item_Data *prev_first_it = NULL, *prev_last_it = NULL; - Evas_Object *prev_first_it_view = NULL, *prev_last_it_view = NULL; - Eina_List *list = NULL; - Eina_Iterator *itr; - Evas_Object *sobj; - - itr = efl_content_iterate(sd->bx); - EINA_ITERATOR_FOREACH(itr, sobj) - list = eina_list_append(list, sobj); - - if (!list) return; - - if (prev_list) - { - prev_first_it_view = eina_list_data_get(prev_list); - prev_last_it_view = eina_list_data_get(eina_list_last(prev_list)); - prev_first_it = evas_object_data_get(prev_first_it_view, "item"); - prev_last_it = evas_object_data_get(prev_last_it_view, "item"); - } - - first_it_view = eina_list_data_get(list); - last_it_view = eina_list_data_get(eina_list_last(list)); - first_it = evas_object_data_get(first_it_view, "item"); - last_it = evas_object_data_get(last_it_view, "item"); - - if (prev_first_it) - { - if ((prev_first_it != first_it) && (prev_first_it != last_it)) - elm_layout_signal_emit(VIEW(prev_first_it), "elm,order,default,item", "elm"); - else if (prev_first_it == last_it) - elm_layout_signal_emit(VIEW(prev_first_it), "elm,order,last,item", "elm"); - } - - if (prev_last_it) - { - if ((prev_last_it != last_it) && (prev_last_it != first_it)) - elm_layout_signal_emit(VIEW(prev_last_it), "elm,order,default,item", "elm"); - else if (prev_last_it == first_it) - elm_layout_signal_emit(VIEW(prev_last_it), "elm,order,first,item", "elm"); - } - - if (it) - { - if (!item_on_deletion) - { - if (first_it == last_it) - { - elm_layout_signal_emit(VIEW(it), "elm,order,first,item", "elm"); - elm_layout_signal_emit(VIEW(it), "elm,order,last,item", "elm"); - } - else if (it == first_it) - { - elm_layout_signal_emit(VIEW(it), "elm,order,first,item", "elm"); - } - else if (it == last_it) - { - elm_layout_signal_emit(VIEW(it), "elm,order,last,item", "elm"); - } - } - else if (first_it != last_it) - { - if (it == first_it) - { - Eina_List *next_l = eina_list_next(list); - first_it_view = eina_list_data_get(next_l); - first_it = evas_object_data_get(first_it_view, "item"); - - elm_layout_signal_emit(first_it_view, "elm,order,first,item", "elm"); - } - else if (it == last_it) - { - Eina_List *prev_l = eina_list_prev(eina_list_last(list)); - last_it_view = eina_list_data_get(prev_l); - last_it = evas_object_data_get(last_it_view, "item"); - - elm_layout_signal_emit(last_it_view, "elm,order,last,item", "elm"); - } - } - } - - eina_list_free(list); -} - -static void -_item_del(Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_DATA_GET(WIDGET(it), sd); - - _item_unselect(it); - - _efl_ui_toolbar_item_order_signal_emit(sd, it, NULL, EINA_TRUE); - - eina_stringshare_del(it->label); - if (it->label) - elm_layout_signal_emit(VIEW(it), "elm,state,text,hidden", "elm"); - eina_stringshare_del(it->icon_str); - - if (it->icon) - { - elm_layout_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm"); - evas_object_del(it->icon); - } - - if (sd->focused_item == EO_OBJ(it)) - sd->focused_item = NULL; - if (sd->last_focused_item == EO_OBJ(it)) - sd->last_focused_item = NULL; - - evas_object_del(it->object); -} - -static void -_item_theme_hook(Evas_Object *obj, - Efl_Ui_Toolbar_Item_Data *it, - double scale) -{ - Evas_Coord mw = -1, mh = -1; - Evas_Object *view = VIEW(it); - const char *style; - - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - style = elm_widget_style_get(obj); - - efl_ui_mirrored_set(VIEW(it), efl_ui_mirrored_get(obj)); - edje_object_scale_set(elm_layout_edje_get(view), scale); - - if (!it->object) - { - if (!elm_layout_theme_set(view, "toolbar", "item", style)) - CRI("Failed to set layout!"); - if (it->selected) - { - elm_layout_signal_emit(view, "elm,state,selected", "elm"); - if (it->icon) - elm_widget_signal_emit(it->icon, "elm,state,selected", "elm"); - } - if (elm_wdg_item_disabled_get(EO_OBJ(it))) - { - elm_layout_signal_emit(view, "elm,state,disabled", "elm"); - if (it->icon) - elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm"); - } - if (it->icon) - { - elm_layout_content_set(view, "elm.swallow.icon", it->icon); - elm_layout_signal_emit - (view, "elm,state,icon,visible", "elm"); - } - if (it->label) - { - elm_layout_text_set(view, "elm.text", it->label); - elm_layout_signal_emit(view, "elm,state,text,visible", "elm"); - } - } - else - { - if (!elm_layout_theme_set(view, "toolbar", "object", style)) - CRI("Failed to set layout!"); - elm_layout_content_set(view, "elm.swallow.object", it->object); - } - - //FIXME: after signal rule is fixed, this should be considered again - elm_layout_signal_emit(view, "elm,state,shrink,default", "elm"); - - if (!efl_ui_dir_is_horizontal(sd->dir, EINA_TRUE)) - elm_layout_signal_emit(view, "elm,orient,vertical", "elm"); - else - elm_layout_signal_emit(view, "elm,orient,horizontal", "elm"); - - edje_object_message_signal_process(elm_layout_edje_get(view)); - if (!it->object) - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - - if (!efl_ui_dir_is_horizontal(sd->dir, EINA_TRUE)) - { - evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, -1.0); - evas_object_size_hint_align_set - (view, EVAS_HINT_FILL, EVAS_HINT_FILL); - } - else - { - evas_object_size_hint_weight_set(VIEW(it), -1.0, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (view, EVAS_HINT_FILL, EVAS_HINT_FILL); - } - - _resizing_eval_item(it); - evas_object_smart_need_recalculate_set(obj, EINA_TRUE); -} - -static void -_inform_item_number(Evas_Object *obj) -{ - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - Efl_Ui_Toolbar_Item_Data *it; - char buf[sizeof("elm,number,item,") + 4]; - static int scount = 0; - int count = 0; - Evas_Coord mw, mh; - - EINA_INLIST_FOREACH(sd->items, it) - { - count++; - } - if (scount != count) - { - scount = count; - if (snprintf(buf, sizeof(buf), "elm,number,item,%d", count) >= (int)sizeof(buf)) - ERR("Too many items to fit signal buffer (%d)", count); - - EINA_INLIST_FOREACH(sd->items, it) - { - if (!it->object) - { - elm_layout_signal_emit(VIEW(it), buf, "elm"); - edje_object_message_signal_process(elm_layout_edje_get(VIEW(it))); - - mw = mh = -1; - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - - edje_object_size_min_restricted_calc(elm_layout_edje_get(VIEW(it)), &mw, &mh, mw, mh); - evas_object_size_hint_min_set(VIEW(it), mw, mh); - } - } - } -} +typedef struct { + Eo *self; + Eo *bx; + Efl_Ui_Dir dir; +} Efl_Ui_Toolbar_Data; static void -_sizing_eval(Evas_Object *obj) +_sizing_calc(Efl_Ui_Toolbar_Data *pd) { - Evas_Coord minw = -1, minh = -1, minw_bx = -1, minh_bx = -1; - Evas_Coord w, h; - - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - - edje_object_size_min_calc(wd->resize_obj, &minw, &minh); - evas_object_geometry_get(obj, NULL, NULL, &w, &h); + Eina_Rect r; - if (w < minw) w = minw; - if (h < minh) h = minh; + efl_canvas_group_calculate(pd->bx); + r.pos = efl_gfx_position_get(pd->self); + r.size = efl_gfx_size_hint_combined_min_get(pd->bx); + efl_gfx_geometry_set(pd->bx, r); - evas_object_resize(wd->resize_obj, w, h); - evas_object_size_hint_combined_min_get(sd->bx, &minw_bx, &minh_bx); - evas_object_size_hint_min_set(obj, minw_bx, minh_bx); - - _inform_item_number(obj); -} - -static void -_efl_ui_toolbar_highlight_in_theme(Evas_Object *obj) -{ - const char *fh; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - - fh = edje_object_data_get - (wd->resize_obj, "focus_highlight"); - if ((fh) && (!strcmp(fh, "on"))) - elm_widget_highlight_in_theme_set(obj, EINA_TRUE); - else - elm_widget_highlight_in_theme_set(obj, EINA_FALSE); + efl_gfx_size_hint_restricted_min_set(pd->self, r.size); } EOLIAN static Efl_Ui_Theme_Apply _efl_ui_toolbar_elm_widget_theme_apply(Eo *obj, Efl_Ui_Toolbar_Data *sd) { - Efl_Ui_Toolbar_Item_Data *it; - double scale = 0; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_FAILED); - - if (sd->delete_me) return EFL_UI_THEME_APPLY_SUCCESS; + Efl_Ui_Theme_Apply ret; - Efl_Ui_Theme_Apply int_ret = EFL_UI_THEME_APPLY_FAILED; - int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS)); - if (!int_ret) return EFL_UI_THEME_APPLY_FAILED; + ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS)); + if (!ret) return EFL_UI_THEME_APPLY_FAILED; - elm_widget_theme_object_set - (obj, wd->resize_obj, "toolbar", "base", - elm_widget_style_get(obj)); + elm_layout_theme_set(obj, "toolbar", "base", elm_widget_style_get(obj)); if (!efl_ui_dir_is_horizontal(sd->dir, EINA_TRUE)) - edje_object_signal_emit(wd->resize_obj, "elm,orient,vertical", "elm"); - else - edje_object_signal_emit(wd->resize_obj, "elm,orient,horizontal", "elm"); - - _mirrored_set(obj, efl_ui_mirrored_get(obj)); - - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - EINA_INLIST_FOREACH(sd->items, it) - _item_theme_hook(obj, it, scale); - - _efl_ui_toolbar_highlight_in_theme(obj); - evas_object_smart_need_recalculate_set(obj, EINA_TRUE); - - return int_ret; -} - -static void -_efl_ui_toolbar_item_label_update(Efl_Ui_Toolbar_Item_Data *item) -{ - elm_layout_text_set(VIEW(item), "elm.text", item->label); - if (item->label) - elm_layout_signal_emit(VIEW(item), "elm,state,text,visible", "elm"); - else - elm_layout_signal_emit(VIEW(item), "elm,state,text,hidden", "elm"); -} - -static void -_efl_ui_toolbar_item_label_set_cb(void *data, - Evas_Object *obj, - const char *emission, - const char *source) -{ - Efl_Ui_Toolbar_Item_Data *item = data; - - _efl_ui_toolbar_item_label_update(item); - elm_layout_signal_callback_del - (obj, emission, source, _efl_ui_toolbar_item_label_set_cb); - elm_layout_signal_emit(VIEW(item), "elm,state,label,reset", "elm"); -} - -static void -_item_label_set(Efl_Ui_Toolbar_Item_Data *item, - const char *label, - const char *sig) -{ - const char *s; - - if ((label) && (item->label) && (!strcmp(label, item->label))) return; - - eina_stringshare_replace(&item->label, label); - s = elm_layout_data_get(VIEW(item), "transition_animation_on"); - if ((s) && (atoi(s))) - { - elm_layout_text_set - (VIEW(item), "elm.text_new", item->label); - elm_layout_signal_emit(VIEW(item), sig, "elm"); - elm_layout_signal_callback_add - (VIEW(item), "elm,state,label_set,done", "elm", - _efl_ui_toolbar_item_label_set_cb, item); - } + efl_canvas_layout_signal_emit(obj, "elm,orient,vertical", "elm"); else - _efl_ui_toolbar_item_label_update(item); - - _resizing_eval_item(item); -} + efl_canvas_layout_signal_emit(obj, "elm,orient,horizontal", "elm"); -EOLIAN static void -_efl_ui_toolbar_item_elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const char *part, - const char *label) -{ - char buf[256]; + efl_canvas_group_need_recalculate_set(obj, EINA_TRUE); - if ((!part) || (!strcmp(part, "default")) || - (!strcmp(part, "elm.text"))) - { - _item_label_set(item, label, "elm,state,label_set"); - } - else - { - if (label) - { - snprintf(buf, sizeof(buf), "elm,state,%s,visible", part); - elm_layout_signal_emit(VIEW(item), buf, "elm"); - } - else - { - snprintf(buf, sizeof(buf), "elm,state,%s,hidden", part); - elm_layout_signal_emit(VIEW(item), buf, "elm"); - } - elm_layout_text_set(VIEW(item), part, label); - } -} - -EOLIAN static const char * -_efl_ui_toolbar_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it, - const char *part) -{ - char buf[256]; - - if (!part || !strcmp(part, "default")) - snprintf(buf, sizeof(buf), "elm.text"); - else - snprintf(buf, sizeof(buf), "%s", part); - - return elm_layout_text_get(VIEW(it), buf); -} - -EOLIAN static void -_efl_ui_toolbar_item_elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const char *part, - Evas_Object *content) -{ - Evas_Object *obj = WIDGET(item); - double scale; - - if (part && strcmp(part, "object") && strcmp(part, "elm.swallow.object")) - { - efl_content_set(efl_part(VIEW(item), part), content); - return; - } - if (item->object == content) return; - - evas_object_del(item->object); - - item->object = content; - if (item->object) - elm_widget_sub_object_add(obj, item->object); - - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - _item_theme_hook(obj, item, scale); -} - -EOLIAN static Evas_Object * -_efl_ui_toolbar_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it, - const char *part) -{ - if (part && strcmp(part, "object") && strcmp(part, "elm.swallow.object")) - { - return efl_content_get(efl_part(VIEW(it), part)); - } - return it->object; -} - -EOLIAN static Evas_Object * -_efl_ui_toolbar_item_elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const char *part) -{ - Evas_Object *obj = WIDGET(item); - Evas_Object *o; - double scale; - - if (part && strcmp(part, "object") && strcmp(part, "elm.swallow.object")) - { - return efl_content_unset(efl_part(VIEW(item), part)); - } - - elm_layout_content_unset(VIEW(item), "elm.swallow.object"); - _elm_widget_sub_object_redirect_to_top(obj, item->object); - o = item->object; - item->object = NULL; - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - _item_theme_hook(obj, item, scale); - - return o; -} - -EOLIAN static void -_efl_ui_toolbar_efl_ui_translatable_translation_update(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - Efl_Ui_Toolbar_Item_Data *it; - - EINA_INLIST_FOREACH(sd->items, it) - elm_wdg_item_translate(EO_OBJ(it)); - - efl_ui_translatable_translation_update(efl_super(obj, MY_CLASS)); -} - -static void -_action_click_cb(void *data, - Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) -{ - Efl_Ui_Toolbar_Item_Data *it = data; - - if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) || - (_elm_access_2nd_click_timeout(VIEW(it)))) - { - if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) - _elm_access_say(E_("Selected")); - _item_select(it); - } -} - -static char * -_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED) -{ - Efl_Ui_Toolbar_Item_Data *it = (Efl_Ui_Toolbar_Item_Data *)data; - const char *txt = (it->base)->access_info; - - if (!txt) txt = it->label; - if (txt) return strdup(txt); - - return NULL; -} - -static char * -_access_state_cb(void *data, Evas_Object *obj EINA_UNUSED) -{ - Efl_Ui_Toolbar_Item_Data *it = (Efl_Ui_Toolbar_Item_Data *)data; - - if (elm_wdg_item_disabled_get(EO_OBJ(it))) - return strdup(E_("State: Disabled")); - else if (it->selected) - return strdup(E_("State: Selected")); - - return NULL; -} - -EOLIAN static void -_efl_ui_toolbar_item_efl_object_destructor(Eo *eo_item, Efl_Ui_Toolbar_Item_Data *item) -{ - EFL_UI_TOOLBAR_DATA_GET(WIDGET(item), sd); - - sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(item)); - sd->item_count--; - _item_del(item); - efl_ui_widget_theme_apply(WIDGET(item)); - - efl_destructor(efl_super(eo_item, EFL_UI_TOOLBAR_ITEM_CLASS)); -} - -static void -_access_activate_cb(void *data EINA_UNUSED, - Evas_Object *part_obj EINA_UNUSED, - Elm_Object_Item *item) -{ - EFL_UI_TOOLBAR_ITEM_DATA_GET(item, it); - if (elm_wdg_item_disabled_get(item)) return; - - if (it->selected) - { - _elm_access_say(E_("Unselected")); - _item_unselect(it); - } - else - { - _elm_access_say(E_("Selected")); - _item_select(it); - } + return ret; } static void -_access_widget_item_register(Efl_Ui_Toolbar_Item_Data *it) -{ - Elm_Access_Info *ai; - _elm_access_widget_item_register(it->base); - ai = _elm_access_info_get(it->base->access_obj); - - _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Toolbar Item")); - _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it); - _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it); - _elm_access_activate_callback_set(ai, _access_activate_cb, NULL); -} - -EOLIAN static Eina_Rect -_efl_ui_toolbar_item_efl_ui_focus_object_focus_geometry_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *pd) +_box_size_cb(void *data, const Efl_Event *event EINA_UNUSED) { - Eina_Rect rect; + Eo *obj = data; - evas_object_geometry_get(VIEW(pd), &rect.x, &rect.y, &rect.w, &rect.h); - - return rect; + efl_canvas_group_need_recalculate_set(obj, EINA_TRUE); } EOLIAN static Eo * -_efl_ui_toolbar_item_efl_object_constructor(Eo *eo_it, Efl_Ui_Toolbar_Item_Data *it) -{ - eo_it = efl_constructor(efl_super(eo_it, EFL_UI_TOOLBAR_ITEM_CLASS)); - it->base = efl_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS); - efl_access_role_set(eo_it, EFL_ACCESS_ROLE_MENU_ITEM); - - return eo_it; -} - -static Efl_Ui_Toolbar_Item_Data * -_item_new(Evas_Object *obj, - const char *icon, - const char *label, - Evas_Smart_Cb func, - const void *data) -{ - Evas_Object *icon_obj; - - EFL_UI_TOOLBAR_DATA_GET(obj, sd); - - Eo *eo_it = efl_add(EFL_UI_TOOLBAR_ITEM_CLASS, obj); - - if (!eo_it) return NULL; - - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_it, it); - - it->label = eina_stringshare_add(label); - it->func = func; - it->object = NULL; - WIDGET_ITEM_DATA_SET(EO_OBJ(it), data); - - VIEW(it) = elm_layout_add(obj); - elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE); - evas_object_data_set(VIEW(it), "item", it); - efl_access_type_set(VIEW(it), EFL_ACCESS_TYPE_DISABLED); - - icon_obj = elm_icon_add(VIEW(it)); - - if (_elm_config->atspi_mode) - if (icon_obj) efl_access_parent_set(icon_obj, eo_it); - - if (_elm_config->access_mode == ELM_ACCESS_MODE_ON) - _access_widget_item_register(it); - - if (_item_icon_set(icon_obj, "toolbar/", icon)) - { - it->icon = icon_obj; - it->icon_str = eina_stringshare_add(icon); - } - else - { - it->icon = NULL; - it->icon_str = NULL; - evas_object_del(icon_obj); - } - - if (!elm_layout_theme_set - (VIEW(it), "toolbar", "item", elm_widget_style_get(obj))) - CRI("Failed to set layout!"); - elm_layout_signal_callback_add - (VIEW(it), "elm,action,click", "elm", _action_click_cb, it); - - if (it->icon) - { - elm_layout_content_set(VIEW(it), "elm.swallow.icon", it->icon); - elm_layout_signal_emit(VIEW(it), "elm,state,icon,visible", "elm"); - elm_layout_signal_emit(VIEW(it), "elm,icon,visible", "elm"); - evas_object_show(it->icon); - } - else - { - elm_layout_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm"); - elm_layout_signal_emit(VIEW(it), "elm,icon,hidden", "elm"); - } - - if (it->label) - { - elm_layout_text_set(VIEW(it), "elm.text", it->label); - elm_layout_signal_emit(VIEW(it), "elm,state,text,visible", "elm"); - elm_layout_signal_emit(VIEW(it), "elm,text,visible", "elm"); - } - else - { - elm_layout_signal_emit(VIEW(it), "elm,state,text,hidden", "elm"); - elm_layout_signal_emit(VIEW(it), "elm,text,hidden", "elm"); - } - - edje_object_message_signal_process(elm_layout_edje_get(VIEW(it))); - - if (!sd->items) _item_select(it); - - if (_elm_config->atspi_mode) efl_access_added(eo_it); - - return it; -} - -static void -_efl_ui_toolbar_item_icon_update(Efl_Ui_Toolbar_Item_Data *item) -{ - Evas_Object *old_icon = - elm_layout_content_get(VIEW(item), "elm.swallow.icon"); - - _elm_widget_sub_object_redirect_to_top(WIDGET(item), old_icon); - elm_layout_content_unset(VIEW(item), "elm.swallow.icon"); - elm_layout_content_set(VIEW(item), "elm.swallow.icon", item->icon); - if (item->icon) - elm_layout_signal_emit(VIEW(item), "elm,state,icon,visible", "elm"); - else - elm_layout_signal_emit(VIEW(item), "elm,state,icon,hidden", "elm"); - - evas_object_del(old_icon); -} - -static void -_efl_ui_toolbar_item_icon_set_cb(void *data, - Evas_Object *obj, - const char *emission, - const char *source) -{ - Efl_Ui_Toolbar_Item_Data *item = data; - _efl_ui_toolbar_item_icon_update(item); - elm_layout_signal_callback_del - (obj, emission, source, _efl_ui_toolbar_item_icon_set_cb); - elm_layout_signal_emit(VIEW(item), "elm,state,icon,reset", "elm"); -} - -static void -_efl_ui_toolbar_item_icon_obj_set(Evas_Object *obj, - Efl_Ui_Toolbar_Item_Data *item, - Evas_Object *icon_obj, - const char *icon_str, - const char *sig) -{ - Evas_Object *old_icon; - const char *s; - - if (icon_str) - eina_stringshare_replace(&item->icon_str, icon_str); - else - { - eina_stringshare_del(item->icon_str); - item->icon_str = NULL; - } - item->icon = icon_obj; - - if (icon_obj) - { - evas_object_show(item->icon); - elm_widget_sub_object_add(obj, item->icon); - } - s = elm_layout_data_get(VIEW(item), "transition_animation_on"); - if ((s) && (atoi(s))) - { - old_icon = elm_layout_content_get - (VIEW(item), "elm.swallow.icon_new"); - if (old_icon) - { - _elm_widget_sub_object_redirect_to_top(WIDGET(item), old_icon); - evas_object_hide(old_icon); - } - elm_layout_content_set - (VIEW(item), "elm.swallow.icon_new", item->icon); - elm_layout_signal_emit(VIEW(item), sig, "elm"); - elm_layout_signal_callback_add - (VIEW(item), "elm,state,icon_set,done", "elm", - _efl_ui_toolbar_item_icon_set_cb, item); - } - else - _efl_ui_toolbar_item_icon_update(item); - _resizing_eval_item(item); -} - -EOLIAN static void -_efl_ui_toolbar_efl_object_destructor(Eo *obj, Efl_Ui_Toolbar_Data *sd) -{ - Efl_Ui_Toolbar_Item_Data *it, *next; - - sd->delete_me = EINA_TRUE; - - it = EFL_UI_TOOLBAR_ITEM_FROM_INLIST(sd->items); - while (it) - { - next = EFL_UI_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); - elm_wdg_item_del(EO_OBJ(it)); - it = next; - } - efl_destructor(efl_super(obj, MY_CLASS)); -} - -EOLIAN static void -_efl_ui_toolbar_efl_gfx_position_set(Eo *obj, Efl_Ui_Toolbar_Data *sd EINA_UNUSED, Eina_Position2D pos) -{ - if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y)) - return; - - efl_gfx_position_set(efl_super(obj, MY_CLASS), pos); -} - -EOLIAN static void -_efl_ui_toolbar_efl_gfx_size_set(Eo *obj, Efl_Ui_Toolbar_Data *sd EINA_UNUSED, Eina_Size2D sz) -{ - if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h)) - return; - - efl_gfx_size_set(efl_super(obj, MY_CLASS), sz); -} - -static Eina_Bool _efl_ui_toolbar_smart_focus_next_enable = EINA_FALSE; - -static void -_access_obj_process(Efl_Ui_Toolbar_Data *sd, Eina_Bool is_access) -{ - Efl_Ui_Toolbar_Item_Data *it; - - EINA_INLIST_FOREACH (sd->items, it) - { - if (is_access) _access_widget_item_register(it); - else _elm_access_widget_item_unregister(it->base); - } -} - -EOLIAN static void -_efl_ui_toolbar_elm_widget_on_access_update(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd, Eina_Bool acs) -{ - _efl_ui_toolbar_smart_focus_next_enable = acs; - _access_obj_process(sd, _efl_ui_toolbar_smart_focus_next_enable); -} - -EOLIAN static void -_efl_ui_toolbar_item_efl_ui_focus_object_focus_set(Eo *obj, Efl_Ui_Toolbar_Item_Data *pd EINA_UNUSED, Eina_Bool focus) -{ - efl_ui_focus_object_focus_set(efl_super(obj, EFL_UI_TOOLBAR_ITEM_CLASS), focus); - elm_wdg_item_focus_set(obj, focus); -} - -EOLIAN static Eina_Rect -_efl_ui_toolbar_elm_widget_focus_highlight_geometry_get(Eo *obj, Efl_Ui_Toolbar_Data *sd) -{ - Eina_Rect r = {}; - - if (sd->focused_item) - { - EFL_UI_TOOLBAR_ITEM_DATA_GET(sd->focused_item, focus_it); - - evas_object_geometry_get(VIEW(focus_it), &r.x, &r.y, &r.w, &r.h); - elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &r.x, &r.y, &r.w, &r.h); - } - else - evas_object_geometry_get(obj, &r.x, &r.y, &r.w, &r.h); - - return r; -} - -EOLIAN static Efl_Object * -_efl_ui_toolbar_efl_object_constructor(Eo *obj, Efl_Ui_Toolbar_Data *sd) +_efl_ui_toolbar_efl_object_constructor(Eo *obj, Efl_Ui_Toolbar_Data *pd) { + pd->self = obj; obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_canvas_object_type_set(obj, MY_CLASS_NAME); - evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); - efl_access_role_set(obj, EFL_ACCESS_ROLE_TOOL_BAR); elm_widget_sub_object_parent_add(obj); - if (!elm_layout_theme_set(obj, "toolbar", "base", - elm_object_style_get(obj))) - CRI("Failed to set layout!"); - - elm_widget_can_focus_set(obj, EINA_TRUE); + elm_layout_theme_set(obj, "toolbar", "base", NULL); + if (!efl_ui_widget_theme_apply(obj)) + return NULL; - sd->dir = EFL_UI_DIR_HORIZONTAL; - sd->bx = efl_add(EFL_UI_BOX_CLASS, obj, - efl_ui_direction_set(efl_added, sd->dir), + pd->dir = EFL_UI_DIR_HORIZONTAL; + pd->bx = efl_add(EFL_UI_BOX_CLASS, obj, + efl_ui_direction_set(efl_added, pd->dir), efl_pack_align_set(efl_added, -1.0, -1.0)); - - elm_layout_content_set(obj, "elm.swallow.content", sd->bx); - _efl_ui_toolbar_highlight_in_theme(obj); - _sizing_eval(obj); + elm_layout_content_set(obj, "elm.swallow.content", pd->bx); + efl_event_callback_add(pd->bx, EFL_GFX_EVENT_CHANGE_SIZE_HINTS, + _box_size_cb, obj); return obj; } -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_item_append(Eo *obj, Efl_Ui_Toolbar_Data *sd, const char *icon, const char *label, Evas_Smart_Cb func, const void *data) -{ - Efl_Ui_Toolbar_Item_Data *it; - double scale; - Eina_List *prev_list = NULL; - Eina_Iterator *itr; - Evas_Object *sobj; - - it = _item_new(obj, icon, label, func, data); - if (!it) return NULL; - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - - itr = efl_content_iterate(sd->bx); - EINA_ITERATOR_FOREACH(itr, sobj) - prev_list = eina_list_append(prev_list, sobj); - - sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it)); - efl_pack(sd->bx, VIEW(it)); - evas_object_show(VIEW(it)); - - _item_theme_hook(obj, it, scale); - sd->item_count++; - - _efl_ui_toolbar_item_order_signal_emit(sd, it, prev_list, EINA_FALSE); - eina_list_free(prev_list); - - return EO_OBJ(it); -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_item_prepend(Eo *obj, Efl_Ui_Toolbar_Data *sd, const char *icon, const char *label, Evas_Smart_Cb func, const void *data) -{ - Efl_Ui_Toolbar_Item_Data *it; - double scale; - Eina_List *prev_list = NULL; - Eina_Iterator *itr; - Evas_Object *sobj; - - it = _item_new(obj, icon, label, func, data); - if (!it) return NULL; - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - - itr = efl_content_iterate(sd->bx); - EINA_ITERATOR_FOREACH(itr, sobj) - prev_list = eina_list_append(prev_list, sobj); - - sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it)); - efl_pack_begin(sd->bx, VIEW(it)); - evas_object_show(VIEW(it)); - _item_theme_hook(obj, it, scale); - sd->item_count++; - - _efl_ui_toolbar_item_order_signal_emit(sd, it, prev_list, EINA_FALSE); - eina_list_free(prev_list); - - return EO_OBJ(it); -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_item_insert_before(Eo *obj, Efl_Ui_Toolbar_Data *sd, Elm_Object_Item *eo_before, const char *icon, const char *label, Evas_Smart_Cb func, const void *data) -{ - Efl_Ui_Toolbar_Item_Data *it; - double scale; - Eina_List *prev_list = NULL; - Eina_Iterator *itr; - Evas_Object *sobj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL); - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_before, _before); - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(_before, NULL); - - it = _item_new(obj, icon, label, func, data); - if (!it) return NULL; - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - - itr = efl_content_iterate(sd->bx); - EINA_ITERATOR_FOREACH(itr, sobj) - prev_list = eina_list_append(prev_list, sobj); - - sd->items = eina_inlist_prepend_relative - (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_before)); - - efl_pack_before(sd->bx, VIEW(it), VIEW(_before)); - _item_theme_hook(obj, it, scale); - sd->item_count++; - - _efl_ui_toolbar_item_order_signal_emit(sd, it, prev_list, EINA_FALSE); - eina_list_free(prev_list); - - return EO_OBJ(it); -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_item_insert_after(Eo *obj, Efl_Ui_Toolbar_Data *sd, Elm_Object_Item *eo_after, const char *icon, const char *label, Evas_Smart_Cb func, const void *data) -{ - Efl_Ui_Toolbar_Item_Data *it; - double scale; - Eina_List *prev_list = NULL; - Eina_Iterator *itr; - Evas_Object *sobj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL); - EFL_UI_TOOLBAR_ITEM_DATA_GET(eo_after, _after); - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(_after, NULL); - - it = _item_new(obj, icon, label, func, data); - if (!it) return NULL; - scale = (efl_ui_scale_get(obj) * elm_config_scale_get()); - - itr = efl_content_iterate(sd->bx); - EINA_ITERATOR_FOREACH(itr, sobj) - prev_list = eina_list_append(prev_list, sobj); - - sd->items = eina_inlist_append_relative - (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_after)); - - efl_pack_after(sd->bx, VIEW(it), VIEW(_after)); - _item_theme_hook(obj, it, scale); - sd->item_count++; - - _efl_ui_toolbar_item_order_signal_emit(sd, it, prev_list, EINA_FALSE); - eina_list_free(prev_list); - - return EO_OBJ(it); -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_efl_ui_menu_first_item_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - if (!sd->items) return NULL; - Efl_Ui_Toolbar_Item_Data *it = EFL_UI_TOOLBAR_ITEM_FROM_INLIST(sd->items); - if (it) return EO_OBJ(it); - return NULL; -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_efl_ui_menu_last_item_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - if (!sd->items) return NULL; - - Efl_Ui_Toolbar_Item_Data *it = EFL_UI_TOOLBAR_ITEM_FROM_INLIST(sd->items->last); - if (it) return EO_OBJ(it); - return NULL; -} - -EOLIAN static Eina_Iterator* -_efl_ui_toolbar_efl_ui_menu_items_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - return eina_inlist_iterator_new(sd->items); -} - -EOLIAN static Elm_Object_Item * -_efl_ui_toolbar_item_efl_ui_item_next_get(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL); - - Efl_Ui_Toolbar_Item_Data *ret_it = EFL_UI_TOOLBAR_ITEM_FROM_INLIST( - EINA_INLIST_GET(it)->next); - if (ret_it) return EO_OBJ(ret_it); - else return NULL; -} - -EOLIAN static Elm_Object_Item * -_efl_ui_toolbar_item_efl_ui_item_prev_get(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL); - - Efl_Ui_Toolbar_Item_Data *ret_it = EFL_UI_TOOLBAR_ITEM_FROM_INLIST( - EINA_INLIST_GET(it)->prev); - if (ret_it) return EO_OBJ(ret_it); - else return NULL; -} - -EOLIAN static void -_efl_ui_toolbar_item_efl_ui_item_selected_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, Eina_Bool selected) -{ - if (item->selected == selected) return; - if (selected) _item_select(item); - else _item_unselect(item); -} - -EOLIAN static Eina_Bool -_efl_ui_toolbar_item_efl_ui_item_selected_get(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item) -{ - return item->selected; -} - -EOLIAN static Elm_Object_Item* -_efl_ui_toolbar_efl_ui_menu_selected_item_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - return sd->selected_item; -} - -EOLIAN static void -_efl_ui_toolbar_item_icon_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const char *icon) -{ - Evas_Object *obj; - Evas_Object *icon_obj; - - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(item); - - obj = WIDGET(item); - if ((icon) && (item->icon_str) && (!strcmp(icon, item->icon_str))) return; - - icon_obj = elm_icon_add(obj); - if (!icon_obj) return; - if (_item_icon_set(icon_obj, "toolbar/", icon)) - _efl_ui_toolbar_item_icon_obj_set - (obj, item, icon_obj, icon, "elm,state,icon_set"); - else - { - _efl_ui_toolbar_item_icon_obj_set - (obj, item, NULL, NULL, "elm,state,icon_set"); - evas_object_del(icon_obj); - } -} - -EOLIAN static const char * -_efl_ui_toolbar_item_icon_get(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL); - - return it->icon_str; -} - -EOLIAN static Evas_Object * -_efl_ui_toolbar_item_icon_object_get(Eo *eo_it EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *it) -{ - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL); - - return it->icon; -} - -EOLIAN static Eina_Bool -_efl_ui_toolbar_item_icon_memfile_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const void *img, - size_t size, - const char *format, - const char *key) -{ - Evas_Object *icon_obj; - Evas_Object *obj; - Eina_Bool ret; - - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(item, EINA_FALSE); - - obj = WIDGET(item); - - if (img && size) - { - icon_obj = elm_icon_add(obj); - evas_object_repeat_events_set(icon_obj, EINA_TRUE); - ret = elm_image_memfile_set(icon_obj, img, size, format, key); - if (!ret) - { - evas_object_del(icon_obj); - return EINA_FALSE; - } - _efl_ui_toolbar_item_icon_obj_set - (obj, item, icon_obj, NULL, "elm,state,icon_set"); - } - else - _efl_ui_toolbar_item_icon_obj_set - (obj, item, NULL, NULL, "elm,state,icon_set"); - return EINA_TRUE; -} - -EOLIAN static Eina_Bool -_efl_ui_toolbar_item_icon_file_set(Eo *eo_item EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *item, - const char *file, - const char *key) -{ - Evas_Object *icon_obj; - Evas_Object *obj; - Eina_Bool ret; - - EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(item, EINA_FALSE); - - obj = WIDGET(item); - - if (file) - { - icon_obj = elm_icon_add(obj); - evas_object_repeat_events_set(icon_obj, EINA_TRUE); - ret = elm_image_file_set(icon_obj, file, key); - if (!ret) - { - evas_object_del(icon_obj); - return EINA_FALSE; - } - _efl_ui_toolbar_item_icon_obj_set - (obj, item, icon_obj, NULL, "elm,state,icon_set"); - } - else - _efl_ui_toolbar_item_icon_obj_set - (obj, item, NULL, NULL, "elm,state,icon_set"); - return EINA_TRUE; -} - EOLIAN static void _efl_ui_toolbar_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Toolbar_Data *sd, Efl_Ui_Dir dir) { @@ -1479,7 +91,7 @@ _efl_ui_toolbar_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Toolbar_Data *sd, sd->dir = dir; efl_ui_direction_set(sd->bx, sd->dir); - _sizing_eval(obj); + evas_object_smart_changed(obj); } EOLIAN static Efl_Ui_Dir @@ -1488,205 +100,75 @@ _efl_ui_toolbar_efl_ui_direction_direction_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolb return sd->dir; } -EOLIAN static unsigned int -_efl_ui_toolbar_items_count(const Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - return sd->item_count; -} - -EOLIAN static const char* -_efl_ui_toolbar_item_efl_access_name_get(Eo *eo_item, Efl_Ui_Toolbar_Item_Data *item) -{ - const char *ret; - ret = efl_access_name_get(efl_super(eo_item, EFL_UI_TOOLBAR_ITEM_CLASS)); - if (ret) return ret; - return _elm_widget_item_accessible_plain_name_get(eo_item, item->label); -} - -EOLIAN static Efl_Access_State_Set -_efl_ui_toolbar_item_efl_access_state_set_get(Eo *eo_it, Efl_Ui_Toolbar_Item_Data *item EINA_UNUSED) -{ - Efl_Access_State_Set ret; - Eina_Bool sel; - - ret = efl_access_state_set_get(efl_super(eo_it, EFL_UI_TOOLBAR_ITEM_CLASS)); - - sel = efl_ui_item_selected_get(eo_it); - - STATE_TYPE_SET(ret, EFL_ACCESS_STATE_SELECTABLE); - - if (sel) - STATE_TYPE_SET(ret, EFL_ACCESS_STATE_SELECTED); - - return ret; -} - -EOLIAN static Elm_Object_Item * -_efl_ui_toolbar_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - return sd->focused_item; -} - -EOLIAN static void -_efl_ui_toolbar_class_constructor(Efl_Class *klass) -{ - evas_smart_legacy_type_register(MY_CLASS_NAME, klass); -} - -EOLIAN static const Efl_Access_Action_Data* -_efl_ui_toolbar_efl_access_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd EINA_UNUSED) -{ - static Efl_Access_Action_Data atspi_actions[] = { - { "select", "select", NULL, _key_action_select}, - { NULL, NULL, NULL, NULL } - }; - return &atspi_actions[0]; -} - -EOLIAN static Eina_List* -_efl_ui_toolbar_efl_access_children_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *sd) -{ - Eina_List *ret = NULL, *ret2 = NULL; - Efl_Ui_Toolbar_Item_Data *it; - ret2 = efl_access_children_get(efl_super(obj, EFL_UI_TOOLBAR_CLASS)); - - EINA_INLIST_FOREACH(sd->items, it) - ret = eina_list_append(ret, EO_OBJ(it)); - - return eina_list_merge(ret, ret2); -} - -EOLIAN static Efl_Access_State_Set -_efl_ui_toolbar_efl_access_state_set_get(Eo *obj, Efl_Ui_Toolbar_Data *sd EINA_UNUSED) -{ - return efl_access_state_set_get(efl_super(obj, EFL_UI_TOOLBAR_CLASS)); -} - -EOLIAN int -_efl_ui_toolbar_efl_access_selection_selected_children_count_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd) -{ - return pd->selected_item ? 1 : 0; -} - -EOLIAN Eo* -_efl_ui_toolbar_efl_access_selection_selected_child_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd, int child_idx) +EOLIAN void +_efl_ui_toolbar_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd) { - if (child_idx != 0) - return NULL; - - return pd->selected_item; + _sizing_calc(pd); } -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_child_select(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd, int child_index) +EOLIAN static const Efl_Class * +_efl_ui_toolbar_efl_ui_item_list_item_class_get(Eo *obj EINA_UNUSED, + Efl_Ui_Toolbar_Data *pd EINA_UNUSED) { - Efl_Ui_Toolbar_Item_Data *item; - EINA_INLIST_FOREACH(pd->items, item) - { - if (child_index-- == 0) - { - efl_ui_item_selected_set(EO_OBJ(item), EINA_TRUE); - return EINA_TRUE; - } - } - return EINA_FALSE; + return EFL_UI_TOOLBAR_ITEM_CLASS; } -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd, int child_index) +EOLIAN static Efl_Ui_Item * +_efl_ui_toolbar_efl_ui_item_list_item_add(Eo *obj, Efl_Ui_Toolbar_Data *pd, + const char *text, const char *icon) { - if (child_index != 0) - return EINA_FALSE; + Efl_Ui_Item *item = efl_ui_item_list_item_add(efl_super(obj, MY_CLASS), text, icon); + EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL); - if (!pd->selected_item) - return EINA_FALSE; - - efl_ui_item_selected_set(pd->selected_item, EINA_FALSE); - - return EINA_TRUE; + efl_pack(pd->bx, efl_ui_item_view_get(item)); + return item; } -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_is_child_selected(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd, int child_index) -{ - Efl_Ui_Toolbar_Item_Data *item; - EINA_INLIST_FOREACH(pd->items, item) - { - if (child_index-- == 0) - { - return efl_ui_item_selected_get(EO_OBJ(item)); - } - } - return EINA_FALSE; -} +// =========================================================================== +// Toolbar Item +// =========================================================================== -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_all_children_select(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd EINA_UNUSED) -{ - return EINA_FALSE; -} +#undef MY_CLASS +#define MY_CLASS EFL_UI_TOOLBAR_ITEM_CLASS -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_clear(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd) -{ - if (pd->selected_item) - efl_ui_item_selected_set(pd->selected_item, EINA_FALSE); - return EINA_TRUE; -} +typedef struct { + Efl_Ui_Toolbar_Item *self; + Efl_Ui_Toolbar *parent; + Efl_Ui_Layout *view; +} Efl_Ui_Toolbar_Item_Data; -EOLIAN Eina_Bool -_efl_ui_toolbar_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Data *pd, int child_index) +EOLIAN static Eo * +_efl_ui_toolbar_item_efl_object_constructor(Eo *obj, Efl_Ui_Toolbar_Item_Data *pd) { - Efl_Ui_Toolbar_Item_Data *item; + pd->self = obj; + obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->parent = efl_parent_get(obj); - EINA_INLIST_FOREACH(pd->items, item) - { - if (child_index-- == 0) - { - efl_ui_item_selected_set(EO_OBJ(item), EINA_FALSE); - return EINA_TRUE; - } - } - return EINA_FALSE; + return obj; } -EOLIAN void -_efl_ui_toolbar_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Toolbar_Data *pd EINA_UNUSED) +EOLIAN static Eo * +_efl_ui_toolbar_item_efl_object_finalize(Eo *obj, Efl_Ui_Toolbar_Item_Data *pd) { - _sizing_eval(obj); -} + const char *style; -static Eina_Bool -_part_of_chain(Efl_Ui_Toolbar_Item_Data *pd) -{ - Eina_Bool want = EINA_TRUE; - if (elm_wdg_item_disabled_get(pd->base->eo_obj)) - want = EINA_FALSE; + obj = efl_finalize(efl_super(obj, MY_CLASS)); - if (!evas_object_visible_get(VIEW(pd))) - want = EINA_FALSE; + // Always realized. + style = efl_ui_widget_style_get(pd->parent); + pd->view = efl_add(EFL_UI_LAYOUT_CLASS, pd->parent, + efl_ui_widget_style_set(efl_added, style), + efl_ui_layout_theme_set(efl_added, "toolbar", "item", style)); - return want; + return obj; } -EOLIAN static void -_efl_ui_toolbar_efl_ui_focus_composition_prepare(Eo *obj, Efl_Ui_Toolbar_Data *pd) +EOLIAN static Efl_Ui_Layout * +_efl_ui_toolbar_item_efl_ui_item_item_view_get(Eo *obj EINA_UNUSED, Efl_Ui_Toolbar_Item_Data *pd) { - Efl_Ui_Toolbar_Item_Data *it; - Eina_List *order = NULL; - - EINA_INLIST_FOREACH(pd->items, it) - { - if (_part_of_chain(it)) - order = eina_list_append(order, EO_OBJ(it)); - } - - efl_ui_focus_composition_elements_set(obj, order); + return pd->view; } -/* Standard widget overrides */ -ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_toolbar, Efl_Ui_Toolbar_Data) - #include "efl_ui_toolbar.eo.c" #include "efl_ui_toolbar_item.eo.c" diff --git a/src/lib/elementary/efl_ui_toolbar.eo b/src/lib/elementary/efl_ui_toolbar.eo index 26980a3486..a2f2f8df01 100644 --- a/src/lib/elementary/efl_ui_toolbar.eo +++ b/src/lib/elementary/efl_ui_toolbar.eo @@ -1,188 +1,18 @@ -import elm_general; - -class Efl.Ui.Toolbar (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Efl.Ui.Direction, - Efl.Access.Widget.Action, Efl.Access.Selection, - Efl.Ui.Clickable, Efl.Ui.Selectable, Efl.Ui.Menu) +class Efl.Ui.Toolbar (Efl.Ui.Item_List, + Efl.Ui.Direction) { [[Toolbar widget A toolbar displays a list of items inside. Among them, only one can be selected at a time. ]] - methods { - item_insert_before { - [[Insert a new item into the toolbar object before item $before. - - A new item will be created and added to the toolbar. Its position in - this toolbar will be just before item $before. - - Items created with this method can be deleted with - elm_object_item_del(). - - Associated $data can be properly freed when item is deleted if a - callback function is set with elm_object_item_del_cb_set(). - - If a function is passed as argument, it will be called every time this item - is selected, i.e., the user clicks over an unselected item. - If such function isn't needed, just passing - $NULL as $func is enough. The same should be done for $data. - - Toolbar will load icon image from fdo or current theme. - This behavior can be set by elm_toolbar_icon_order_lookup_set() function. - If an absolute path is provided it will load it direct from a file. - - Note: This function does not accept relative icon path. - - See: elm_toolbar_item_icon_set()]] - - return: Elm.Widget.Item; [[The created item or $NULL upon failure.]] - params { - @in before: Elm.Widget.Item; [[The toolbar item to insert before.]] - @in icon: string @optional; [[A string with icon name or the absolute path of an image file.]] - @in label: string; [[The label of the item.]] - @in func: Evas_Smart_Cb @optional; [[The function to call when the item is clicked.]] - @in data: const(void_ptr) @optional; [[The data to associate with the item for related callbacks.]] - } - } - item_insert_after { - [[Insert a new item into the toolbar object after item $after. - - A new item will be created and added to the toolbar. Its position in - this toolbar will be just after item $after. - - Items created with this method can be deleted with - elm_object_item_del(). - - Associated $data can be properly freed when item is deleted if a - callback function is set with elm_object_item_del_cb_set(). - - If a function is passed as argument, it will be called every time this item - is selected, i.e., the user clicks over an unselected item. - If such function isn't needed, just passing - $NULL as $func is enough. The same should be done for $data. - - Toolbar will load icon image from fdo or current theme. - This behavior can be set by elm_toolbar_icon_order_lookup_set() function. - If an absolute path is provided it will load it direct from a file. - - Note: This function does not accept relative icon path. - - See: elm_toolbar_item_icon_set()]] - - return: Elm.Widget.Item; [[The created item or $NULL upon failure.]] - params { - @in after: Elm.Widget.Item; [[The toolbar item to insert after.]] - @in icon: string @optional; [[A string with icon name or the absolute path of an image file.]] - @in label: string; [[The label of the item.]] - @in func: Evas_Smart_Cb @optional; [[The function to call when the item is clicked.]] - @in data: const(void_ptr) @optional; [[The data to associate with the item for related callbacks.]] - } - } - item_append { - [[Append item to the toolbar. - - A new item will be created and appended to the toolbar, i.e., will - be set as last item. - - Items created with this method can be deleted with - elm_object_item_del(). - - Associated $data can be properly freed when item is deleted if a - callback function is set with elm_object_item_del_cb_set(). - - If a function is passed as argument, it will be called every time this item - is selected, i.e., the user clicks over an unselected item. - If such function isn't needed, just passing - $NULL as $func is enough. The same should be done for $data. - - Toolbar will load icon image from fdo or current theme. - This behavior can be set by elm_toolbar_icon_order_lookup_set() function. - If an absolute path is provided it will load it direct from a file. - - Note: This function does not accept relative icon path. - - See: elm_toolbar_item_icon_set()]] - - return: Elm.Widget.Item; [[The created item or $NULL upon failure.]] - params { - @in icon: string @optional; [[A string with icon name or the absolute path of an image file.]] - @in label: string; [[The label of the item.]] - @in func: Evas_Smart_Cb @optional; [[The function to call when the item is clicked.]] - @in data: const(void_ptr) @optional; [[The data to associate with the item for related callbacks.]] - } - } - items_count @const { - [[Get the number of items in a toolbar]] - return: uint; [[The number of items in $obj toolbar]] - } - item_prepend { - [[Prepend item to the toolbar. - - A new item will be created and prepended to the toolbar, i.e., will - be set as first item. - - Items created with this method can be deleted with - elm_object_item_del(). - - Associated $data can be properly freed when item is deleted if a - callback function is set with elm_object_item_del_cb_set(). - - If a function is passed as argument, it will be called every time this item - is selected, i.e., the user clicks over an unselected item. - If such function isn't needed, just passing - $NULL as $func is enough. The same should be done for $data. - - Toolbar will load icon image from fdo or current theme. - This behavior can be set by elm_toolbar_icon_order_lookup_set() function. - If an absolute path is provided it will load it direct from a file. - - Note: This function does not accept relative icon path. - - See: elm_toolbar_item_icon_set()]] - - return: Elm.Widget.Item; [[The created item or $NULL upon failure.]] - params { - @in icon: string @optional; [[A string with icon name or the absolute path of an image file.]] - @in label: string; [[The label of the item.]] - @in func: Evas_Smart_Cb @optional; [[The function to call when the item is clicked.]] - @in data: const(void_ptr) @optional; [[The data to associate with the item for related callbacks.]] - } - } - } implements { - class.constructor; Efl.Object.constructor; - Efl.Object.destructor; - Efl.Gfx.position { set; } - Efl.Gfx.size { set; } Efl.Canvas.Group.group_calculate; - Elm.Widget.on_access_update; Elm.Widget.theme_apply; - Elm.Widget.on_focus_update; - Efl.Ui.Translatable.translation_update; - Elm.Widget.widget_event; - Elm.Widget.focus_highlight_geometry { get; } - Elm.Widget.focused_item { get; } - Efl.Ui.Direction.direction { get; set; [[Only supports $vertical and $horizontal. Default is $horizontal.]] } - Efl.Access.Widget.Action.elm_actions { get; } - Efl.Access.children { get; } - Efl.Access.state_set { get; } - Efl.Access.Selection.selected_children_count { get; } - Efl.Access.Selection.selected_child { get; } - Efl.Access.Selection.selected_child_deselect; - Efl.Access.Selection.child_select; - Efl.Access.Selection.child_deselect; - Efl.Access.Selection.is_child_selected; - Efl.Access.Selection.all_children_select; - Efl.Access.Selection.clear; - Efl.Ui.Menu.selected_item { get; } - Efl.Ui.Menu.first_item { get; } - Efl.Ui.Menu.last_item { get; } - Efl.Ui.Menu.items { get; } - Efl.Ui.Focus.Composition.prepare; - } - events { - item,focused; [[Called when toolbar item got focus]] - item,unfocused; [[Called when toolbar item lost focus]] + Efl.Ui.Direction.direction { get; set; [[Only supports $vertical and + $horizontal. Default is $horizontal.]] } + Efl.Ui.Item_List.item_add; + Efl.Ui.Item_List.item_class { get; } } } diff --git a/src/lib/elementary/efl_ui_toolbar_item.eo b/src/lib/elementary/efl_ui_toolbar_item.eo index 0e016b3234..04a11f9940 100644 --- a/src/lib/elementary/efl_ui_toolbar_item.eo +++ b/src/lib/elementary/efl_ui_toolbar_item.eo @@ -1,81 +1,8 @@ -class Efl.Ui.Toolbar.Item(Elm.Widget.Item, Efl.Ui.Item, Efl.Ui.Focus.Object) +class Efl.Ui.Toolbar.Item (Efl.Ui.Item) { - [[Toolbar widget item class]] - methods { - @property icon { - get { - [[Get the string used to set the icon of $item.]] - } - set { - [[Set the icon associated with $item. - - Toolbar will load icon image from fdo or current theme. - This behavior can be set by - elm_toolbar_icon_order_lookup_set function. - If an absolute path is provided it will load it direct - from a file. - - Note: This function does not accept relative icon path. - ]] - } - values { - icon: string; [[A string with icon name or the - absolute path of an image file.]] - } - } - @property icon_object { - get { - [[Get the icon object of $item. - - See also @.icon.set, @.icon_file_set, @.icon_memfile_set. - ]] - } - values { - obj: Efl.Canvas.Object; [[The icon object.]] - } - } - icon_memfile_set { - [[Set the icon associated with $item to an image in a binary buffer. - - Note: The icon image set by this function can be changed by - @.icon.set. - ]] - params { - @in img: const(void_ptr); [[The binary data that will be used as an image.]] - @in size: size; [[The size of binary data $img.]] - @in format: string; [[Optional format of $img to pass to the image loader.]] - @in key: string; [[Optional key of $img to pass to the image loader (eg. if $img is an edje file).]] - } - return: bool; [[$true on success, $false otherwise]] - } - icon_file_set { - [[Set the icon associated with $item to an image in a binary buffer. - - Note: The icon image set by this function can be changed by - elm_toolbar_item_icon_set(). - ]] - params { - @in file: string; [[The file that contains the image.]] - @in key: string; [[Optional key of $img to pass to the image loader (eg. if $img is an edje file).]] - } - return: bool; [[$true on success, $false otherwise]] - } - } - implements { - Efl.Object.constructor; - Efl.Object.destructor; - Elm.Widget.Item.disable; - Elm.Widget.Item.focus { get; set; } - Elm.Widget.Item.signal_emit; - Elm.Widget.Item.part_text { get; set; } - Elm.Widget.Item.part_content { get; set; } - Elm.Widget.Item.part_content_unset; - Efl.Ui.Focus.Object.focus_geometry { get; } - Efl.Ui.Focus.Object.focus { set; } - Efl.Access.name { get; } - Efl.Access.state_set { get; } - Efl.Ui.Item.selected { get; set; } - Efl.Ui.Item.prev { get; } - Efl.Ui.Item.next { get; } - } + implements { + Efl.Object.constructor; + Efl.Object.finalize; + Efl.Ui.Item.item_view { get; } + } } diff --git a/src/lib/elementary/efl_ui_toolbar_private.h b/src/lib/elementary/efl_ui_toolbar_private.h deleted file mode 100644 index 030c0e6b89..0000000000 --- a/src/lib/elementary/efl_ui_toolbar_private.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef EFL_UI_TOOLBAR_PRIVATE_H -#define EFL_UI_TOOLBAR_PRIVATE_H - -/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR - * CODE. THIS IS EFL_UI'S INTERNAL WIDGET API (for now) AND IS NOT - * FINAL. - */ - -/** - * @addtogroup Widget - * @{ - * - * @section efl-ui-toolbar-class The Efl Ui Toolbar Class - * - */ - -typedef struct _Efl_Ui_Toolbar_Item_Data Efl_Ui_Toolbar_Item_Data; - -/** - * Base widget smart data extended with toolbar instance data. - */ -typedef struct _Efl_Ui_Toolbar_Data Efl_Ui_Toolbar_Data; -struct _Efl_Ui_Toolbar_Data -{ - Evas_Object *bx; - Eina_Inlist *items; - Elm_Object_Item *selected_item; /**< a selected item by mouse click, return key, api, and etc. */ - Elm_Object_Item *focused_item; /**< a focused item by keypad arrow or mouse. This is set to NULL if widget looses focus. */ - Elm_Object_Item *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */ - unsigned int item_count; - Efl_Ui_Dir dir; - - Eina_Bool delete_me : 1; -}; - -struct _Efl_Ui_Toolbar_Item_Data -{ - Elm_Widget_Item_Data *base; - EINA_INLIST; - - const char *label; - const char *icon_str; - Evas_Object *icon; - Evas_Object *object; - Evas_Smart_Cb func; - - Eina_Bool selected : 1; -}; - - -/** - * @} - */ - -#define EFL_UI_TOOLBAR_DATA_GET(o, sd) \ - Efl_Ui_Toolbar_Data * sd = efl_data_scope_get(o, EFL_UI_TOOLBAR_CLASS) - -#define EFL_UI_TOOLBAR_CHECK(obj) \ - if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_TOOLBAR_CLASS))) \ - return - -#define EFL_UI_TOOLBAR_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, ); \ - EFL_UI_TOOLBAR_CHECK(it->base->widget); - -#define EFL_UI_TOOLBAR_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN(it->base, __VA_ARGS__); \ - EFL_UI_TOOLBAR_CHECK(it->base->widget) __VA_ARGS__; - -#define EFL_UI_TOOLBAR_ITEM_DATA_GET(o, sd) \ - Efl_Ui_Toolbar_Item_Data *sd = efl_data_scope_get(o, EFL_UI_TOOLBAR_ITEM_CLASS) - -#endif -- cgit v1.2.1