From 585ded649f3f94ea59b7b65a989059cd62921ac6 Mon Sep 17 00:00:00 2001 From: Daniel Hirt Date: Thu, 9 Nov 2017 17:56:41 +0200 Subject: Ui text: add ability to set item providers Added API to set an item provider factory object. This is similar to the previous item providers that used callbacks. You instantiate a factory object and set it on the Ui.Text object. Each factory implements the "create" method from Efl.Canvas.Text.Factory. This also includes 2 public factories (Image and Emoticon), and one internal for Ui.Text as a fallback. The fallback provider can be disabled via API. See the added "Ui text factory" test in elementary_test for an example of usage. @feature --- src/Makefile_Elementary.am | 6 + src/bin/elementary/test.c | 2 + src/bin/elementary/test_efl_ui_text.c | 201 ++++++++++++++++++++- src/lib/elementary/Elementary.h | 3 + src/lib/elementary/efl_ui_text.c | 120 ++++-------- src/lib/elementary/efl_ui_text.eo | 49 ++--- .../elementary/efl_ui_text_emoticon_item_factory.c | 52 ++++++ .../efl_ui_text_emoticon_item_factory.eo | 12 ++ .../elementary/efl_ui_text_fallback_item_factory.c | 62 +++++++ .../efl_ui_text_fallback_item_factory.eo | 16 ++ .../elementary/efl_ui_text_image_item_factory.c | 97 ++++++++++ .../elementary/efl_ui_text_image_item_factory.eo | 42 +++++ 12 files changed, 543 insertions(+), 119 deletions(-) create mode 100644 src/lib/elementary/efl_ui_text_emoticon_item_factory.c create mode 100644 src/lib/elementary/efl_ui_text_emoticon_item_factory.eo create mode 100644 src/lib/elementary/efl_ui_text_fallback_item_factory.c create mode 100644 src/lib/elementary/efl_ui_text_fallback_item_factory.eo create mode 100644 src/lib/elementary/efl_ui_text_image_item_factory.c create mode 100644 src/lib/elementary/efl_ui_text_image_item_factory.eo diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 95d1cf8976..8e300b9add 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -33,6 +33,9 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_text.eo \ lib/elementary/efl_ui_text_editable.eo \ lib/elementary/efl_ui_text_async.eo \ + lib/elementary/efl_ui_text_image_item_factory.eo \ + lib/elementary/efl_ui_text_emoticon_item_factory.eo \ + lib/elementary/efl_ui_text_fallback_item_factory.eo \ lib/elementary/efl_ui_textpath.eo \ lib/elementary/efl_ui_translatable.eo \ lib/elementary/efl_ui_clock.eo \ @@ -689,6 +692,9 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_grid_static.c \ lib/elementary/efl_ui_grid_private.h \ lib/elementary/efl_ui_text.c \ + lib/elementary/efl_ui_text_emoticon_item_factory.c \ + lib/elementary/efl_ui_text_image_item_factory.c \ + lib/elementary/efl_ui_text_fallback_item_factory.c \ lib/elementary/efl_ui_clock.c \ lib/elementary/efl_ui_clock_private.h \ lib/elementary/efl_ui_image_factory.c \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index 57b1916d53..0d30541c46 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -316,6 +316,7 @@ void test_code_diff_inline(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_text_async(void *data, Evas_Object *obj, void *event_info); +void test_ui_text_item_factory(void *data, Evas_Object *obj, void *event_info); void test_evas_mask(void *data, Edje_Object *obj, void *event_info); void test_gfx_filters(void *data, Evas_Object *obj, void *event_info); void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info); @@ -778,6 +779,7 @@ add_tests: ADD_TEST(NULL, "Entries", "Efl UI Text", test_efl_ui_text); ADD_TEST(NULL, "Entries", "Efl UI Text Label", test_efl_ui_text_label); ADD_TEST(NULL, "Entries", "Efl UI Text Async", test_efl_ui_text_async); + ADD_TEST(NULL, "Entries", "UI Text Item Provider", test_ui_text_item_factory); //------------------------------// ADD_TEST(NULL, "Advanced Entries", "Code Entry Markup", test_code_welcome); diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c index b53c427b9a..3f41e801de 100644 --- a/src/bin/elementary/test_efl_ui_text.c +++ b/src/bin/elementary/test_efl_ui_text.c @@ -187,6 +187,7 @@ test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve { Evas_Object *win, *bx, *bx2, *bx3, *bt, *en; Efl_Text_Cursor_Cursor *main_cur, *cur; + char buf[128]; win = elm_win_util_standard_add("entry", "Entry"); elm_win_autodel_set(win, EINA_TRUE); @@ -215,9 +216,12 @@ test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve cur = efl_text_cursor_new(en); efl_text_cursor_position_set(en, cur, 2); - efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon"); + efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon/happy"); efl_text_cursor_position_set(en, cur, 50); - efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon"); + + sprintf(buf, "size=32x32 href=file://%s/images/sky_01.jpg", + elm_app_data_dir_get()); + efl_text_cursor_object_item_insert(en, cur, buf); efl_text_cursor_position_set(en, main_cur, 5); efl_text_cursor_position_set(en, cur, 20); @@ -297,7 +301,7 @@ test_efl_ui_text_async(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi elm_win_resize_object_add(win, bx); evas_object_show(bx); - en = efl_add(EFL_UI_TEXT_ASYNC_CLASS, win, + en = efl_add(EFL_UI_TEXT_CLASS, win, efl_text_wrap_set(efl_added, EFL_TEXT_FORMAT_WRAP_WORD), efl_text_multiline_set(efl_added, EINA_TRUE) ); @@ -332,3 +336,194 @@ test_efl_ui_text_async(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi evas_object_resize(win, 480, 320); evas_object_show(win); } + +static const char *images[4] = { "sky", "logo", "dog" }; + +static void +my_efl_ui_text_item_factory_bt_image(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *en = data; + char buf[128]; + + static int image_idx = 0; + image_idx = (image_idx + 1) % 5; + if (image_idx == 3) + { + sprintf(buf, "size=32x32 href=file://%s/images/sky_02.jpg", + elm_app_data_dir_get()); + } + else if (image_idx == 4) + { + sprintf(buf, "size=32x32 href=%s/images/sky_03.jpg", + elm_app_data_dir_get()); + } + else + { + sprintf(buf, "size=32x32 href=%s", images[image_idx]); + } + printf("Adding image: %s\n", buf); + efl_text_cursor_object_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN), + buf); +} + +static void +my_efl_ui_text_item_factory_bt_emoticon(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *en = data; + efl_text_cursor_object_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN), + "size=32x32 href=emoticon/evil-laugh"); +} + +static void +my_efl_ui_text_item_factory_bt_fallback(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *en = data; + efl_ui_text_item_provider_fallback_disabled_set(en, + !efl_ui_text_item_provider_fallback_disabled_get(en)); + printf("Fallback changed to: %s\n", + efl_ui_text_item_provider_fallback_disabled_get(en) ? + "disabled" : "enabled"); + +} + +static struct +{ + const char *name; + Eo *item_factory; +} factories[3]; + +static void +my_efl_ui_text_item_factory_bt_change(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *en = data; + static int item_factory_idx = 0; + + item_factory_idx = (item_factory_idx + 1) % 3; + efl_ui_text_item_factory_set(en, factories[item_factory_idx].item_factory); + printf("Factory set to: %s\n", factories[item_factory_idx].name); +} + +void +test_ui_text_item_factory(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *win, *bx, *bx2, *bx3, *bt, *en; + Efl_Text_Cursor_Cursor *main_cur, *cur; + char buf[128]; + + win = elm_win_util_standard_add("entry", "Entry"); + elm_win_autodel_set(win, EINA_TRUE); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + en = efl_add(EFL_UI_TEXT_CLASS, win, + efl_text_multiline_set(efl_added, EINA_TRUE)); + + factories[0].name = "None"; + factories[0].item_factory = NULL; + + factories[1].name = "Image Factory"; + factories[1].item_factory = efl_add(EFL_UI_TEXT_IMAGE_ITEM_FACTORY_CLASS, en); + + factories[2].name = "Emoticon Factory"; + factories[2].item_factory = efl_add(EFL_UI_TEXT_EMOTICON_ITEM_FACTORY_CLASS, en); + + sprintf(buf, "%s/images/sky_01.jpg", elm_app_data_dir_get()); + efl_ui_text_image_item_factory_matches_add(factories[1].item_factory, + images[0], buf, NULL); + sprintf(buf, "%s/images/logo.png", elm_app_data_dir_get()); + efl_ui_text_image_item_factory_matches_add(factories[1].item_factory, + images[1], buf, NULL); + sprintf(buf, "%s/images/mystrale.jpg", elm_app_data_dir_get()); + efl_ui_text_image_item_factory_matches_add(factories[1].item_factory, + images[2], buf, NULL); + + printf("Added Efl.Ui.Text object\n"); + efl_text_set(en, "Hello world! Goodbye world! This is a test text for the" + " new UI Text widget.\xE2\x80\xA9This is the next paragraph.\nThis" + " is the next line.\nThis is Yet another line! Line and paragraph" + " separators are actually different!"); + efl_text_font_set(en, "Sans", 14); + efl_text_normal_color_set(en, 255, 255, 255, 255); + + main_cur = efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN); + cur = efl_text_cursor_new(en); + + efl_text_cursor_position_set(en, cur, 2); + efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon/happy"); + efl_text_cursor_position_set(en, cur, 50); + + sprintf(buf, "size=32x32 href=file://%s/images/sky_01.jpg", + elm_app_data_dir_get()); + efl_text_cursor_object_item_insert(en, cur, buf); + efl_text_cursor_position_set(en, main_cur, 5); + + efl_ui_text_interactive_editable_set(en, EINA_TRUE); + efl_ui_text_scrollable_set(en, EINA_TRUE); + elm_box_pack_end(bx, en); + elm_object_focus_set(en, EINA_TRUE); + + bx2 = elm_box_add(win); + elm_box_horizontal_set(bx2, EINA_TRUE); + evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Image"); + evas_object_smart_callback_add(bt, "clicked", + my_efl_ui_text_item_factory_bt_image, en); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx2, bt); + elm_object_focus_allow_set(bt, EINA_FALSE); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Emoticon"); + evas_object_smart_callback_add(bt, "clicked", + my_efl_ui_text_item_factory_bt_emoticon, en); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx2, bt); + elm_object_focus_allow_set(bt, EINA_FALSE); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Factory"); + evas_object_smart_callback_add(bt, "clicked", + my_efl_ui_text_item_factory_bt_change, en); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx2, bt); + elm_object_focus_allow_set(bt, EINA_FALSE); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Fallback"); + evas_object_smart_callback_add(bt, "clicked", + my_efl_ui_text_item_factory_bt_fallback, en); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx2, bt); + elm_object_focus_allow_set(bt, EINA_FALSE); + evas_object_show(bt); + + bx3 = elm_box_add(win); + elm_box_horizontal_set(bx3, EINA_TRUE); + evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(bx3, EVAS_HINT_FILL, EVAS_HINT_FILL); + + elm_box_pack_end(bx, bx3); + elm_box_pack_end(bx, bx2); + evas_object_show(bx3); + evas_object_show(bx2); + + evas_object_resize(win, 480, 320); + evas_object_show(win); +} diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 806e04821e..f3214d9e79 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -280,6 +280,9 @@ EAPI extern Elm_Version *elm_version; # include # include # include +# include +# include +# include # include # include # include diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index c1b9bd7287..c80d378fe4 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -63,7 +63,8 @@ struct _Efl_Ui_Text_Data Eina_List *sel; Eina_List *items; /** context menu item list */ Item_Obj *item_objs; - Eina_List *item_providers; + Efl_Canvas_Text_Item_Factory *item_factory_fallback; + Efl_Canvas_Text_Item_Factory *item_factory; Eina_List *markup_filters; Ecore_Job *hov_deljob; Mod_Api *api; // module api if supplied @@ -131,6 +132,7 @@ struct _Efl_Ui_Text_Data Eina_Bool scroll : 1; Eina_Bool input_panel_show_on_demand : 1; Eina_Bool anchors_updated : 1; + Eina_Bool fallback_item_provider_disabled : 1; }; struct _Anchor @@ -2557,43 +2559,22 @@ _entry_mouse_triple_signal_cb(void *data, static Evas_Object * _item_get(void *data, const char *item) { - Eina_List *l; - Evas_Object *o; - Elm_Entry_Item_Provider *ip; - const char *style = elm_widget_style_get(data); + Evas_Object *o = NULL; EFL_UI_TEXT_DATA_GET(data, sd); - EINA_LIST_FOREACH(sd->item_providers, l, ip) - { - o = ip->func(ip->data, data, item); - if (o) return o; - } - if (item && !strncmp(item, "file://", 7)) + if (item) { - const char *fname = item + 7; - - o = evas_object_image_filled_add(evas_object_evas_get(data)); - evas_object_image_file_set(o, fname, NULL); - if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE) + if (sd->item_factory) { - evas_object_show(o); + o = efl_canvas_text_item_factory_create(sd->item_factory, data, item); } - else + if (!o && !sd->fallback_item_provider_disabled) { - evas_object_del(o); - o = edje_object_add(evas_object_evas_get(data)); - elm_widget_theme_object_set - (data, o, "entry/emoticon", "wtf", style); + o = efl_canvas_text_item_factory_create(sd->item_factory_fallback, + data, item); } - return o; } - - o = edje_object_add(evas_object_evas_get(data)); - if (!elm_widget_theme_object_set - (data, o, "entry", item, style)) - elm_widget_theme_object_set - (data, o, "entry/emoticon", "wtf", style); return o; } @@ -3182,6 +3163,7 @@ _efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv) if (_elm_config->desktop_entry) priv->sel_handler_disabled = EINA_TRUE; + priv->item_factory_fallback = efl_add(EFL_UI_TEXT_FALLBACK_ITEM_FACTORY_CLASS, obj); _create_text_cursors(obj, priv); } @@ -3264,10 +3246,6 @@ _efl_ui_text_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Text_Data *sd) eina_stringshare_del(it->icon_group); free(it); } - EINA_LIST_FREE(sd->item_providers, ip) - { - free(ip); - } EINA_LIST_FREE(sd->markup_filters, tf) { _filter_free(tf); @@ -3304,6 +3282,7 @@ _efl_ui_text_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Text_Data *sd) // a specific behavior of SWALLOW parts. efl_del(sd->text_obj); sd->text_obj = NULL; + if (sd->item_factory_fallback) efl_del(sd->item_factory_fallback); efl_canvas_group_del(efl_super(obj, MY_CLASS)); } @@ -3619,55 +3598,6 @@ _efl_ui_text_context_menu_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd return !sd->context_menu; } -EOLIAN static void -_efl_ui_text_item_provider_append(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data) -{ - Elm_Entry_Item_Provider *ip; - - EINA_SAFETY_ON_NULL_RETURN(func); - - ip = calloc(1, sizeof(Elm_Entry_Item_Provider)); - if (!ip) return; - - ip->func = func; - ip->data = data; - sd->item_providers = eina_list_append(sd->item_providers, ip); -} - -EOLIAN static void -_efl_ui_text_item_provider_prepend(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data) -{ - Elm_Entry_Item_Provider *ip; - - EINA_SAFETY_ON_NULL_RETURN(func); - - ip = calloc(1, sizeof(Elm_Entry_Item_Provider)); - if (!ip) return; - - ip->func = func; - ip->data = data; - sd->item_providers = eina_list_prepend(sd->item_providers, ip); -} - -EOLIAN static void -_efl_ui_text_item_provider_remove(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data) -{ - Eina_List *l; - Elm_Entry_Item_Provider *ip; - - EINA_SAFETY_ON_NULL_RETURN(func); - - EINA_LIST_FOREACH(sd->item_providers, l, ip) - { - if ((ip->func == func) && ((!data) || (ip->data == data))) - { - sd->item_providers = eina_list_remove_list(sd->item_providers, l); - free(ip); - return; - } - } -} - EOLIAN static Eina_Bool _efl_ui_text_efl_file_file_set(Eo *obj, Efl_Ui_Text_Data *sd, const char *file, const char *group EINA_UNUSED) { @@ -5375,6 +5305,32 @@ _efl_ui_text_move_cb(void *data, Evas *e EINA_UNUSED, _decoration_defer_all(data); } +static void +_efl_ui_text_item_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd, + Efl_Canvas_Text_Item_Factory *item_factory) +{ + pd->item_factory = item_factory; +} + +static Eo * +_efl_ui_text_item_factory_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd) +{ + return pd->item_factory; +} + +static void +_efl_ui_text_item_provider_fallback_disabled_set(Eo *obj EINA_UNUSED, + Efl_Ui_Text_Data *pd, Eina_Bool disabled) +{ + pd->fallback_item_provider_disabled = disabled; +} + +static Eina_Bool +_efl_ui_text_item_provider_fallback_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd) +{ + return pd->fallback_item_provider_disabled; +} + #if 0 /* Efl.Part begin */ diff --git a/src/lib/elementary/efl_ui_text.eo b/src/lib/elementary/efl_ui_text.eo index 67ad82d034..d2e1aff32d 100644 --- a/src/lib/elementary/efl_ui_text.eo +++ b/src/lib/elementary/efl_ui_text.eo @@ -232,13 +232,22 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable, enabled: bool; [[If $enabled is $true, the return key is automatically disabled when the entry has no text.]] } } - item_provider_prepend { - [[This prepends a custom item provider to the list for that entry + @property item_factory { + [[The factory that provides items for "href" items e.g. + "href=emoticon/happy" or "href=file://image.jpg" + ]] + values { + item_factory: Efl.Canvas.Text.Item_Factory; [[Factory to create items]] + } + } + @property item_provider_fallback_disabled { + [[Fallback to internal item provider. - This prepends the given callback.]] - params { - @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]] - @in data: void_ptr @optional; [[The data passed to $func.]] + This will query the internal item provider for object items, in case + there was no result querying the set item_provider. + ]] + values { + disabled: bool; } } input_panel_show { @@ -251,17 +260,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable, selection_copy { [[This executes a "copy" action on the selected text in the entry.]] } - item_provider_remove { - [[This removes a custom item provider to the list for that entry - - This removes the given callback. See @.item_provider_append for - more information - ]] - params { - @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]] - @in data: void_ptr @optional; [[The data passed to $func.]] - } - } context_menu_clear { [[This clears and frees the items in a entry's contextual (longpress) menu. @@ -305,23 +303,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable, selection_cut { [[This executes a "cut" action on the selected text in the entry.]] } - item_provider_append { - [[This appends a custom item provider to the list for that entry - - This appends the given callback. The list is walked from beginning to end - with each function called given the item href string in the text. If the - function returns an object handle other than $null (it should create an - object to do this), then this object is used to replace that item. If - not the next provider is called until one provides an item object, or the - default provider in entry does. - - See also \@ref entry-items. - ]] - params { - @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]] - @in data: void_ptr @optional; [[The data passed to $func.]] - } - } context_menu_item_add { [[This adds an item to the entry's contextual menu. diff --git a/src/lib/elementary/efl_ui_text_emoticon_item_factory.c b/src/lib/elementary/efl_ui_text_emoticon_item_factory.c new file mode 100644 index 0000000000..022446d47e --- /dev/null +++ b/src/lib/elementary/efl_ui_text_emoticon_item_factory.c @@ -0,0 +1,52 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include +#include "elm_priv.h" + +#define MY_CLASS EFL_UI_TEXT_EMOTICON_ITEM_FACTORY_CLASS + +typedef struct _Efl_Ui_Text_Emoticon_Item_Factory_Data Efl_Ui_Text_Emoticon_Item_Factory_Data; + +struct _Efl_Ui_Text_Emoticon_Item_Factory_Data +{ + const char *name; +}; + +EOLIAN static Eo * +_efl_ui_text_emoticon_item_factory_efl_object_constructor(Eo *obj, + Efl_Ui_Text_Emoticon_Item_Factory_Data *pd EINA_UNUSED) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + return obj; +} + +EOLIAN static void +_efl_ui_text_emoticon_item_factory_efl_object_destructor(Eo *obj, + Efl_Ui_Text_Emoticon_Item_Factory_Data *pd EINA_UNUSED) +{ + efl_destructor(efl_super(obj, MY_CLASS)); +} + + +EOLIAN static Efl_Canvas_Object +*_efl_ui_text_emoticon_item_factory_efl_canvas_text_item_factory_create( + Eo *obj EINA_UNUSED, + Efl_Ui_Text_Emoticon_Item_Factory_Data *pd EINA_UNUSED, + Efl_Canvas_Object *object, + const char *key) +{ + Eo *o; + const char *style = elm_widget_style_get(object); + + o = edje_object_add(evas_object_evas_get(object)); + if (!_elm_theme_object_set + (object, o, "entry", key, style)) + _elm_theme_object_set + (object, o, "entry/emoticon", "wtf", style); + return o; +} + +#include "efl_ui_text_emoticon_item_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_text_emoticon_item_factory.eo b/src/lib/elementary/efl_ui_text_emoticon_item_factory.eo new file mode 100644 index 0000000000..b8bc7715dc --- /dev/null +++ b/src/lib/elementary/efl_ui_text_emoticon_item_factory.eo @@ -0,0 +1,12 @@ +class Efl.Ui.Text.Emoticon_Item_Factory (Efl.Object, Efl.Canvas.Text.Item_Factory) +{ + [[Factory that creates emoticons from the current theme given a key. + + @since 1.21 + ]] + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Canvas.Text.Item_Factory.create; + } +} diff --git a/src/lib/elementary/efl_ui_text_fallback_item_factory.c b/src/lib/elementary/efl_ui_text_fallback_item_factory.c new file mode 100644 index 0000000000..5e439259e2 --- /dev/null +++ b/src/lib/elementary/efl_ui_text_fallback_item_factory.c @@ -0,0 +1,62 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include +#include "elm_priv.h" + +#define MY_CLASS EFL_UI_TEXT_FALLBACK_ITEM_FACTORY_CLASS + +typedef struct _Efl_Ui_Text_Fallback_Item_Factory_Data Efl_Ui_Text_Fallback_Item_Factory_Data; + +struct _Efl_Ui_Text_Fallback_Item_Factory_Data +{ + Efl_Canvas_Text_Item_Factory *emoticon_item_factory, *image_item_factory; +}; + +EOLIAN static Eo * +_efl_ui_text_fallback_item_factory_efl_object_constructor(Eo *obj, + Efl_Ui_Text_Fallback_Item_Factory_Data *pd EINA_UNUSED) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->emoticon_item_factory = efl_add(EFL_UI_TEXT_EMOTICON_ITEM_FACTORY_CLASS, obj); + pd->image_item_factory = efl_add(EFL_UI_TEXT_IMAGE_ITEM_FACTORY_CLASS, obj); + return obj; +} + +EOLIAN static void +_efl_ui_text_fallback_item_factory_efl_object_destructor(Eo *obj, + Efl_Ui_Text_Fallback_Item_Factory_Data *pd EINA_UNUSED) +{ + efl_del(pd->emoticon_item_factory); + efl_del(pd->image_item_factory); + efl_destructor(efl_super(obj, MY_CLASS)); +} + + +EOLIAN static Efl_Canvas_Object +*_efl_ui_text_fallback_item_factory_efl_canvas_text_item_factory_create( + Eo *obj EINA_UNUSED, + Efl_Ui_Text_Fallback_Item_Factory_Data *pd EINA_UNUSED, + Efl_Canvas_Object *object, + const char *key) +{ + Efl_Canvas_Object *o = NULL; + + // Parse the string. Can be either: + // 1. some/name - an emoticon (load from theme) + // 2. file:// - image file + if (key && !strncmp(key, "file://", 7)) + { + const char *fname = key + 7; + o = efl_canvas_text_item_factory_create(pd->image_item_factory, object, fname); + } + else + { + o = efl_canvas_text_item_factory_create(pd->emoticon_item_factory, object, key); + } + return o; +} + +#include "efl_ui_text_fallback_item_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_text_fallback_item_factory.eo b/src/lib/elementary/efl_ui_text_fallback_item_factory.eo new file mode 100644 index 0000000000..c4bb90e900 --- /dev/null +++ b/src/lib/elementary/efl_ui_text_fallback_item_factory.eo @@ -0,0 +1,16 @@ +class Efl.Ui.Text.Fallback_Item_Factory (Efl.Object, Efl.Canvas.Text.Item_Factory) +{ + [[Internal factory for fallback cases. + + This wraps some internal functionality: + - Contains 2 factories: image and emoticon + - Strips-off "file://" prefix for image items, to be used with the image + factory. + @since 1.21 + ]] + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Canvas.Text.Item_Factory.create; + } +} diff --git a/src/lib/elementary/efl_ui_text_image_item_factory.c b/src/lib/elementary/efl_ui_text_image_item_factory.c new file mode 100644 index 0000000000..38ce8407ea --- /dev/null +++ b/src/lib/elementary/efl_ui_text_image_item_factory.c @@ -0,0 +1,97 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include +#include "elm_priv.h" + +#define MY_CLASS EFL_UI_TEXT_IMAGE_ITEM_FACTORY_CLASS + +typedef struct _Efl_Ui_Text_Image_Item_Factory_Data Efl_Ui_Text_Image_Item_Factory_Data; + +struct _Efl_Ui_Text_Image_Item_Factory_Data +{ + const char *name; + Eina_Hash *hash; +}; + +typedef struct +{ + const char *file; + const char *key; +} Image_Entry; + +static void +_entry_free_cb(void *data) +{ + Image_Entry *e = data; + eina_stringshare_del(e->file); + eina_stringshare_del(e->key); + free(e); +} + +EOLIAN static Eo * +_efl_ui_text_image_item_factory_efl_object_constructor(Eo *obj, + Efl_Ui_Text_Image_Item_Factory_Data *pd EINA_UNUSED) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->hash = eina_hash_string_superfast_new(_entry_free_cb); + return obj; +} + +EOLIAN static void +_efl_ui_text_image_item_factory_efl_object_destructor(Eo *obj, + Efl_Ui_Text_Image_Item_Factory_Data *pd EINA_UNUSED) +{ + eina_hash_free(pd->hash); + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Canvas_Object +*_efl_ui_text_image_item_factory_efl_canvas_text_item_factory_create(Eo *obj EINA_UNUSED, + Efl_Ui_Text_Image_Item_Factory_Data *pd EINA_UNUSED, + Efl_Canvas_Object *object, + const char *key) +{ + Efl_Canvas_Object *o; + Image_Entry *e; + const char *file = key, *filekey = NULL; + + e = eina_hash_find(pd->hash, key); + if (e) + { + file = e->file; + filekey = e->key; + } + + o = evas_object_image_filled_add(evas_object_evas_get(object)); + evas_object_image_file_set(o, file, filekey); + if (evas_object_image_load_error_get(o) != EVAS_LOAD_ERROR_NONE) + { + evas_object_del(o); + o = NULL; + } + return o; +} + +EOLIAN static Eina_Bool +_efl_ui_text_image_item_factory_matches_add(Eo *obj EINA_UNUSED, + Efl_Ui_Text_Image_Item_Factory_Data *pd, + const char *name, const char *file, const char *key) +{ + Image_Entry *e = malloc(sizeof(*e)); + e->file = eina_stringshare_add(file); + e->key = eina_stringshare_add(key); + return eina_hash_add(pd->hash, name, e); +} + +EOLIAN static Eina_Bool +_efl_ui_text_image_item_factory_matches_del(Eo *obj EINA_UNUSED, + Efl_Ui_Text_Image_Item_Factory_Data *pd, + const char *name) +{ + return eina_hash_del(pd->hash, name, NULL); +} + +#include "efl_ui_text_image_item_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_text_image_item_factory.eo b/src/lib/elementary/efl_ui_text_image_item_factory.eo new file mode 100644 index 0000000000..7911c83981 --- /dev/null +++ b/src/lib/elementary/efl_ui_text_image_item_factory.eo @@ -0,0 +1,42 @@ +class Efl.Ui.Text.Image_Item_Factory (Efl.Object, Efl.Canvas.Text.Item_Factory) +{ + [[Factory that creates images given key string + + The key can be either a full image path, or associated with one. The + factory will fallback if key was not matches with an image, and try + to load it as a full path. + + @since 1.21 + ]] + methods { + matches_add { + [[Associates given name with a filename of an image. + + This can be used for quick retrieval (instead of + providing actual filenames. + ]] + params { + name: string; [[the name associated with filename]] + filename: string; [[the image filename]] + key: string; [[the key to use (in cases of loading an EET file]] + } + return: bool; + } + matches_del { + [[Associated given name with a filename of an image. + + This can be used for quick retrieval (instead of + providing actual filenames. + ]] + params { + key: string; [[the key to use (in cases of loading an EET file]] + } + return: bool; + } + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Canvas.Text.Item_Factory.create; + } +} -- cgit v1.2.1