Canvas image: add Efl.Canvas.Text.Factory + use in Ui.Text
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
This commit is contained in:
parent
2eac0dd89d
commit
4a905a22a4
|
@ -50,7 +50,8 @@ elementary_images_files = \
|
||||||
elementary/images/pm_fill.png \
|
elementary/images/pm_fill.png \
|
||||||
elementary/images/pt.png \
|
elementary/images/pt.png \
|
||||||
elementary/images/earth_normal.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_glayer_files = \
|
||||||
elementary/images/g_layer/double_tap_1.png \
|
elementary/images/g_layer/double_tap_1.png \
|
||||||
|
|
Binary file not shown.
|
@ -45,6 +45,9 @@ elm_public_eolian_files = \
|
||||||
lib/elementary/efl_ui_popup_anchor.eo \
|
lib/elementary/efl_ui_popup_anchor.eo \
|
||||||
lib/elementary/efl_ui_text_editable.eo \
|
lib/elementary/efl_ui_text_editable.eo \
|
||||||
lib/elementary/efl_ui_text_async.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_textpath.eo \
|
||||||
lib/elementary/efl_ui_translatable.eo \
|
lib/elementary/efl_ui_translatable.eo \
|
||||||
lib/elementary/efl_ui_clock.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_static.c \
|
||||||
lib/elementary/efl_ui_table_private.h \
|
lib/elementary/efl_ui_table_private.h \
|
||||||
lib/elementary/efl_ui_text.c \
|
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.c \
|
||||||
lib/elementary/efl_ui_clock_private.h \
|
lib/elementary/efl_ui_clock_private.h \
|
||||||
lib/elementary/efl_ui_image_factory.c \
|
lib/elementary/efl_ui_image_factory.c \
|
||||||
|
|
|
@ -7,6 +7,7 @@ evas_canvas_eolian_pub_files = \
|
||||||
lib/evas/canvas/efl_canvas_polygon.eo \
|
lib/evas/canvas/efl_canvas_polygon.eo \
|
||||||
lib/evas/canvas/efl_canvas_rectangle.eo \
|
lib/evas/canvas/efl_canvas_rectangle.eo \
|
||||||
lib/evas/canvas/efl_canvas_text.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_group.eo \
|
||||||
lib/evas/canvas/efl_canvas_image_internal.eo \
|
lib/evas/canvas/efl_canvas_image_internal.eo \
|
||||||
lib/evas/canvas/evas_canvas3d_camera.eo\
|
lib/evas/canvas/evas_canvas3d_camera.eo\
|
||||||
|
|
|
@ -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(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_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_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_evas_mask(void *data, Edje_Object *obj, void *event_info);
|
||||||
void test_gfx_filters(void *data, Evas_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);
|
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", 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 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", "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);
|
ADD_TEST(NULL, "Advanced Entries", "Code Syntax", test_code_syntax);
|
||||||
|
|
|
@ -144,8 +144,8 @@ static void
|
||||||
my_efl_ui_text_bt_4(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
my_efl_ui_text_bt_4(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Evas_Object *en = data;
|
Evas_Object *en = data;
|
||||||
efl_text_cursor_object_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
|
efl_text_cursor_item_insert(en, efl_text_cursor_get(en, EFL_TEXT_CURSOR_GET_MAIN),
|
||||||
"size=32x32 href=emoticon/evil-laugh");
|
"emoticon/evil-laugh", "size=32x32");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
Evas_Object *win, *bx, *bx2, *bx3, *bt, *en;
|
||||||
Efl_Text_Cursor_Cursor *main_cur, *cur;
|
Efl_Text_Cursor_Cursor *main_cur, *cur;
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
win = elm_win_util_standard_add("entry", "Entry");
|
win = elm_win_util_standard_add("entry", "Entry");
|
||||||
elm_win_autodel_set(win, EINA_TRUE);
|
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);
|
cur = efl_text_cursor_new(en);
|
||||||
|
|
||||||
efl_text_cursor_position_set(en, cur, 2);
|
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_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, main_cur, 5);
|
||||||
efl_text_cursor_position_set(en, cur, 20);
|
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);
|
elm_win_resize_object_add(win, bx);
|
||||||
evas_object_show(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_wrap_set(efl_added, EFL_TEXT_FORMAT_WRAP_WORD),
|
||||||
efl_text_multiline_set(efl_added, EINA_TRUE)
|
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_resize(win, 480, 320);
|
||||||
evas_object_show(win);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -76,23 +76,6 @@ interface Efl.Text.Annotate {
|
||||||
}
|
}
|
||||||
return: bool; [[$true on success, $false otherwise.]]
|
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 {
|
annotation_positions_get {
|
||||||
[[Sets given cursors to the start and end positions of the annotation.
|
[[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]]
|
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
|
// Cursor
|
||||||
@property cursor_object_item_annotation {
|
@property cursor_item_annotation {
|
||||||
[[The object-item annotation at the cursor's position.]]
|
[[The object-item annotation at the cursor's position.]]
|
||||||
get {
|
get {
|
||||||
legacy: null;
|
legacy: null;
|
||||||
|
@ -124,7 +140,7 @@ interface Efl.Text.Annotate {
|
||||||
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
|
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor_object_item_insert {
|
cursor_item_insert {
|
||||||
[[Inserts a object item at specified position.
|
[[Inserts a object item at specified position.
|
||||||
|
|
||||||
This adds a placeholder to be queried by higher-level code,
|
This adds a placeholder to be queried by higher-level code,
|
||||||
|
@ -134,8 +150,11 @@ interface Efl.Text.Annotate {
|
||||||
legacy: null;
|
legacy: null;
|
||||||
params {
|
params {
|
||||||
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
|
cur: ptr(Efl.Text.Cursor.Cursor); [[Cursor object]]
|
||||||
@in format: string; [[Format of the inserted item.
|
@in item: string; [[Item key to be used in higher-up
|
||||||
See Format styles.]]
|
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
|
return: ptr(Efl.Text.Annotate.Annotation); [[The annotation handle of the
|
||||||
inserted item.]]
|
inserted item.]]
|
||||||
|
|
|
@ -311,6 +311,9 @@ typedef Eo Efl_Ui_Focus_Manager;
|
||||||
# include <efl_ui_popup_alert_scroll.eo.h>
|
# include <efl_ui_popup_alert_scroll.eo.h>
|
||||||
# include <efl_ui_popup_alert_text.eo.h>
|
# include <efl_ui_popup_alert_text.eo.h>
|
||||||
# include <efl_ui_popup_anchor.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_editable.eo.h>
|
||||||
# include <efl_ui_text_async.eo.h>
|
# include <efl_ui_text_async.eo.h>
|
||||||
# include <efl_ui_clock.eo.h>
|
# include <efl_ui_clock.eo.h>
|
||||||
|
|
|
@ -63,7 +63,8 @@ struct _Efl_Ui_Text_Data
|
||||||
Eina_List *sel;
|
Eina_List *sel;
|
||||||
Eina_List *items; /** context menu item list */
|
Eina_List *items; /** context menu item list */
|
||||||
Item_Obj *item_objs;
|
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;
|
Eina_List *markup_filters;
|
||||||
Ecore_Job *hov_deljob;
|
Ecore_Job *hov_deljob;
|
||||||
Mod_Api *api; // module api if supplied
|
Mod_Api *api; // module api if supplied
|
||||||
|
@ -131,6 +132,7 @@ struct _Efl_Ui_Text_Data
|
||||||
Eina_Bool scroll : 1;
|
Eina_Bool scroll : 1;
|
||||||
Eina_Bool input_panel_show_on_demand : 1;
|
Eina_Bool input_panel_show_on_demand : 1;
|
||||||
Eina_Bool anchors_updated : 1;
|
Eina_Bool anchors_updated : 1;
|
||||||
|
Eina_Bool fallback_item_provider_disabled : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Anchor
|
struct _Anchor
|
||||||
|
@ -2485,43 +2487,22 @@ _entry_mouse_triple_signal_cb(void *data,
|
||||||
static Evas_Object *
|
static Evas_Object *
|
||||||
_item_get(void *data, const char *item)
|
_item_get(void *data, const char *item)
|
||||||
{
|
{
|
||||||
Eina_List *l;
|
Evas_Object *o = NULL;
|
||||||
Evas_Object *o;
|
|
||||||
Elm_Entry_Item_Provider *ip;
|
|
||||||
const char *style = elm_widget_style_get(data);
|
|
||||||
|
|
||||||
EFL_UI_TEXT_DATA_GET(data, sd);
|
EFL_UI_TEXT_DATA_GET(data, sd);
|
||||||
|
|
||||||
EINA_LIST_FOREACH(sd->item_providers, l, ip)
|
if (item)
|
||||||
{
|
{
|
||||||
o = ip->func(ip->data, data, item);
|
if (sd->item_factory)
|
||||||
if (o) return o;
|
|
||||||
}
|
|
||||||
if (item && !strncmp(item, "file://", 7))
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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 = efl_canvas_text_factory_create(sd->item_fallback_factory,
|
||||||
o = edje_object_add(evas_object_evas_get(data));
|
data, item);
|
||||||
elm_widget_theme_object_set
|
|
||||||
(data, o, "text/emoticon", "wtf", style);
|
|
||||||
}
|
}
|
||||||
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;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3215,6 +3196,7 @@ _efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *sd)
|
||||||
if (_elm_config->desktop_entry)
|
if (_elm_config->desktop_entry)
|
||||||
sd->sel_handler_disabled = EINA_TRUE;
|
sd->sel_handler_disabled = EINA_TRUE;
|
||||||
|
|
||||||
|
sd->item_fallback_factory = efl_add(EFL_UI_TEXT_FACTORY_FALLBACK_CLASS, obj);
|
||||||
_create_text_cursors(obj, sd);
|
_create_text_cursors(obj, sd);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -3224,7 +3206,6 @@ EOLIAN static void
|
||||||
_efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
|
_efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd)
|
||||||
{
|
{
|
||||||
Elm_Entry_Context_Menu_Item *it;
|
Elm_Entry_Context_Menu_Item *it;
|
||||||
Elm_Entry_Item_Provider *ip;
|
|
||||||
Elm_Entry_Markup_Filter *tf;
|
Elm_Entry_Markup_Filter *tf;
|
||||||
Eo *text_obj;
|
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);
|
eina_stringshare_del(it->icon_group);
|
||||||
free(it);
|
free(it);
|
||||||
}
|
}
|
||||||
EINA_LIST_FREE(sd->item_providers, ip)
|
|
||||||
{
|
|
||||||
free(ip);
|
|
||||||
}
|
|
||||||
EINA_LIST_FREE(sd->markup_filters, tf)
|
EINA_LIST_FREE(sd->markup_filters, tf)
|
||||||
{
|
{
|
||||||
_filter_free(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);
|
ecore_job_del(sd->deferred_decoration_job);
|
||||||
sd->deferred_decoration_job = NULL;
|
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));
|
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;
|
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
|
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)
|
_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_anchor = EINA_FALSE;
|
||||||
Eina_Bool is_item = EINA_FALSE;
|
Eina_Bool is_item = EINA_FALSE;
|
||||||
|
|
||||||
if (efl_text_object_item_geometry_get(obj, anchor,
|
if (efl_text_annotation_is_item(obj, anchor))
|
||||||
NULL, NULL, NULL, NULL))
|
|
||||||
{
|
{
|
||||||
is_anchor = EINA_TRUE;
|
is_anchor = EINA_TRUE;
|
||||||
is_item = EINA_TRUE;
|
is_item = EINA_TRUE;
|
||||||
|
@ -5052,7 +4982,7 @@ _anchors_update(Eo *o, Efl_Ui_Text_Data *sd)
|
||||||
{
|
{
|
||||||
rect->obj = ob;
|
rect->obj = ob;
|
||||||
|
|
||||||
efl_text_object_item_geometry_get(an->obj,
|
efl_text_item_geometry_get(an->obj,
|
||||||
an->annotation, &cx, &cy, &cw, &ch);
|
an->annotation, &cx, &cy, &cw, &ch);
|
||||||
evas_object_move(rect->obj, x + cx, y + cy);
|
evas_object_move(rect->obj, x + cx, y + cy);
|
||||||
evas_object_resize(rect->obj, cw, ch);
|
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);
|
_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
|
#if 0
|
||||||
/* Efl.Part begin */
|
/* Efl.Part begin */
|
||||||
|
|
||||||
|
|
|
@ -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.]]
|
enabled: bool; [[If $enabled is $true, the return key is automatically disabled when the entry has no text.]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_provider_prepend {
|
@property item_factory {
|
||||||
[[This prepends a custom item provider to the list for that entry
|
[[The factory that provides item in the text e.g.
|
||||||
|
"emoticon/happy" or "href=file://image.jpg" etc.
|
||||||
This prepends the given callback.]]
|
]]
|
||||||
params {
|
values {
|
||||||
@in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
|
item_factory: Efl.Canvas.Text.Factory; [[Factory to create items]]
|
||||||
@in data: void_ptr @optional; [[The data passed to $func.]]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input_panel_show {
|
input_panel_show {
|
||||||
|
@ -252,17 +251,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
||||||
selection_copy {
|
selection_copy {
|
||||||
[[This executes a "copy" action on the selected text in the entry.]]
|
[[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 {
|
context_menu_clear {
|
||||||
[[This clears and frees the items in a entry's contextual (longpress)
|
[[This clears and frees the items in a entry's contextual (longpress)
|
||||||
menu.
|
menu.
|
||||||
|
@ -306,23 +294,6 @@ class Efl.Ui.Text (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
||||||
selection_cut {
|
selection_cut {
|
||||||
[[This executes a "cut" action on the selected text in the entry.]]
|
[[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 {
|
context_menu_item_add {
|
||||||
[[This adds an item to the entry's contextual menu.
|
[[This adds an item to the entry's contextual menu.
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
//#include "canvas/efl_canvas_text_cursor.eo.h"
|
//#include "canvas/efl_canvas_text_cursor.eo.h"
|
||||||
#include "canvas/efl_canvas_text.eo.h"
|
#include "canvas/efl_canvas_text.eo.h"
|
||||||
|
#include "canvas/efl_canvas_text_factory.eo.h"
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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.range_annotations_get;
|
||||||
Efl.Text.Annotate.annotation_insert;
|
Efl.Text.Annotate.annotation_insert;
|
||||||
Efl.Text.Annotate.annotation_del;
|
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.annotation_positions_get;
|
||||||
Efl.Text.Annotate.cursor_object_item_annotation { get; }
|
Efl.Text.Annotate.cursor_item_annotation { get; }
|
||||||
Efl.Text.Annotate.cursor_object_item_insert;
|
Efl.Text.Annotate.cursor_item_insert;
|
||||||
Efl.Text.Markup.markup { set; get; }
|
Efl.Text.Markup.markup { set; get; }
|
||||||
Efl.Text.Markup.cursor_markup_insert;
|
Efl.Text.Markup.cursor_markup_insert;
|
||||||
Efl.Gfx.scale { set; }
|
Efl.Gfx.scale { set; }
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15123,16 +15123,24 @@ _efl_canvas_text_efl_text_annotate_range_annotations_get(Eo *eo_obj EINA_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Text_Annotate_Annotation *
|
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 =
|
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);
|
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Text_Annotate_Annotation *
|
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)
|
Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
|
||||||
{
|
{
|
||||||
Eina_Iterator *it;
|
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
|
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)
|
const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
|
||||||
{
|
{
|
||||||
Efl_Text_Cursor_Cursor cur;
|
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.eo.c"
|
||||||
|
#include "canvas/efl_canvas_text_factory.eo.c" // interface
|
||||||
|
|
|
@ -4371,8 +4371,8 @@ START_TEST(evas_textblock_annotation)
|
||||||
/* Check "item" annotations */
|
/* Check "item" annotations */
|
||||||
efl_text_set(tb, "abcd");
|
efl_text_set(tb, "abcd");
|
||||||
evas_textblock_cursor_pos_set(cur, 4);
|
evas_textblock_cursor_pos_set(cur, 4);
|
||||||
an = efl_text_cursor_object_item_insert(tb, cur, "size=16x16");
|
an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
|
||||||
_test_check_annotation(tb, 4, 4, _COMP_PARAMS("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" */
|
/* Check that format is not extended if it's an "object item" */
|
||||||
evas_textblock_cursor_pos_set(cur, 5);
|
evas_textblock_cursor_pos_set(cur, 5);
|
||||||
|
@ -4417,14 +4417,14 @@ START_TEST(evas_textblock_annotation)
|
||||||
|
|
||||||
/* Test getting of object item */
|
/* Test getting of object item */
|
||||||
evas_textblock_cursor_pos_set(cur, 4);
|
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(!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);
|
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(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();
|
END_TB_TEST();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue