summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 = \
50 elementary/images/pm_fill.png \ 50 elementary/images/pm_fill.png \
51 elementary/images/pt.png \ 51 elementary/images/pt.png \
52 elementary/images/earth_normal.png \ 52 elementary/images/earth_normal.png \
53 elementary/images/space.png 53 elementary/images/space.png \
54 elementary/images/image_items.eet
54 55
55elementary_images_glayer_files = \ 56elementary_images_glayer_files = \
56 elementary/images/g_layer/double_tap_1.png \ 57 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 = \
45 lib/elementary/efl_ui_popup_anchor.eo \ 45 lib/elementary/efl_ui_popup_anchor.eo \
46 lib/elementary/efl_ui_text_editable.eo \ 46 lib/elementary/efl_ui_text_editable.eo \
47 lib/elementary/efl_ui_text_async.eo \ 47 lib/elementary/efl_ui_text_async.eo \
48 lib/elementary/efl_ui_text_factory_images.eo \
49 lib/elementary/efl_ui_text_factory_emoticons.eo \
50 lib/elementary/efl_ui_text_factory_fallback.eo \
48 lib/elementary/efl_ui_textpath.eo \ 51 lib/elementary/efl_ui_textpath.eo \
49 lib/elementary/efl_ui_translatable.eo \ 52 lib/elementary/efl_ui_translatable.eo \
50 lib/elementary/efl_ui_clock.eo \ 53 lib/elementary/efl_ui_clock.eo \
@@ -738,6 +741,9 @@ lib_elementary_libelementary_la_SOURCES = \
738 lib/elementary/efl_ui_table_static.c \ 741 lib/elementary/efl_ui_table_static.c \
739 lib/elementary/efl_ui_table_private.h \ 742 lib/elementary/efl_ui_table_private.h \
740 lib/elementary/efl_ui_text.c \ 743 lib/elementary/efl_ui_text.c \
744 lib/elementary/efl_ui_text_factory_images.c \
745 lib/elementary/efl_ui_text_factory_emoticons.c \
746 lib/elementary/efl_ui_text_factory_fallback.c \
741 lib/elementary/efl_ui_clock.c \ 747 lib/elementary/efl_ui_clock.c \
742 lib/elementary/efl_ui_clock_private.h \ 748 lib/elementary/efl_ui_clock_private.h \
743 lib/elementary/efl_ui_image_factory.c \ 749 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 = \
7 lib/evas/canvas/efl_canvas_polygon.eo \ 7 lib/evas/canvas/efl_canvas_polygon.eo \
8 lib/evas/canvas/efl_canvas_rectangle.eo \ 8 lib/evas/canvas/efl_canvas_rectangle.eo \
9 lib/evas/canvas/efl_canvas_text.eo \ 9 lib/evas/canvas/efl_canvas_text.eo \
10 lib/evas/canvas/efl_canvas_text_factory.eo \
10 lib/evas/canvas/efl_canvas_group.eo \ 11 lib/evas/canvas/efl_canvas_group.eo \
11 lib/evas/canvas/efl_canvas_image_internal.eo \ 12 lib/evas/canvas/efl_canvas_image_internal.eo \
12 lib/evas/canvas/evas_canvas3d_camera.eo\ 13 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);
333void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info); 333void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info);
334void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info); 334void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info);
335void test_efl_ui_text_async(void *data, Evas_Object *obj, void *event_info); 335void test_efl_ui_text_async(void *data, Evas_Object *obj, void *event_info);
336void test_ui_text_item_factory(void *data, Evas_Object *obj, void *event_info);
336void test_evas_mask(void *data, Edje_Object *obj, void *event_info); 337void test_evas_mask(void *data, Edje_Object *obj, void *event_info);
337void test_gfx_filters(void *data, Evas_Object *obj, void *event_info); 338void test_gfx_filters(void *data, Evas_Object *obj, void *event_info);
338void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info); 339void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info);
@@ -834,6 +835,7 @@ add_tests:
834 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text", test_efl_ui_text); 835 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text", test_efl_ui_text);
835 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Label", test_efl_ui_text_label); 836 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Label", test_efl_ui_text_label);
836 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text.Async", test_efl_ui_text_async); 837 ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text.Async", test_efl_ui_text_async);
838 ADD_TEST_EO(NULL, "Entries", "Ui.Text Item Factory", test_ui_text_item_factory);
837 839
838 //------------------------------// 840 //------------------------------//
839 ADD_TEST(NULL, "Advanced Entries", "Code Syntax", test_code_syntax); 841 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
144my_efl_ui_text_bt_4(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 144my_efl_ui_text_bt_4(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
145{ 145{
146 Evas_Object *en = data; 146 Evas_Object *en = data;
147 efl_text_cursor_object_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN), 147 efl_text_cursor_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
148 "size=32x32 href=emoticon/evil-laugh"); 148 "emoticon/evil-laugh", "size=32x32");
149} 149}
150 150
151static void 151static void
@@ -187,6 +187,7 @@ test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
187{ 187{
188 Evas_Object *win, *bx, *bx2, *bx3, *bt, *en; 188 Evas_Object *win, *bx, *bx2, *bx3, *bt, *en;
189 Efl_Text_Cursor_Cursor *main_cur, *cur; 189 Efl_Text_Cursor_Cursor *main_cur, *cur;
190 char buf[128];
190 191
191 win = elm_win_util_standard_add("entry", "Entry"); 192 win = elm_win_util_standard_add("entry", "Entry");
192 elm_win_autodel_set(win, EINA_TRUE); 193 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
215 cur = efl_text_cursor_new(en); 216 cur = efl_text_cursor_new(en);
216 217
217 efl_text_cursor_position_set(en, cur, 2); 218 efl_text_cursor_position_set(en, cur, 2);
218 efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon"); 219 efl_text_cursor_item_insert(en, cur, "emoticon/happy", "size=32x32");
219 efl_text_cursor_position_set(en, cur, 50); 220 efl_text_cursor_position_set(en, cur, 50);
220 efl_text_cursor_object_item_insert(en, cur, "size=32x32 href=emoticon"); 221 sprintf(buf, "file://%s/images/sky_01.jpg", elm_app_data_dir_get());
222 efl_text_cursor_item_insert(en, cur, buf, "size=32x32");
221 223
222 efl_text_cursor_position_set(en, main_cur, 5); 224 efl_text_cursor_position_set(en, main_cur, 5);
223 efl_text_cursor_position_set(en, cur, 20); 225 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
297 elm_win_resize_object_add(win, bx); 299 elm_win_resize_object_add(win, bx);
298 evas_object_show(bx); 300 evas_object_show(bx);
299 301
300 en = efl_add(EFL_UI_TEXT_ASYNC_CLASS, win, 302 en = efl_add(EFL_UI_TEXT_CLASS, win,
301 efl_text_wrap_set(efl_added, EFL_TEXT_FORMAT_WRAP_WORD), 303 efl_text_wrap_set(efl_added, EFL_TEXT_FORMAT_WRAP_WORD),
302 efl_text_multiline_set(efl_added, EINA_TRUE) 304 efl_text_multiline_set(efl_added, EINA_TRUE)
303 ); 305 );
@@ -332,3 +334,196 @@ test_efl_ui_text_async(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
332 evas_object_resize(win, 480, 320); 334 evas_object_resize(win, 480, 320);
333 evas_object_show(win); 335 evas_object_show(win);
334} 336}
337
338#define IMAGES_SZ 5
339
340static const char *images[IMAGES_SZ] = {
341 "sky", "logo", "dog", "eet_rock", "eet_plant" };
342
343static void
344my_efl_ui_text_item_factory_bt_image(void *data, Evas_Object *obj EINA_UNUSED,
345 void *event_info EINA_UNUSED)
346{
347 Evas_Object *en = data;
348 static int image_idx = 0;
349
350 image_idx = (image_idx + 1) % IMAGES_SZ;
351 efl_text_cursor_item_insert(en,
352 efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
353 images[image_idx], "size=32x32");
354 printf("Inserted image: key = %s\n", images[image_idx]);
355}
356
357static void
358my_efl_ui_text_item_factory_bt_emoticon(void *data, Evas_Object *obj EINA_UNUSED,
359 void *event_info EINA_UNUSED)
360{
361 Evas_Object *en = data;
362 efl_text_cursor_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
363 "emoticon/evil-laugh", "size=32x32");
364}
365
366static struct
367{
368 const char *name;
369 Eo *item_factory;
370} factories[3];
371
372static void
373my_efl_ui_text_item_factory_bt_change(void *data, Evas_Object *obj EINA_UNUSED,
374 void *event_info EINA_UNUSED)
375{
376 Evas_Object *en = data;
377 static int item_factory_idx = 0;
378
379 item_factory_idx = (item_factory_idx + 1) % 3;
380 efl_ui_text_item_factory_set(en, factories[item_factory_idx].item_factory);
381 printf("Factory set to: %s\n", factories[item_factory_idx].name);
382}
383
384#define FACTORY_NONE 0
385#define FACTORY_IMAGE 1
386#define FACTORY_EMOTICON 2
387
388static void
389_ui_text_factory_del(void *data, const Efl_Event *ev EINA_UNUSED)
390{
391 Eina_File *f = data;
392 eina_file_close(f);
393 efl_del(factories[FACTORY_IMAGE].item_factory);
394 efl_del(factories[FACTORY_EMOTICON].item_factory);
395}
396
397void
398test_ui_text_item_factory(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
399{
400 Evas_Object *win, *bx, *bx2, *bx3, *bt, *en;
401 Efl_Text_Cursor_Cursor *main_cur, *cur;
402 char buf[128];
403 Eina_File *f;
404
405 win = elm_win_util_standard_add("entry", "Entry");
406 elm_win_autodel_set(win, EINA_TRUE);
407
408 bx = elm_box_add(win);
409 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
410 elm_win_resize_object_add(win, bx);
411 evas_object_show(bx);
412
413 en = efl_add(EFL_UI_TEXT_CLASS, win,
414 efl_text_multiline_set(efl_added, EINA_TRUE));
415
416 factories[FACTORY_NONE].name = "None (Fallback)";
417 factories[FACTORY_NONE].item_factory = NULL;
418
419 factories[FACTORY_IMAGE].name = "Image Factory";
420 factories[FACTORY_IMAGE].item_factory =
421 efl_add(EFL_UI_TEXT_FACTORY_IMAGES_CLASS, win);
422
423 factories[FACTORY_EMOTICON].name = "Emoticon Factory";
424 factories[FACTORY_EMOTICON].item_factory =
425 efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, win);
426
427 // Test assigning file path source
428 sprintf(buf, "%s/images/sky_01.jpg", elm_app_data_dir_get());
429 efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
430 images[0], buf, NULL);
431 sprintf(buf, "%s/images/logo.png", elm_app_data_dir_get());
432 efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
433 images[1], buf, NULL);
434 sprintf(buf, "%s/images/mystrale.jpg", elm_app_data_dir_get());
435 efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
436 images[2], buf, NULL);
437
438 // Open EET source w/ key
439 sprintf(buf, "%s/images/image_items.eet", elm_app_data_dir_get());
440 f = eina_file_open(buf, EINA_FALSE);
441 if (f)
442 {
443 efl_event_callback_add(en, EFL_EVENT_DEL, _ui_text_factory_del, f);
444
445 efl_ui_text_factory_images_matches_mmap_add(
446 factories[FACTORY_IMAGE].item_factory,
447 "eet_rock", f, "rock");
448 efl_ui_text_factory_images_matches_mmap_add(
449 factories[FACTORY_IMAGE].item_factory,
450 "eet_plant", f, "plant");
451 }
452 else
453 {
454 printf("Error loading test file. Please review test.");
455 }
456
457
458 printf("Added Efl.Ui.Text object\n");
459 efl_text_set(en, "Hello world! Goodbye world! This is a test text for the"
460 " new UI Text widget.\xE2\x80\xA9This is the next paragraph.\nThis"
461 " is the next line.\nThis is Yet another line! Line and paragraph"
462 " separators are actually different!");
463 efl_text_font_set(en, "Sans", 14);
464 efl_text_normal_color_set(en, 255, 255, 255, 255);
465
466 main_cur = efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN);
467 cur = efl_text_cursor_new(en);
468
469 efl_text_cursor_position_set(en, cur, 2);
470 efl_text_cursor_item_insert(en, cur, "emoticon/happy", "size=32x32");
471 efl_text_cursor_position_set(en, cur, 50);
472
473 sprintf(buf, "file://%s/images/sky_01.jpg", elm_app_data_dir_get());
474 efl_text_cursor_item_insert(en, cur, buf, "size=32x32");
475 efl_text_cursor_position_set(en, main_cur, 5);
476
477 efl_ui_text_interactive_editable_set(en, EINA_TRUE);
478 efl_ui_text_scrollable_set(en, EINA_TRUE);
479 elm_box_pack_end(bx, en);
480 elm_object_focus_set(en, EINA_TRUE);
481
482 bx2 = elm_box_add(win);
483 elm_box_horizontal_set(bx2, EINA_TRUE);
484 evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
485 evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
486
487 bt = elm_button_add(win);
488 elm_object_text_set(bt, "Image");
489 evas_object_smart_callback_add(bt, "clicked",
490 my_efl_ui_text_item_factory_bt_image, en);
491 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
492 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
493 elm_box_pack_end(bx2, bt);
494 elm_object_focus_allow_set(bt, EINA_FALSE);
495 evas_object_show(bt);
496
497 bt = elm_button_add(win);
498 elm_object_text_set(bt, "Emoticon");
499 evas_object_smart_callback_add(bt, "clicked",
500 my_efl_ui_text_item_factory_bt_emoticon, en);
501 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
502 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
503 elm_box_pack_end(bx2, bt);
504 elm_object_focus_allow_set(bt, EINA_FALSE);
505 evas_object_show(bt);
506
507 bt = elm_button_add(win);
508 elm_object_text_set(bt, "Factory");
509 evas_object_smart_callback_add(bt, "clicked",
510 my_efl_ui_text_item_factory_bt_change, en);
511 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
512 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
513 elm_box_pack_end(bx2, bt);
514 elm_object_focus_allow_set(bt, EINA_FALSE);
515 evas_object_show(bt);
516
517 bx3 = elm_box_add(win);
518 elm_box_horizontal_set(bx3, EINA_TRUE);
519 evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, 0.0);
520 evas_object_size_hint_align_set(bx3, EVAS_HINT_FILL, EVAS_HINT_FILL);
521
522 elm_box_pack_end(bx, bx3);
523 elm_box_pack_end(bx, bx2);
524 evas_object_show(bx3);
525 evas_object_show(bx2);
526
527 evas_object_resize(win, 480, 320);
528 evas_object_show(win);
529}
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 {
76 } 76 }
77 return: bool; [[$true on success, $false otherwise.]] 77 return: bool; [[$true on success, $false otherwise.]]
78 } 78 }
79 object_item_geometry_get {
80 [[Queries a given object item for its geometry.
81
82 Note that the provided annotation should be an object item type.
83
84 @since 1.18
85 ]]
86 legacy: null;
87 params {
88 @in an: ptr(const(Efl.Text.Annotate.Annotation)); [[Given annotation to query]]
89 @out x: int; [[X coordinate of the annotation]]
90 @out y: int; [[Y coordinate of the annotation]]
91 @out w: int; [[Width of the annotation]]
92 @out h: int; [[Height of the annotation]]
93 }
94 return: bool; [[$true if given annotation is an object item, $false otherwise]]
95 }
96 annotation_positions_get { 79 annotation_positions_get {
97 [[Sets given cursors to the start and end positions of the annotation. 80 [[Sets given cursors to the start and end positions of the annotation.
98 81
@@ -111,8 +94,41 @@ interface Efl.Text.Annotate {
111 position of the annotation in the text]] 94 position of the annotation in the text]]
112 } 95 }
113 } 96 }
97 annotation_is_item {
98 [[Whether this is an "item" type of annotation. Should be used before
99 querying the annotation's geometry, as only "item" annotations have
100 a geometry.
101
102 see @.cursor_item_insert
103 see @.item_geometry_get
104
105 @since 1.21
106 ]]
107 legacy: null;
108 params {
109 annotation: ptr(Efl.Text.Annotate.Annotation); [[Given annotation]]
110 }
111 return: bool; [[$true if given annotation is an object item, $false otherwise]]
112 }
113 item_geometry_get {
114 [[Queries a given object item for its geometry.
115
116 Note that the provided annotation should be an object item type.
117
118 @since 1.18
119 ]]
120 legacy: null;
121 params {
122 @in an: ptr(const(Efl.Text.Annotate.Annotation)); [[Given annotation to query]]
123 @out x: int; [[X coordinate of the annotation]]
124 @out y: int; [[Y coordinate of the annotation]]
125 @out w: int; [[Width of the annotation]]
126 @out h: int; [[Height of the annotation]]
127 }
128 return: bool; [[$true if given annotation is an object item, $false otherwise]]
129 }
114 // Cursor 130 // Cursor
115 @property cursor_object_item_annotation { 131 @property cursor_item_annotation {
116 [[The object-item annotation at the cursor's position.]] 132 [[The object-item annotation at the cursor's position.]]
117 get { 133 get {
118 legacy: null; 134 legacy: null;
@@ -124,7 +140,7 @@ interface Efl.Text.Annotate {
124 cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]] 140 cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
125 } 141 }
126 } 142 }
127 cursor_object_item_insert { 143 cursor_item_insert {
128 [[Inserts a object item at specified position. 144 [[Inserts a object item at specified position.
129 145
130 This adds a placeholder to be queried by higher-level code, 146 This adds a placeholder to be queried by higher-level code,
@@ -134,8 +150,11 @@ interface Efl.Text.Annotate {
134 legacy: null; 150 legacy: null;
135 params { 151 params {
136 cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]] 152 cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
137 @in format: string; [[Format of the inserted item. 153 @in item: string; [[Item key to be used in higher-up
138 See Format styles.]] 154 code to query and decided what image, emoticon
155 etc. to embed.]]
156 @in format: string; [[Size format of the inserted item.
157 This hints how to size the item in the text.]]
139 } 158 }
140 return: ptr(Efl.Text.Annotate.Annotation); [[The annotation handle of the 159 return: ptr(Efl.Text.Annotate.Annotation); [[The annotation handle of the
141 inserted item.]] 160 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;
311# include <efl_ui_popup_alert_scroll.eo.h> 311# include <efl_ui_popup_alert_scroll.eo.h>
312# include <efl_ui_popup_alert_text.eo.h> 312# include <efl_ui_popup_alert_text.eo.h>
313# include <efl_ui_popup_anchor.eo.h> 313# include <efl_ui_popup_anchor.eo.h>
314# include <efl_ui_text_factory_images.eo.h>
315# include <efl_ui_text_factory_emoticons.eo.h>
316# include <efl_ui_text_factory_fallback.eo.h>
314# include <efl_ui_text_editable.eo.h> 317# include <efl_ui_text_editable.eo.h>
315# include <efl_ui_text_async.eo.h> 318# include <efl_ui_text_async.eo.h>
316# include <efl_ui_clock.eo.h> 319# 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
63 Eina_List *sel; 63 Eina_List *sel;
64 Eina_List *items; /** context menu item list */ 64 Eina_List *items; /** context menu item list */
65 Item_Obj *item_objs; 65 Item_Obj *item_objs;
66 Eina_List *item_providers; 66 Efl_Canvas_Text_Factory *item_factory;
67 Efl_Canvas_Text_Factory *item_fallback_factory;
67 Eina_List *markup_filters; 68 Eina_List *markup_filters;
68 Ecore_Job *hov_deljob; 69 Ecore_Job *hov_deljob;
69 Mod_Api *api; // module api if supplied 70 Mod_Api *api; // module api if supplied
@@ -131,6 +132,7 @@ struct _Efl_Ui_Text_Data
131 Eina_Bool scroll : 1; 132 Eina_Bool scroll : 1;
132 Eina_Bool input_panel_show_on_demand : 1; 133 Eina_Bool input_panel_show_on_demand : 1;
133 Eina_Bool anchors_updated : 1; 134 Eina_Bool anchors_updated : 1;
135 Eina_Bool fallback_item_provider_disabled : 1;
134}; 136};
135 137
136struct _Anchor 138struct _Anchor
@@ -2485,43 +2487,22 @@ _entry_mouse_triple_signal_cb(void *data,
2485static Evas_Object * 2487static Evas_Object *
2486_item_get(void *data, const char *item) 2488_item_get(void *data, const char *item)
2487{ 2489{
2488 Eina_List *l; 2490 Evas_Object *o = NULL;
2489 Evas_Object *o;
2490 Elm_Entry_Item_Provider *ip;
2491 const char *style = elm_widget_style_get(data);
2492 2491
2493 EFL_UI_TEXT_DATA_GET(data, sd); 2492 EFL_UI_TEXT_DATA_GET(data, sd);
2494 2493
2495 EINA_LIST_FOREACH(sd->item_providers, l, ip) 2494 if (item)
2496 {
2497 o = ip->func(ip->data, data, item);
2498 if (o) return o;
2499 }
2500 if (item && !strncmp(item, "file://", 7))
2501 { 2495 {
2502 const char *fname = item + 7; 2496 if (sd->item_factory)
2503
2504 o = evas_object_image_filled_add(evas_object_evas_get(data));
2505 evas_object_image_file_set(o, fname, NULL);
2506 if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
2507 { 2497 {
2508 evas_object_show(o); 2498 o = efl_canvas_text_factory_create(sd->item_factory, data, item);
2509 } 2499 }
2510 else 2500 else if (sd->item_fallback_factory)
2511 { 2501 {
2512 evas_object_del(o); 2502 o = efl_canvas_text_factory_create(sd->item_fallback_factory,
2513 o = edje_object_add(evas_object_evas_get(data)); 2503 data, item);
2514 elm_widget_theme_object_set
2515 (data, o, "text/emoticon", "wtf", style);
2516 } 2504 }
2517 return o;
2518 } 2505 }
2519
2520 o = edje_object_add(evas_object_evas_get(data));
2521 if (!elm_widget_theme_object_set
2522 (data, o, "text", item, style))
2523 elm_widget_theme_object_set
2524 (data, o, "text/emoticon", "wtf", style);
2525 return o; 2506 return o;
2526} 2507}
2527 2508
@@ -3215,6 +3196,7 @@ _efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *sd)
3215 if (_elm_config->desktop_entry) 3196 if (_elm_config->desktop_entry)
3216 sd->sel_handler_disabled = EINA_TRUE; 3197 sd->sel_handler_disabled = EINA_TRUE;
3217 3198
3199 sd->item_fallback_factory = efl_add(EFL_UI_TEXT_FACTORY_FALLBACK_CLASS, obj);
3218 _create_text_cursors(obj, sd); 3200 _create_text_cursors(obj, sd);
3219 3201
3220 return obj; 3202 return obj;
@@ -3224,7 +3206,6 @@ EOLIAN static void
3224_efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd) 3206_efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
3225{ 3207{
3226 Elm_Entry_Context_Menu_Item *it; 3208 Elm_Entry_Context_Menu_Item *it;
3227 Elm_Entry_Item_Provider *ip;
3228 Elm_Entry_Markup_Filter *tf; 3209 Elm_Entry_Markup_Filter *tf;
3229 Eo *text_obj; 3210 Eo *text_obj;
3230 3211
@@ -3270,10 +3251,6 @@ _efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
3270 eina_stringshare_del(it->icon_group); 3251 eina_stringshare_del(it->icon_group);
3271 free(it); 3252 free(it);
3272 } 3253 }
3273 EINA_LIST_FREE(sd->item_providers, ip)
3274 {
3275 free(ip);
3276 }
3277 EINA_LIST_FREE(sd->markup_filters, tf) 3254 EINA_LIST_FREE(sd->markup_filters, tf)
3278 { 3255 {
3279 _filter_free(tf); 3256 _filter_free(tf);
@@ -3314,6 +3291,9 @@ _efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
3314 ecore_job_del(sd->deferred_decoration_job); 3291 ecore_job_del(sd->deferred_decoration_job);
3315 sd->deferred_decoration_job = NULL; 3292 sd->deferred_decoration_job = NULL;
3316 3293
3294 if (sd->item_factory) efl_unref(sd->item_factory);
3295 if (sd->item_fallback_factory) efl_del(sd->item_fallback_factory);
3296
3317 efl_destructor(efl_super(obj, MY_CLASS)); 3297 efl_destructor(efl_super(obj, MY_CLASS));
3318} 3298}
3319 3299
@@ -3539,55 +3519,6 @@ _efl_ui_text_context_menu_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd
3539 return !sd->context_menu; 3519 return !sd->context_menu;
3540} 3520}
3541 3521
3542EOLIAN static void
3543_efl_ui_text_item_provider_append(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
3544{
3545 Elm_Entry_Item_Provider *ip;
3546
3547 EINA_SAFETY_ON_NULL_RETURN(func);
3548
3549 ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3550 if (!ip) return;
3551
3552 ip->func = func;
3553 ip->data = data;
3554 sd->item_providers = eina_list_append(sd->item_providers, ip);
3555}
3556
3557EOLIAN static void
3558_efl_ui_text_item_provider_prepend(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
3559{
3560 Elm_Entry_Item_Provider *ip;
3561
3562 EINA_SAFETY_ON_NULL_RETURN(func);
3563
3564 ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
3565 if (!ip) return;
3566
3567 ip->func = func;
3568 ip->data = data;
3569 sd->item_providers = eina_list_prepend(sd->item_providers, ip);
3570}
3571
3572EOLIAN static void
3573_efl_ui_text_item_provider_remove(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
3574{
3575 Eina_List *l;
3576 Elm_Entry_Item_Provider *ip;
3577
3578 EINA_SAFETY_ON_NULL_RETURN(func);
3579
3580 EINA_LIST_FOREACH(sd->item_providers, l, ip)
3581 {
3582 if ((ip->func == func) && ((!data) || (ip->data == data)))
3583 {
3584 sd->item_providers = eina_list_remove_list(sd->item_providers, l);
3585 free(ip);
3586 return;
3587 }
3588 }
3589}
3590
3591EOLIAN static Eina_Bool 3522EOLIAN static Eina_Bool
3592_efl_ui_text_efl_file_file_set(Eo *obj, Efl_Ui_Text_Data *sd, const char *file, const char *group EINA_UNUSED) 3523_efl_ui_text_efl_file_file_set(Eo *obj, Efl_Ui_Text_Data *sd, const char *file, const char *group EINA_UNUSED)
3593{ 3524{
@@ -4927,8 +4858,7 @@ _anchors_create(Eo *obj, Efl_Ui_Text_Data *sd)
4927 Eina_Bool is_anchor = EINA_FALSE; 4858 Eina_Bool is_anchor = EINA_FALSE;
4928 Eina_Bool is_item = EINA_FALSE; 4859 Eina_Bool is_item = EINA_FALSE;
4929 4860
4930 if (efl_text_object_item_geometry_get(obj, anchor, 4861 if (efl_text_annotation_is_item(obj, anchor))
4931 NULL, NULL, NULL, NULL))
4932 { 4862 {
4933 is_anchor = EINA_TRUE; 4863 is_anchor = EINA_TRUE;
4934 is_item = EINA_TRUE; 4864 is_item = EINA_TRUE;
@@ -5052,7 +4982,7 @@ _anchors_update(Eo *o, Efl_Ui_Text_Data *sd)
5052 { 4982 {
5053 rect->obj = ob; 4983 rect->obj = ob;
5054 4984
5055 efl_text_object_item_geometry_get(an->obj, 4985 efl_text_item_geometry_get(an->obj,
5056 an->annotation, &cx, &cy, &cw, &ch); 4986 an->annotation, &cx, &cy, &cw, &ch);
5057 evas_object_move(rect->obj, x + cx, y + cy); 4987 evas_object_move(rect->obj, x + cx, y + cy);
5058 evas_object_resize(rect->obj, cw, ch); 4988 evas_object_resize(rect->obj, cw, ch);
@@ -5296,6 +5226,20 @@ _efl_ui_text_move_cb(void *data, Evas *e EINA_UNUSED,
5296 _decoration_defer_all(data); 5226 _decoration_defer_all(data);
5297} 5227}
5298 5228
5229static void
5230_efl_ui_text_item_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd,
5231 Efl_Canvas_Text_Factory *item_factory)
5232{
5233 if (pd->item_factory) efl_unref(pd->item_factory);
5234 pd->item_factory = efl_ref(item_factory);
5235}
5236
5237static Eo *
5238_efl_ui_text_item_factory_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *pd)
5239{
5240 return pd->item_factory;
5241}
5242
5299#if 0 5243#if 0
5300/* Efl.Part begin */ 5244/* Efl.Part begin */
5301 5245
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,
233 enabled: bool; [[If $enabled is $true, the return key is automatically disabled when the entry has no text.]] 233 enabled: bool; [[If $enabled is $true, the return key is automatically disabled when the entry has no text.]]
234 } 234 }
235 } 235 }
236 item_provider_prepend { 236 @property item_factory {
237 [[This prepends a custom item provider to the list for that entry 237 [[The factory that provides item in the text e.g.
238 238 "emoticon/happy" or "href=file://image.jpg" etc.
239 This prepends the given callback.]] 239 ]]
240 params { 240 values {
241 @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]] 241 item_factory: Efl.Canvas.Text.Factory; [[Factory to create items]]
242 @in data: void_ptr @optional; [[The data passed to $func.]]
243 } 242 }
244 } 243 }
245 input_panel_show { 244 input_panel_show {
@@ -252,17 +251,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
252 selection_copy { 251 selection_copy {
253 [[This executes a "copy" action on the selected text in the entry.]] 252 [[This executes a "copy" action on the selected text in the entry.]]
254 } 253 }
255 item_provider_remove {
256 [[This removes a custom item provider to the list for that entry
257
258 This removes the given callback. See @.item_provider_append for
259 more information
260 ]]
261 params {
262 @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
263 @in data: void_ptr @optional; [[The data passed to $func.]]
264 }
265 }
266 context_menu_clear { 254 context_menu_clear {
267 [[This clears and frees the items in a entry's contextual (longpress) 255 [[This clears and frees the items in a entry's contextual (longpress)
268 menu. 256 menu.
@@ -306,23 +294,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
306 selection_cut { 294 selection_cut {
307 [[This executes a "cut" action on the selected text in the entry.]] 295 [[This executes a "cut" action on the selected text in the entry.]]
308 } 296 }
309 item_provider_append {
310 [[This appends a custom item provider to the list for that entry
311
312 This appends the given callback. The list is walked from beginning to end
313 with each function called given the item href string in the text. If the
314 function returns an object handle other than $null (it should create an
315 object to do this), then this object is used to replace that item. If
316 not the next provider is called until one provides an item object, or the
317 default provider in entry does.
318
319 See also \@ref entry-items.
320 ]]
321 params {
322 @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
323 @in data: void_ptr @optional; [[The data passed to $func.]]
324 }
325 }
326 context_menu_item_add { 297 context_menu_item_add {
327 [[This adds an item to the entry's contextual menu. 298 [[This adds an item to the entry's contextual menu.
328 299
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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6#include <Elementary_Cursor.h>
7#include "elm_priv.h"
8
9#define MY_CLASS EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS
10
11typedef struct _Efl_Ui_Text_Factory_Emoticons_Data Efl_Ui_Text_Factory_Emoticons_Data;
12
13struct _Efl_Ui_Text_Factory_Emoticons_Data
14{
15 const char *name;
16};
17
18EOLIAN static Eo *
19_efl_ui_text_factory_emoticons_efl_object_constructor(Eo *obj,
20 Efl_Ui_Text_Factory_Emoticons_Data *pd EINA_UNUSED)
21{
22 obj = efl_constructor(efl_super(obj, MY_CLASS));
23 return obj;
24}
25
26EOLIAN static void
27_efl_ui_text_factory_emoticons_efl_object_destructor(Eo *obj,
28 Efl_Ui_Text_Factory_Emoticons_Data *pd EINA_UNUSED)
29{
30 efl_destructor(efl_super(obj, MY_CLASS));
31}
32
33
34EOLIAN static Efl_Canvas_Object
35*_efl_ui_text_factory_emoticons_efl_canvas_text_factory_create(
36 Eo *obj EINA_UNUSED,
37 Efl_Ui_Text_Factory_Emoticons_Data *pd EINA_UNUSED,
38 Efl_Canvas_Object *object,
39 const char *key)
40{
41 Eo *o;
42 const char *style = elm_widget_style_get(object);
43
44 o = edje_object_add(evas_object_evas_get(object));
45 if (!_elm_theme_object_set
46 (object, o, "text", key, style))
47 _elm_theme_object_set
48 (object, o, "text/emoticon", "wtf", style);
49 return o;
50}
51
52#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 @@
1class Efl.Ui.Text.Factory.Emoticons (Efl.Object, Efl.Canvas.Text.Factory)
2{
3 [[Factory that creates emoticons from the current theme given a key.
4
5 @since 1.21
6 ]]
7 implements {
8 Efl.Object.constructor;
9 Efl.Object.destructor;
10 Efl.Canvas.Text.Factory.create;
11 }
12}
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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6#include <Elementary_Cursor.h>
7#include "elm_priv.h"
8
9#define MY_CLASS EFL_UI_TEXT_FACTORY_FALLBACK_CLASS
10
11typedef struct _Efl_Ui_Text_Factory_Fallback_Data Efl_Ui_Text_Factory_Fallback_Data;
12
13struct _Efl_Ui_Text_Factory_Fallback_Data
14{
15 Efl_Canvas_Text_Factory *emoticon_factory, *image_factory;
16};
17
18EOLIAN static Eo *
19_efl_ui_text_factory_fallback_efl_object_constructor(Eo *obj,
20 Efl_Ui_Text_Factory_Fallback_Data *pd EINA_UNUSED)
21{
22 obj = efl_constructor(efl_super(obj, MY_CLASS));
23 pd->image_factory = efl_add(EFL_UI_TEXT_FACTORY_IMAGES_CLASS, obj);
24 pd->emoticon_factory = efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, obj);
25 return obj;
26}
27
28EOLIAN static void
29_efl_ui_text_factory_fallback_efl_object_destructor(Eo *obj,
30 Efl_Ui_Text_Factory_Fallback_Data *pd EINA_UNUSED)
31{
32 efl_del(pd->emoticon_factory);
33 efl_del(pd->image_factory);
34 efl_destructor(efl_super(obj, MY_CLASS));
35}
36
37
38EOLIAN static Efl_Canvas_Object
39*_efl_ui_text_factory_fallback_efl_canvas_text_factory_create(
40 Eo *obj EINA_UNUSED,
41 Efl_Ui_Text_Factory_Fallback_Data *pd EINA_UNUSED,
42 Efl_Canvas_Object *object,
43 const char *key)
44{
45 Efl_Canvas_Object *o = NULL;
46
47 // Parse the string. Can be either:
48 // 1. some/name - an emoticon (load from theme)
49 // 2. file:// - image file
50 if (key && !strncmp(key, "file://", 7))
51 {
52 const char *fname = key + 7;
53 o = efl_canvas_text_factory_create(pd->image_factory, object, fname);
54 }
55 else
56 {
57 o = efl_canvas_text_factory_create(pd->emoticon_factory, object, key);
58 }
59 return o;
60}
61
62#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 @@
1class Efl.Ui.Text.Factory.Fallback (Efl.Object, Efl.Canvas.Text.Factory)
2{
3 [[Internal factory for fallback cases.
4
5 This wraps some internal functionality:
6 - Contains 2 factories: image and emoticon
7 - Strips off "file://" prefix for image items, to be used with the image
8 factory.
9 @since 1.21
10 ]]
11 implements {
12 Efl.Object.constructor;
13 Efl.Object.destructor;
14 Efl.Canvas.Text.Factory.create;
15 }
16}
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 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6#include <Elementary_Cursor.h>
7#include "elm_priv.h"
8
9#define MY_CLASS EFL_UI_TEXT_FACTORY_IMAGES_CLASS
10
11typedef struct _Efl_Ui_Text_Factory_Images_Data Efl_Ui_Text_Factory_Images_Data;
12
13struct _Efl_Ui_Text_Factory_Images_Data
14{
15 const char *name;
16 Eina_Hash *hash;
17};
18
19typedef struct
20{
21 Eina_File *file;
22 const char *key;
23} File_Entry;
24
25static void
26_entry_free_cb(void *data)
27{
28 File_Entry *e = data;
29 eina_file_close(e->file);
30 eina_stringshare_del(e->key);
31 free(e);
32}
33
34EOLIAN static Eo *
35_efl_ui_text_factory_images_efl_object_constructor(Eo *obj,
36 Efl_Ui_Text_Factory_Images_Data *pd EINA_UNUSED)
37{
38 obj = efl_constructor(efl_super(obj, MY_CLASS));
39 pd->hash = eina_hash_string_superfast_new(_entry_free_cb);
40 return obj;
41}
42
43EOLIAN static void
44_efl_ui_text_factory_images_efl_object_destructor(Eo *obj,
45 Efl_Ui_Text_Factory_Images_Data *pd EINA_UNUSED)
46{
47 eina_hash_free(pd->hash);
48 efl_destructor(efl_super(obj, MY_CLASS));
49}
50
51EOLIAN static Efl_Canvas_Object *
52_efl_ui_text_factory_images_efl_canvas_text_factory_create(Eo *obj EINA_UNUSED,
53 Efl_Ui_Text_Factory_Images_Data *pd EINA_UNUSED,
54 Efl_Canvas_Object *object,
55 const char *key)
56{
57 Efl_Canvas_Object *o;
58 File_Entry *e;
59
60 o = efl_add(EFL_CANVAS_IMAGE_CLASS, object);
61 e = eina_hash_find(pd->hash, key);
62 if (e)
63 {
64 efl_file_mmap_set(o, e->file, e->key);
65 }
66 else
67 {
68 efl_file_set(o, key, NULL);
69 }
70
71 if (efl_file_load_error_get(o) != EFL_IMAGE_LOAD_ERROR_NONE)
72 {
73 efl_del(o);
74 o = NULL;
75 }
76
77 return o;
78}
79
80EOLIAN static Eina_Bool
81_efl_ui_text_factory_images_matches_add(Eo *obj EINA_UNUSED,
82 Efl_Ui_Text_Factory_Images_Data *pd,
83 const char *name, const char *file, const char *key)
84{
85 File_Entry *e;
86 Eina_File *f = eina_file_open(file, EINA_FALSE);
87
88 if (!f) return EINA_FALSE;
89
90 e = malloc(sizeof(*e));
91 e->file = f;
92 e->key = eina_stringshare_add(key);
93
94 if (!eina_hash_add(pd->hash, name, e))
95 {
96 ERR("Failed to add file path %s to key %s\n", file, key);
97 eina_file_close(f);
98 free(e);
99 return EINA_FALSE;
100 }
101
102 return EINA_TRUE;
103}
104
105EOLIAN static Eina_Bool
106_efl_ui_text_factory_images_matches_del(Eo *obj EINA_UNUSED,
107 Efl_Ui_Text_Factory_Images_Data *pd,
108 const char *name)
109{
110 return eina_hash_del(pd->hash, name, NULL);
111}
112
113EOLIAN static Eina_Bool
114_efl_ui_text_factory_images_matches_mmap_add(Eo *obj EINA_UNUSED,
115 Efl_Ui_Text_Factory_Images_Data *pd,
116 const char *name, const Eina_File *file, const char *key)
117{
118 File_Entry *e;
119 Eina_File *f;
120
121 if (!file) return EINA_FALSE;
122
123 f = eina_file_dup(file);
124 e = malloc(sizeof(*e));
125 e->file = f;
126 e->key = eina_stringshare_add(key);
127
128 if (!eina_hash_add(pd->hash, name, e))
129 {
130 ERR("Failed to add Eina_File %p to key %s\n", file, key);
131 eina_file_close(f);
132 free(e);
133 return EINA_FALSE;
134 }
135
136 return EINA_TRUE;
137}
138
139EOLIAN static Eina_Bool
140_efl_ui_text_factory_images_matches_mmap_del(Eo *obj EINA_UNUSED,
141 Efl_Ui_Text_Factory_Images_Data *pd,
142 const char *name)
143{
144 return eina_hash_del(pd->hash, name, NULL);
145}
146
147#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 @@
1class Efl.Ui.Text.Factory.Images (Efl.Object, Efl.Canvas.Text.Factory)
2{
3 [[Factory that creates images given key string
4
5 The key can be either a full image path, or associated with one. The
6 factory will fallback if key was not matches with an image, and try
7 to load it as a full path.
8
9 @since 1.21
10 ]]
11 methods {
12 matches_add {
13 [[Associates given name with a path of an image or EET file.
14
15 This can be used for quick retrieval (instead of
16 providing actual filenames.
17
18 This $file is associated with $name is considered a full file path.
19
20 see @.matches_mmap_add for mmap version
21 see @.matches_del
22 ]]
23 params {
24 name: string; [[the name associated with filename]]
25 path: string; [[the image or EET file path]]
26 key: string; [[the key to use (in cases of loading an EET file]]
27 }
28 return: bool; [[$true if successful, $false otherwise]]
29 }
30 matches_del {
31 [[Deletes an association of $key with its respective file path.
32
33 see @.matches_add
34 ]]
35 params {
36 key: string; [[the entry's key to delete]]
37 }
38 return: bool; [[$true if successful, $false otherwise]]
39 }
40 matches_mmap_add {
41 [[Associates given name with a mmap'd image or EET file and key.
42
43 see @.matches_add for string file path version
44 see @.matches_mmap_del
45 ]]
46 params {
47 name: string; [[the name associated with filename]]
48 file: ptr(const(Eina.File)); [[the image or EET file]]
49 key: string; [[the key to use (in cases of loading an EET file]]
50 }
51 return: bool; [[$true if successful, $false otherwise]]
52 }
53 matches_mmap_del {
54 [[Deletes an association of $key with its respective file.
55
56 see @.matches_mmap_add
57 ]]
58 params {
59 key: string; [[the entry's key to delete]]
60 }
61 return: bool; [[$true if successful, $false otherwise]]
62 }
63 }
64 implements {
65 Efl.Object.constructor;
66 Efl.Object.destructor;
67 Efl.Canvas.Text.Factory.create;
68 }
69}
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 @@
21 */ 21 */
22//#include "canvas/efl_canvas_text_cursor.eo.h" 22//#include "canvas/efl_canvas_text_cursor.eo.h"
23#include "canvas/efl_canvas_text.eo.h" 23#include "canvas/efl_canvas_text.eo.h"
24#include "canvas/efl_canvas_text_factory.eo.h"
24/** 25/**
25 * @} 26 * @}
26 */ 27 */
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,
345 Efl.Text.Annotate.range_annotations_get; 345 Efl.Text.Annotate.range_annotations_get;
346 Efl.Text.Annotate.annotation_insert; 346 Efl.Text.Annotate.annotation_insert;
347 Efl.Text.Annotate.annotation_del; 347 Efl.Text.Annotate.annotation_del;
348 Efl.Text.Annotate.object_item_geometry_get; 348 Efl.Text.Annotate.annotation_is_item;
349 Efl.Text.Annotate.item_geometry_get;
349 Efl.Text.Annotate.annotation_positions_get; 350 Efl.Text.Annotate.annotation_positions_get;
350 Efl.Text.Annotate.cursor_object_item_annotation { get; } 351 Efl.Text.Annotate.cursor_item_annotation { get; }
351 Efl.Text.Annotate.cursor_object_item_insert; 352 Efl.Text.Annotate.cursor_item_insert;
352 Efl.Text.Markup.markup { set; get; } 353 Efl.Text.Markup.markup { set; get; }
353 Efl.Text.Markup.cursor_markup_insert; 354 Efl.Text.Markup.cursor_markup_insert;
354 Efl.Gfx.scale { set; } 355 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 @@
1interface Efl.Canvas.Text.Factory ()
2{
3 [[Object factory that creates Efl.Canvas.Object objects.
4
5 Translates a given key to an object (item), to be later placed in a text
6 for higher level usages. The translation implementation is left to be
7 decided by the inheriting class, whether it is by treating the $key as an
8 image path, or a key associated with a real-path in a hashtable
9 or something else entirely.
10
11 @since 1.21
12 ]]
13 methods {
14 create {
15 [[Translates a given $key to an item object, and returns the object.
16 The returned object should be owned by the passed $object.
17 ]]
18 params {
19 object: Efl.Canvas.Object; [[The parent of the created object]]
20 key: string; [[Key that is associated to an item object]]
21 }
22 return: Efl.Canvas.Object @owned;
23 }
24 }
25}
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,
15123} 15123}
15124 15124
15125EOLIAN static Efl_Text_Annotate_Annotation * 15125EOLIAN static Efl_Text_Annotate_Annotation *
15126_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) 15126_efl_canvas_text_efl_text_annotate_cursor_item_insert(Eo *eo_obj,
15127 Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur,
15128 const char *item, const char *format)
15127{ 15129{
15130 Eina_Strbuf *buf = eina_strbuf_new();
15131
15132 eina_strbuf_append_printf(buf, "%s href=%s", format, item);
15133
15128 Efl_Text_Annotate_Annotation *ret = 15134 Efl_Text_Annotate_Annotation *ret =
15129 _textblock_annotation_insert(cur->obj, o, cur, cur, format, EINA_TRUE); 15135 _textblock_annotation_insert(cur->obj, o, cur, cur,
15136 eina_strbuf_string_get(buf), EINA_TRUE);
15137 eina_strbuf_free(buf);
15130 efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL); 15138 efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
15131 return ret; 15139 return ret;
15132} 15140}
15133 15141
15134EOLIAN static Efl_Text_Annotate_Annotation * 15142EOLIAN static Efl_Text_Annotate_Annotation *
15135_efl_canvas_text_efl_text_annotate_cursor_object_item_annotation_get(Eo *eo_obj EINA_UNUSED, 15143_efl_canvas_text_efl_text_annotate_cursor_item_annotation_get(Eo *eo_obj EINA_UNUSED,
15136 Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur) 15144 Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
15137{ 15145{
15138 Eina_Iterator *it; 15146 Eina_Iterator *it;
@@ -15153,7 +15161,21 @@ _efl_canvas_text_efl_text_annotate_cursor_object_item_annotation_get(Eo *eo_obj
15153} 15161}
15154 15162
15155EOLIAN static Eina_Bool 15163EOLIAN static Eina_Bool
15156_efl_canvas_text_efl_text_annotate_object_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, 15164_efl_canvas_text_efl_text_annotate_annotation_is_item(Eo *eo_obj EINA_UNUSED,
15165 Efl_Canvas_Text_Data *o EINA_UNUSED,
15166 Efl_Text_Annotate_Annotation *annotation)
15167{
15168 if (!annotation || (annotation->obj != eo_obj))
15169 {
15170 ERR("Used invalid handle or of a different object");
15171 return EINA_FALSE;
15172 }
15173
15174 return annotation->is_item;
15175}
15176
15177EOLIAN static Eina_Bool
15178_efl_canvas_text_efl_text_annotate_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
15157 const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) 15179 const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
15158{ 15180{
15159 Efl_Text_Cursor_Cursor cur; 15181 Efl_Text_Cursor_Cursor cur;
@@ -16264,3 +16286,4 @@ _efl_canvas_text_async_layout(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o)
16264} 16286}
16265 16287
16266#include "canvas/efl_canvas_text.eo.c" 16288#include "canvas/efl_canvas_text.eo.c"
16289#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)
4371 /* Check "item" annotations */ 4371 /* Check "item" annotations */
4372 efl_text_set(tb, "abcd"); 4372 efl_text_set(tb, "abcd");
4373 evas_textblock_cursor_pos_set(cur, 4); 4373 evas_textblock_cursor_pos_set(cur, 4);
4374 an = efl_text_cursor_object_item_insert(tb, cur, "size=16x16"); 4374 an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
4375 _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16")); 4375 _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16 href="));
4376 4376
4377 /* Check that format is not extended if it's an "object item" */ 4377 /* Check that format is not extended if it's an "object item" */
4378 evas_textblock_cursor_pos_set(cur, 5); 4378 evas_textblock_cursor_pos_set(cur, 5);
@@ -4417,14 +4417,14 @@ START_TEST(evas_textblock_annotation)
4417 4417
4418 /* Test getting of object item */ 4418 /* Test getting of object item */
4419 evas_textblock_cursor_pos_set(cur, 4); 4419 evas_textblock_cursor_pos_set(cur, 4);
4420 an = efl_text_cursor_object_item_annotation_get(tb, cur); 4420 an = efl_text_cursor_item_annotation_get(tb, cur);
4421 ck_assert(!an); 4421 ck_assert(!an);
4422 4422
4423 an = efl_text_cursor_object_item_insert(tb, cur, "size=16x16"); 4423 an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
4424 evas_textblock_cursor_pos_set(cur, 4); 4424 evas_textblock_cursor_pos_set(cur, 4);
4425 an = efl_text_cursor_object_item_annotation_get(tb, cur); 4425 an = efl_text_cursor_item_annotation_get(tb, cur);
4426 ck_assert(an); 4426 ck_assert(an);
4427 ck_assert_str_eq("size=16x16", efl_text_annotation_get(tb, an)); 4427 ck_assert_str_eq("size=16x16 href=", efl_text_annotation_get(tb, an));
4428 4428
4429 END_TB_TEST(); 4429 END_TB_TEST();
4430} 4430}