aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Hirt <hirt.danny@gmail.com>2017-11-09 17:53:20 +0200
committerDaniel Hirt <hirt.danny@gmail.com>2018-01-18 11:01:07 +0200
commit2ff2bae9a02e6d30f52de856810a0c21fc6a52ca (patch)
tree36ac625fb0a0bb10d541a5641bb28a689c539e50
parentEdje: remove item provider from eo api (diff)
downloadefl-devs/herdsman/annotation_item_staging.tar.gz
Canvas image: add Efl.Canvas.Text.Factory + use in Ui.Textdevs/herdsman/annotation_item_staging
This interface has a simple 'create' method to create Efl.Canvas.Object given a key. This is used higher-up in Ui.Text in the next commit. Ui text: add ability to set item factories Added API to set an item factory object. This is similar to the previous item providers (that worked with callbacks). You instantiate a factory object and set it on the Ui.Text object. Each factory implements the "create" method from Efl.Canvas.Text.Item_Factory. This also includes 3 public factories (Image, Emoticon and Fallback): - Image factory: creates images from added entries (key strings) - Emoticon factory: creates emoticons by querying the theme - Fallback: creates image, then falls back to emoticon If no factory is set, then the fallback (internal) factory is used. See the added "Ui.text Item Factory" test in elementary_test for an example of usage. @feature
-rw-r--r--data/elementary/images/Makefile.am3
-rw-r--r--data/elementary/images/image_items.eetbin0 -> 573646 bytes
-rw-r--r--src/Makefile_Elementary.am6
-rw-r--r--src/Makefile_Evas.am1
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_efl_ui_text.c205
-rw-r--r--src/lib/efl/interfaces/efl_text_annotate.eo61
-rw-r--r--src/lib/elementary/Elementary.h3
-rw-r--r--src/lib/elementary/efl_ui_text.c116
-rw-r--r--src/lib/elementary/efl_ui_text.eo41
-rw-r--r--src/lib/elementary/efl_ui_text_factory_emoticons.c52
-rw-r--r--src/lib/elementary/efl_ui_text_factory_emoticons.eo12
-rw-r--r--src/lib/elementary/efl_ui_text_factory_fallback.c62
-rw-r--r--src/lib/elementary/efl_ui_text_factory_fallback.eo16
-rw-r--r--src/lib/elementary/efl_ui_text_factory_images.c147
-rw-r--r--src/lib/elementary/efl_ui_text_factory_images.eo69
-rw-r--r--src/lib/evas/Evas_Eo.h1
-rw-r--r--src/lib/evas/canvas/efl_canvas_text.eo7
-rw-r--r--src/lib/evas/canvas/efl_canvas_text_factory.eo25
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c31
-rw-r--r--src/tests/evas/evas_test_textblock.c12
21 files changed, 711 insertions, 161 deletions
diff --git a/data/elementary/images/Makefile.am b/data/elementary/images/Makefile.am
index 6ecc178d52..6f028257cb 100644
--- a/data/elementary/images/Makefile.am
+++ b/data/elementary/images/Makefile.am
@@ -50,7 +50,8 @@ elementary_images_files = \
elementary/images/pm_fill.png \
elementary/images/pt.png \
elementary/images/earth_normal.png \
- elementary/images/space.png
+ elementary/images/space.png \
+ elementary/images/image_items.eet
elementary_images_glayer_files = \
elementary/images/g_layer/double_tap_1.png \
diff --git a/data/elementary/images/image_items.eet b/data/elementary/images/image_items.eet
new file mode 100644
index 0000000000..1db45dfaa3
--- /dev/null
+++ b/data/elementary/images/image_items.eet
Binary files differ
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index b080c61f87..86925ce943 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -45,6 +45,9 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_popup_anchor.eo \
lib/elementary/efl_ui_text_editable.eo \
lib/elementary/efl_ui_text_async.eo \
+ lib/elementary/efl_ui_text_factory_images.eo \
+ lib/elementary/efl_ui_text_factory_emoticons.eo \
+ lib/elementary/efl_ui_text_factory_fallback.eo \
lib/elementary/efl_ui_textpath.eo \
lib/elementary/efl_ui_translatable.eo \
lib/elementary/efl_ui_clock.eo \
@@ -738,6 +741,9 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_table_static.c \
lib/elementary/efl_ui_table_private.h \
lib/elementary/efl_ui_text.c \
+ lib/elementary/efl_ui_text_factory_images.c \
+ lib/elementary/efl_ui_text_factory_emoticons.c \
+ lib/elementary/efl_ui_text_factory_fallback.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/Makefile_Evas.am b/src/Makefile_Evas.am
index 36298162a2..c26a978943 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -7,6 +7,7 @@ evas_canvas_eolian_pub_files = \
lib/evas/canvas/efl_canvas_polygon.eo \
lib/evas/canvas/efl_canvas_rectangle.eo \
lib/evas/canvas/efl_canvas_text.eo \
+ lib/evas/canvas/efl_canvas_text_factory.eo \
lib/evas/canvas/efl_canvas_group.eo \
lib/evas/canvas/efl_canvas_image_internal.eo \
lib/evas/canvas/evas_canvas3d_camera.eo\
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 1f75b930cb..0f7fdacfe3 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -333,6 +333,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);
@@ -834,6 +835,7 @@ add_tests:
ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text", test_efl_ui_text);
ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Label", test_efl_ui_text_label);
ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text.Async", test_efl_ui_text_async);
+ ADD_TEST_EO(NULL, "Entries", "Ui.Text Item Factory", test_ui_text_item_factory);
//------------------------------//
ADD_TEST(NULL, "Advanced Entries", "Code Syntax", test_code_syntax);
diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c
index b53c427b9a..e28ba3bc64 100644
--- a/src/bin/elementary/test_efl_ui_text.c
+++ b/src/bin/elementary/test_efl_ui_text.c
@@ -144,8 +144,8 @@ static void
my_efl_ui_text_bt_4(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");
+ efl_text_cursor_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
+ "emoticon/evil-laugh", "size=32x32");
}
static void
@@ -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,10 @@ 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_item_insert(en, cur, "emoticon/happy", "size=32x32");
efl_text_cursor_position_set(en, cur, 50);
- efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon");
+ sprintf(buf, "file://%s/images/sky_01.jpg", elm_app_data_dir_get());
+ efl_text_cursor_item_insert(en, cur, buf, "size=32x32");
efl_text_cursor_position_set(en, main_cur, 5);
efl_text_cursor_position_set(en, cur, 20);
@@ -297,7 +299,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 +334,196 @@ 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);
}
+
+#define IMAGES_SZ 5
+
+static const char *images[IMAGES_SZ] = {
+ "sky", "logo", "dog", "eet_rock", "eet_plant" };
+
+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;
+ static int image_idx = 0;
+
+ image_idx = (image_idx + 1) % IMAGES_SZ;
+ efl_text_cursor_item_insert(en,
+ efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
+ images[image_idx], "size=32x32");
+ printf("Inserted image: key = %s\n", images[image_idx]);
+}
+
+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_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
+ "emoticon/evil-laugh", "size=32x32");
+}
+
+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);
+}
+
+#define FACTORY_NONE 0
+#define FACTORY_IMAGE 1
+#define FACTORY_EMOTICON 2
+
+static void
+_ui_text_factory_del(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eina_File *f = data;
+ eina_file_close(f);
+ efl_del(factories[FACTORY_IMAGE].item_factory);
+ efl_del(factories[FACTORY_EMOTICON].item_factory);
+}
+
+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];
+ Eina_File *f;
+
+ 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[FACTORY_NONE].name = "None (Fallback)";
+ factories[FACTORY_NONE].item_factory = NULL;
+
+ factories[FACTORY_IMAGE].name = "Image Factory";
+ factories[FACTORY_IMAGE].item_factory =
+ efl_add(EFL_UI_TEXT_FACTORY_IMAGES_CLASS, win);
+
+ factories[FACTORY_EMOTICON].name = "Emoticon Factory";
+ factories[FACTORY_EMOTICON].item_factory =
+ efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, win);
+
+ // Test assigning file path source
+ sprintf(buf, "%s/images/sky_01.jpg", elm_app_data_dir_get());
+ efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
+ images[0], buf, NULL);
+ sprintf(buf, "%s/images/logo.png", elm_app_data_dir_get());
+ efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
+ images[1], buf, NULL);
+ sprintf(buf, "%s/images/mystrale.jpg", elm_app_data_dir_get());
+ efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
+ images[2], buf, NULL);
+
+ // Open EET source w/ key
+ sprintf(buf, "%s/images/image_items.eet", elm_app_data_dir_get());
+ f = eina_file_open(buf, EINA_FALSE);
+ if (f)
+ {
+ efl_event_callback_add(en, EFL_EVENT_DEL, _ui_text_factory_del, f);
+
+ efl_ui_text_factory_images_matches_mmap_add(
+ factories[FACTORY_IMAGE].item_factory,
+ "eet_rock", f, "rock");
+ efl_ui_text_factory_images_matches_mmap_add(
+ factories[FACTORY_IMAGE].item_factory,
+ "eet_plant", f, "plant");
+ }
+ else
+ {
+ printf("Error loading test file. Please review test.");
+ }
+
+
+ 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_item_insert(en, cur, "emoticon/happy", "size=32x32");
+ efl_text_cursor_position_set(en, cur, 50);
+
+ sprintf(buf, "file://%s/images/sky_01.jpg", elm_app_data_dir_get());
+ efl_text_cursor_item_insert(en, cur, buf, "size=32x32");
+ 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);
+
+ 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/efl/interfaces/efl_text_annotate.eo b/src/lib/efl/interfaces/efl_text_annotate.eo
index 002505356c..7826d07991 100644
--- a/src/lib/efl/interfaces/efl_text_annotate.eo
+++ b/src/lib/efl/interfaces/efl_text_annotate.eo
@@ -76,23 +76,6 @@ interface Efl.Text.Annotate {
}
return: bool; [[$true on success, $false otherwise.]]
}
- object_item_geometry_get {
- [[Queries a given object item for its geometry.
-
- Note that the provided annotation should be an object item type.
-
- @since 1.18
- ]]
- legacy: null;
- params {
- @in an: ptr(const(Efl.Text.Annotate.Annotation)); [[Given annotation to query]]
- @out x: int; [[X coordinate of the annotation]]
- @out y: int; [[Y coordinate of the annotation]]
- @out w: int; [[Width of the annotation]]
- @out h: int; [[Height of the annotation]]
- }
- return: bool; [[$true if given annotation is an object item, $false otherwise]]
- }
annotation_positions_get {
[[Sets given cursors to the start and end positions of the annotation.
@@ -111,8 +94,41 @@ interface Efl.Text.Annotate {
position of the annotation in the text]]
}
}
+ annotation_is_item {
+ [[Whether this is an "item" type of annotation. Should be used before
+ querying the annotation's geometry, as only "item" annotations have
+ a geometry.
+
+ see @.cursor_item_insert
+ see @.item_geometry_get
+
+ @since 1.21
+ ]]
+ legacy: null;
+ params {
+ annotation: ptr(Efl.Text.Annotate.Annotation); [[Given annotation]]
+ }
+ return: bool; [[$true if given annotation is an object item, $false otherwise]]
+ }
+ item_geometry_get {
+ [[Queries a given object item for its geometry.
+
+ Note that the provided annotation should be an object item type.
+
+ @since 1.18
+ ]]
+ legacy: null;
+ params {
+ @in an: ptr(const(Efl.Text.Annotate.Annotation)); [[Given annotation to query]]
+ @out x: int; [[X coordinate of the annotation]]
+ @out y: int; [[Y coordinate of the annotation]]
+ @out w: int; [[Width of the annotation]]
+ @out h: int; [[Height of the annotation]]
+ }
+ return: bool; [[$true if given annotation is an object item, $false otherwise]]
+ }
// Cursor
- @property cursor_object_item_annotation {
+ @property cursor_item_annotation {
[[The object-item annotation at the cursor's position.]]
get {
legacy: null;
@@ -124,7 +140,7 @@ interface Efl.Text.Annotate {
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
}
}
- cursor_object_item_insert {
+ cursor_item_insert {
[[Inserts a object item at specified position.
This adds a placeholder to be queried by higher-level code,
@@ -134,8 +150,11 @@ interface Efl.Text.Annotate {
legacy: null;
params {
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
- @in format: string; [[Format of the inserted item.
- See Format styles.]]
+ @in item: string; [[Item key to be used in higher-up
+ code to query and decided what image, emoticon
+ etc. to embed.]]
+ @in format: string; [[Size format of the inserted item.
+ This hints how to size the item in the text.]]
}
return: ptr(Efl.Text.Annotate.Annotation); [[The annotation handle of the
inserted item.]]
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index fa34c3ed43..69d020c3af 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -311,6 +311,9 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_popup_alert_scroll.eo.h>
# include <efl_ui_popup_alert_text.eo.h>
# include <efl_ui_popup_anchor.eo.h>
+# include <efl_ui_text_factory_images.eo.h>
+# include <efl_ui_text_factory_emoticons.eo.h>
+# include <efl_ui_text_factory_fallback.eo.h>
# include <efl_ui_text_editable.eo.h>
# include <efl_ui_text_async.eo.h>
# include <efl_ui_clock.eo.h>
diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c
index ed4f5d1718..ae74e5c42a 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_Factory *item_factory;
+ Efl_Canvas_Text_Factory *item_fallback_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
@@ -2485,43 +2487,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_factory_create(sd->item_factory, data, item);
}
- else
+ else if (sd->item_fallback_factory)
{
- evas_object_del(o);
- o = edje_object_add(evas_object_evas_get(data));
- elm_widget_theme_object_set
- (data, o, "text/emoticon", "wtf", style);
+ o = efl_canvas_text_factory_create(sd->item_fallback_factory,
+ data, item);
}
- return o;
}
-
- o = edje_object_add(evas_object_evas_get(data));
- if (!elm_widget_theme_object_set
- (data, o, "text", item, style))
- elm_widget_theme_object_set
- (data, o, "text/emoticon", "wtf", style);
return o;
}
@@ -3215,6 +3196,7 @@ _efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *sd)
if (_elm_config->desktop_entry)
sd->sel_handler_disabled = EINA_TRUE;
+ sd->item_fallback_factory = efl_add(EFL_UI_TEXT_FACTORY_FALLBACK_CLASS, obj);
_create_text_cursors(obj, sd);
return obj;
@@ -3224,7 +3206,6 @@ EOLIAN static void
_efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
{
Elm_Entry_Context_Menu_Item *it;
- Elm_Entry_Item_Provider *ip;
Elm_Entry_Markup_Filter *tf;
Eo *text_obj;
@@ -3270,10 +3251,6 @@ _efl_ui_text_efl_object_destructor(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);
@@ -3314,6 +3291,9 @@ _efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
ecore_job_del(sd->deferred_decoration_job);
sd->deferred_decoration_job = NULL;
+ if (sd->item_factory) efl_unref(sd->item_factory);
+ if (sd->item_fallback_factory) efl_del(sd->item_fallback_factory);
+
efl_destructor(efl_super(obj, MY_CLASS));
}
@@ -3539,55 +3519,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)
{
@@ -4927,8 +4858,7 @@ _anchors_create(Eo *obj, Efl_Ui_Text_Data *sd)
Eina_Bool is_anchor = EINA_FALSE;
Eina_Bool is_item = EINA_FALSE;
- if (efl_text_object_item_geometry_get(obj, anchor,
- NULL, NULL, NULL, NULL))
+ if (efl_text_annotation_is_item(obj, anchor))
{
is_anchor = EINA_TRUE;
is_item = EINA_TRUE;
@@ -5052,7 +4982,7 @@ _anchors_update(Eo *o, Efl_Ui_Text_Data *sd)
{
rect->obj = ob;
- efl_text_object_item_geometry_get(an->obj,
+ efl_text_item_geometry_get(an->obj,
an->annotation, &cx, &cy, &cw, &ch);
evas_object_move(rect->obj, x + cx, y + cy);
evas_object_resize(rect->obj, cw, ch);
@@ -5296,6 +5226,20 @@ _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_Factory *item_factory)
+{
+ if (pd->item_factory) efl_unref(pd->item_factory);
+ pd->item_factory = efl_ref(item_factory);
+}
+
+static Eo *
+_efl_ui_text_item_factory_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd)
+{
+ return pd->item_factory;
+}
+
#if 0
/* Efl.Part begin */
diff --git a/src/lib/elementary/efl_ui_text.eo b/src/lib/elementary/efl_ui_text.eo
index 341a951679..515fc0dfda 100644
--- a/src/lib/elementary/efl_ui_text.eo
+++ b/src/lib/elementary/efl_ui_text.eo
@@ -233,13 +233,12 @@ 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
-
- 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.]]
+ @property item_factory {
+ [[The factory that provides item in the text e.g.
+ "emoticon/happy" or "href=file://image.jpg" etc.
+ ]]
+ values {
+ item_factory: Efl.Canvas.Text.Factory; [[Factory to create items]]
}
}
input_panel_show {
@@ -252,17 +251,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.
@@ -306,23 +294,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_factory_emoticons.c b/src/lib/elementary/efl_ui_text_factory_emoticons.c
new file mode 100644
index 0000000000..55818af33d
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_emoticons.c
@@ -0,0 +1,52 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include <Elementary_Cursor.h>
+#include "elm_priv.h"
+
+#define MY_CLASS EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS
+
+typedef struct _Efl_Ui_Text_Factory_Emoticons_Data Efl_Ui_Text_Factory_Emoticons_Data;
+
+struct _Efl_Ui_Text_Factory_Emoticons_Data
+{
+ const char *name;
+};
+
+EOLIAN static Eo *
+_efl_ui_text_factory_emoticons_efl_object_constructor(Eo *obj,
+ Efl_Ui_Text_Factory_Emoticons_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_text_factory_emoticons_efl_object_destructor(Eo *obj,
+ Efl_Ui_Text_Factory_Emoticons_Data *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+
+EOLIAN static Efl_Canvas_Object
+*_efl_ui_text_factory_emoticons_efl_canvas_text_factory_create(
+ Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Emoticons_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, "text", key, style))
+ _elm_theme_object_set
+ (object, o, "text/emoticon", "wtf", style);
+ return o;
+}
+
+#include "efl_ui_text_factory_emoticons.eo.c"
diff --git a/src/lib/elementary/efl_ui_text_factory_emoticons.eo b/src/lib/elementary/efl_ui_text_factory_emoticons.eo
new file mode 100644
index 0000000000..38269ea7d5
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_emoticons.eo
@@ -0,0 +1,12 @@
+class Efl.Ui.Text.Factory.Emoticons (Efl.Object, Efl.Canvas.Text.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.Factory.create;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_text_factory_fallback.c b/src/lib/elementary/efl_ui_text_factory_fallback.c
new file mode 100644
index 0000000000..4ee456e1e0
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_fallback.c
@@ -0,0 +1,62 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include <Elementary_Cursor.h>
+#include "elm_priv.h"
+
+#define MY_CLASS EFL_UI_TEXT_FACTORY_FALLBACK_CLASS
+
+typedef struct _Efl_Ui_Text_Factory_Fallback_Data Efl_Ui_Text_Factory_Fallback_Data;
+
+struct _Efl_Ui_Text_Factory_Fallback_Data
+{
+ Efl_Canvas_Text_Factory *emoticon_factory, *image_factory;
+};
+
+EOLIAN static Eo *
+_efl_ui_text_factory_fallback_efl_object_constructor(Eo *obj,
+ Efl_Ui_Text_Factory_Fallback_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ pd->image_factory = efl_add(EFL_UI_TEXT_FACTORY_IMAGES_CLASS, obj);
+ pd->emoticon_factory = efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, obj);
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_text_factory_fallback_efl_object_destructor(Eo *obj,
+ Efl_Ui_Text_Factory_Fallback_Data *pd EINA_UNUSED)
+{
+ efl_del(pd->emoticon_factory);
+ efl_del(pd->image_factory);
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+
+EOLIAN static Efl_Canvas_Object
+*_efl_ui_text_factory_fallback_efl_canvas_text_factory_create(
+ Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Fallback_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_factory_create(pd->image_factory, object, fname);
+ }
+ else
+ {
+ o = efl_canvas_text_factory_create(pd->emoticon_factory, object, key);
+ }
+ return o;
+}
+
+#include "efl_ui_text_factory_fallback.eo.c"
diff --git a/src/lib/elementary/efl_ui_text_factory_fallback.eo b/src/lib/elementary/efl_ui_text_factory_fallback.eo
new file mode 100644
index 0000000000..830fa5b637
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_fallback.eo
@@ -0,0 +1,16 @@
+class Efl.Ui.Text.Factory.Fallback (Efl.Object, Efl.Canvas.Text.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.Factory.create;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_text_factory_images.c b/src/lib/elementary/efl_ui_text_factory_images.c
new file mode 100644
index 0000000000..91325f15b2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_images.c
@@ -0,0 +1,147 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include <Elementary_Cursor.h>
+#include "elm_priv.h"
+
+#define MY_CLASS EFL_UI_TEXT_FACTORY_IMAGES_CLASS
+
+typedef struct _Efl_Ui_Text_Factory_Images_Data Efl_Ui_Text_Factory_Images_Data;
+
+struct _Efl_Ui_Text_Factory_Images_Data
+{
+ const char *name;
+ Eina_Hash *hash;
+};
+
+typedef struct
+{
+ Eina_File *file;
+ const char *key;
+} File_Entry;
+
+static void
+_entry_free_cb(void *data)
+{
+ File_Entry *e = data;
+ eina_file_close(e->file);
+ eina_stringshare_del(e->key);
+ free(e);
+}
+
+EOLIAN static Eo *
+_efl_ui_text_factory_images_efl_object_constructor(Eo *obj,
+ Efl_Ui_Text_Factory_Images_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_factory_images_efl_object_destructor(Eo *obj,
+ Efl_Ui_Text_Factory_Images_Data *pd EINA_UNUSED)
+{
+ eina_hash_free(pd->hash);
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Efl_Canvas_Object *
+_efl_ui_text_factory_images_efl_canvas_text_factory_create(Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Images_Data *pd EINA_UNUSED,
+ Efl_Canvas_Object *object,
+ const char *key)
+{
+ Efl_Canvas_Object *o;
+ File_Entry *e;
+
+ o = efl_add(EFL_CANVAS_IMAGE_CLASS, object);
+ e = eina_hash_find(pd->hash, key);
+ if (e)
+ {
+ efl_file_mmap_set(o, e->file, e->key);
+ }
+ else
+ {
+ efl_file_set(o, key, NULL);
+ }
+
+ if (efl_file_load_error_get(o) != EFL_IMAGE_LOAD_ERROR_NONE)
+ {
+ efl_del(o);
+ o = NULL;
+ }
+
+ return o;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_factory_images_matches_add(Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Images_Data *pd,
+ const char *name, const char *file, const char *key)
+{
+ File_Entry *e;
+ Eina_File *f = eina_file_open(file, EINA_FALSE);
+
+ if (!f) return EINA_FALSE;
+
+ e = malloc(sizeof(*e));
+ e->file = f;
+ e->key = eina_stringshare_add(key);
+
+ if (!eina_hash_add(pd->hash, name, e))
+ {
+ ERR("Failed to add file path %s to key %s\n", file, key);
+ eina_file_close(f);
+ free(e);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_factory_images_matches_del(Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Images_Data *pd,
+ const char *name)
+{
+ return eina_hash_del(pd->hash, name, NULL);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_factory_images_matches_mmap_add(Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Images_Data *pd,
+ const char *name, const Eina_File *file, const char *key)
+{
+ File_Entry *e;
+ Eina_File *f;
+
+ if (!file) return EINA_FALSE;
+
+ f = eina_file_dup(file);
+ e = malloc(sizeof(*e));
+ e->file = f;
+ e->key = eina_stringshare_add(key);
+
+ if (!eina_hash_add(pd->hash, name, e))
+ {
+ ERR("Failed to add Eina_File %p to key %s\n", file, key);
+ eina_file_close(f);
+ free(e);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_factory_images_matches_mmap_del(Eo *obj EINA_UNUSED,
+ Efl_Ui_Text_Factory_Images_Data *pd,
+ const char *name)
+{
+ return eina_hash_del(pd->hash, name, NULL);
+}
+
+#include "efl_ui_text_factory_images.eo.c"
diff --git a/src/lib/elementary/efl_ui_text_factory_images.eo b/src/lib/elementary/efl_ui_text_factory_images.eo
new file mode 100644
index 0000000000..d682e294a7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_factory_images.eo
@@ -0,0 +1,69 @@
+class Efl.Ui.Text.Factory.Images (Efl.Object, Efl.Canvas.Text.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 path of an image or EET file.
+
+ This can be used for quick retrieval (instead of
+ providing actual filenames.
+
+ This $file is associated with $name is considered a full file path.
+
+ see @.matches_mmap_add for mmap version
+ see @.matches_del
+ ]]
+ params {
+ name: string; [[the name associated with filename]]
+ path: string; [[the image or EET file path]]
+ key: string; [[the key to use (in cases of loading an EET file]]
+ }
+ return: bool; [[$true if successful, $false otherwise]]
+ }
+ matches_del {
+ [[Deletes an association of $key with its respective file path.
+
+ see @.matches_add
+ ]]
+ params {
+ key: string; [[the entry's key to delete]]
+ }
+ return: bool; [[$true if successful, $false otherwise]]
+ }
+ matches_mmap_add {
+ [[Associates given name with a mmap'd image or EET file and key.
+
+ see @.matches_add for string file path version
+ see @.matches_mmap_del
+ ]]
+ params {
+ name: string; [[the name associated with filename]]
+ file: ptr(const(Eina.File)); [[the image or EET file]]
+ key: string; [[the key to use (in cases of loading an EET file]]
+ }
+ return: bool; [[$true if successful, $false otherwise]]
+ }
+ matches_mmap_del {
+ [[Deletes an association of $key with its respective file.
+
+ see @.matches_mmap_add
+ ]]
+ params {
+ key: string; [[the entry's key to delete]]
+ }
+ return: bool; [[$true if successful, $false otherwise]]
+ }
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Canvas.Text.Factory.create;
+ }
+}
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index d6664a2ddd..f2b2f6d372 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -21,6 +21,7 @@
*/
//#include "canvas/efl_canvas_text_cursor.eo.h"
#include "canvas/efl_canvas_text.eo.h"
+#include "canvas/efl_canvas_text_factory.eo.h"
/**
* @}
*/
diff --git a/src/lib/evas/canvas/efl_canvas_text.eo b/src/lib/evas/canvas/efl_canvas_text.eo
index a021fbacef..73367b0f58 100644
--- a/src/lib/evas/canvas/efl_canvas_text.eo
+++ b/src/lib/evas/canvas/efl_canvas_text.eo
@@ -345,10 +345,11 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text, Efl.Text.Properties,
Efl.Text.Annotate.range_annotations_get;
Efl.Text.Annotate.annotation_insert;
Efl.Text.Annotate.annotation_del;
- Efl.Text.Annotate.object_item_geometry_get;
+ Efl.Text.Annotate.annotation_is_item;
+ Efl.Text.Annotate.item_geometry_get;
Efl.Text.Annotate.annotation_positions_get;
- Efl.Text.Annotate.cursor_object_item_annotation { get; }
- Efl.Text.Annotate.cursor_object_item_insert;
+ Efl.Text.Annotate.cursor_item_annotation { get; }
+ Efl.Text.Annotate.cursor_item_insert;
Efl.Text.Markup.markup { set; get; }
Efl.Text.Markup.cursor_markup_insert;
Efl.Gfx.scale { set; }
diff --git a/src/lib/evas/canvas/efl_canvas_text_factory.eo b/src/lib/evas/canvas/efl_canvas_text_factory.eo
new file mode 100644
index 0000000000..240cfb4669
--- /dev/null
+++ b/src/lib/evas/canvas/efl_canvas_text_factory.eo
@@ -0,0 +1,25 @@
+interface Efl.Canvas.Text.Factory ()
+{
+ [[Object factory that creates Efl.Canvas.Object objects.
+
+ Translates a given key to an object (item), to be later placed in a text
+ for higher level usages. The translation implementation is left to be
+ decided by the inheriting class, whether it is by treating the $key as an
+ image path, or a key associated with a real-path in a hashtable
+ or something else entirely.
+
+ @since 1.21
+ ]]
+ methods {
+ create {
+ [[Translates a given $key to an item object, and returns the object.
+ The returned object should be owned by the passed $object.
+ ]]
+ params {
+ object: Efl.Canvas.Object; [[The parent of the created object]]
+ key: string; [[Key that is associated to an item object]]
+ }
+ return: Efl.Canvas.Object @owned;
+ }
+ }
+}
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c
index 70c5618390..1a0023da5f 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -15123,16 +15123,24 @@ _efl_canvas_text_efl_text_annotate_range_annotations_get(Eo *eo_obj EINA_UNUSED,
}
EOLIAN static Efl_Text_Annotate_Annotation *
-_efl_canvas_text_efl_text_annotate_cursor_object_item_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur, const char *format)
+_efl_canvas_text_efl_text_annotate_cursor_item_insert(Eo *eo_obj,
+ Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur,
+ const char *item, const char *format)
{
+ Eina_Strbuf *buf = eina_strbuf_new();
+
+ eina_strbuf_append_printf(buf, "%s href=%s", format, item);
+
Efl_Text_Annotate_Annotation *ret =
- _textblock_annotation_insert(cur->obj, o, cur, cur, format, EINA_TRUE);
+ _textblock_annotation_insert(cur->obj, o, cur, cur,
+ eina_strbuf_string_get(buf), EINA_TRUE);
+ eina_strbuf_free(buf);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
return ret;
}
EOLIAN static Efl_Text_Annotate_Annotation *
-_efl_canvas_text_efl_text_annotate_cursor_object_item_annotation_get(Eo *eo_obj EINA_UNUSED,
+_efl_canvas_text_efl_text_annotate_cursor_item_annotation_get(Eo *eo_obj EINA_UNUSED,
Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
Eina_Iterator *it;
@@ -15153,7 +15161,21 @@ _efl_canvas_text_efl_text_annotate_cursor_object_item_annotation_get(Eo *eo_obj
}
EOLIAN static Eina_Bool
-_efl_canvas_text_efl_text_annotate_object_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
+_efl_canvas_text_efl_text_annotate_annotation_is_item(Eo *eo_obj EINA_UNUSED,
+ Efl_Canvas_Text_Data *o EINA_UNUSED,
+ Efl_Text_Annotate_Annotation *annotation)
+{
+ if (!annotation || (annotation->obj != eo_obj))
+ {
+ ERR("Used invalid handle or of a different object");
+ return EINA_FALSE;
+ }
+
+ return annotation->is_item;
+}
+
+EOLIAN static Eina_Bool
+_efl_canvas_text_efl_text_annotate_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
{
Efl_Text_Cursor_Cursor cur;
@@ -16264,3 +16286,4 @@ _efl_canvas_text_async_layout(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o)
}
#include "canvas/efl_canvas_text.eo.c"
+#include "canvas/efl_canvas_text_factory.eo.c" // interface
diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c
index 0e6057cf58..14d04a7e10 100644
--- a/src/tests/evas/evas_test_textblock.c
+++ b/src/tests/evas/evas_test_textblock.c
@@ -4371,8 +4371,8 @@ START_TEST(evas_textblock_annotation)
/* Check "item" annotations */
efl_text_set(tb, "abcd");
evas_textblock_cursor_pos_set(cur, 4);
- an = efl_text_cursor_object_item_insert(tb, cur, "size=16x16");
- _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16"));
+ an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
+ _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16 href="));
/* Check that format is not extended if it's an "object item" */
evas_textblock_cursor_pos_set(cur, 5);
@@ -4417,14 +4417,14 @@ START_TEST(evas_textblock_annotation)
/* Test getting of object item */
evas_textblock_cursor_pos_set(cur, 4);
- an = efl_text_cursor_object_item_annotation_get(tb, cur);
+ an = efl_text_cursor_item_annotation_get(tb, cur);
ck_assert(!an);
- an = efl_text_cursor_object_item_insert(tb, cur, "size=16x16");
+ an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
evas_textblock_cursor_pos_set(cur, 4);
- an = efl_text_cursor_object_item_annotation_get(tb, cur);
+ an = efl_text_cursor_item_annotation_get(tb, cur);
ck_assert(an);
- ck_assert_str_eq("size=16x16", efl_text_annotation_get(tb, an));
+ ck_assert_str_eq("size=16x16 href=", efl_text_annotation_get(tb, an));
END_TB_TEST();
}