From: Ali Alzyod Date: Wed, 27 Nov 2019 04:04:31 +0000 (+0900) Subject: Efl.Text.Attribute_Factory X-Git-Tag: accepted/tizen/unified/20191128.161934~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=112a9fc1faba937c082424d5264019e179516f7f;p=platform%2Fupstream%2Fefl.git Efl.Text.Attribute_Factory Summary: Implementation of new Efl.Text.Attribute_Factory class which replace the annotation interface. Currently, we have two public methods: ``` void efl_text_attribute_factory_attribute_insert(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end, const char *format) unsigned int efl_text_attribute_factory_attribute_clear(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end); ``` Other methods will be internal methods, for the time being, we will redesign internal methods Reviewers: woohyun, tasn, segfaultxavi, bu5hm4n, zmike Subscribers: zmike, q66, cedric, segfaultxavi, bu5hm4n, a.srour, #committers, #reviewers Tags: #efl Differential Revision: https://phab.enlightenment.org/D10646 --- diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index a78850a..1d91bf5 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -366,7 +366,6 @@ 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_inputfield(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info); -void test_ui_text_item_factory(void *data, Evas_Object *obj, void *event_info); void test_evas_mask(void *data, Edje_Object *obj, void *event_info); void test_gfx_filters(void *data, Evas_Object *obj, void *event_info); void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info); @@ -941,7 +940,6 @@ add_tests: ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text", test_efl_ui_text); ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Input Field", test_efl_ui_text_inputfield); ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Label", test_efl_ui_text_label); - ADD_TEST_EO(NULL, "Entries", "Ui.Text Item Factory", test_ui_text_item_factory); ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Tags", test_ui_tags); //------------------------------// diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c index d56fddb..e060067 100644 --- a/src/bin/elementary/test_efl_ui_text.c +++ b/src/bin/elementary/test_efl_ui_text.c @@ -5,6 +5,7 @@ #include #include #include "elm_priv.h" //FIXME remove this once efl.ui.text doesn't need elm_general.h + static void _apply_style(Eo *obj, size_t start_pos, size_t end_pos, const char *style) { @@ -16,7 +17,7 @@ _apply_style(Eo *obj, size_t start_pos, size_t end_pos, const char *style) efl_text_cursor_position_set(start, start_pos); efl_text_cursor_position_set(end, end_pos); - efl_text_annotation_insert(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end), style); + efl_text_attribute_factory_attribute_insert(start, end, style); efl_del(start); efl_del(end); @@ -235,162 +236,3 @@ test_efl_ui_text_inputfield(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 200)); } - -#define IMAGES_SZ 5 - -static const char *images[IMAGES_SZ] = { - "sky", "logo", "dog", "eet_rock", "eet_plant" }; - -static void -_on_factory_bt_image_clicked(void *data, const Efl_Event *event 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_handle_get(efl_text_interactive_main_cursor_get(en)), - images[image_idx], "size=32x32"); - printf("Inserted image: key = %s\n", images[image_idx]); -} - -static void -_on_factory_bt_emoticon_clicked(void *data, const Efl_Event *event EINA_UNUSED) -{ - Evas_Object *en = data; - efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(efl_text_interactive_main_cursor_get(en)), - "emoticon/evil-laugh", "size=32x32"); -} - -static struct -{ - const char *name; - Eo *item_factory; -} factories[3]; - -static void -_on_factory_bt_factory_clicked(void *data, const Efl_Event *event 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 - -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, *bt, *en; - Efl_Text_Cursor *main_cur, *cur; - char buf[128]; - Eina_File *f; - - win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), - efl_text_set(efl_added, "Efl Ui Text Item Factory"), - efl_ui_win_autodel_set(efl_added, EINA_TRUE)); - - bx = efl_add(EFL_UI_BOX_CLASS, win); - efl_content_set(win, bx); - - en = efl_add(EFL_UI_TEXT_CLASS, bx, - 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, en); - - factories[FACTORY_EMOTICON].name = "Emoticon Factory"; - factories[FACTORY_EMOTICON].item_factory = - efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, en); - - // Test assigning file path source - snprintf(buf, sizeof(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); - snprintf(buf, sizeof(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); - snprintf(buf, sizeof(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 - snprintf(buf, sizeof(buf), "%s/images/image_items.eet", elm_app_data_dir_get()); - f = eina_file_open(buf, EINA_FALSE); - if (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"); - eina_file_close(f); - } - 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_interactive_main_cursor_get(en); - cur = efl_ui_text_cursor_create(en); - - efl_text_cursor_position_set(cur, 2); - efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(cur), "emoticon/happy", "size=32x32"); - efl_text_cursor_position_set(cur, 50); - - snprintf(buf, sizeof(buf), "file://%s/images/sky_01.jpg", elm_app_data_dir_get()); - efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(cur), buf, "size=32x32"); - efl_text_cursor_position_set(main_cur, 5); - - efl_text_interactive_editable_set(en, EINA_TRUE); - efl_ui_text_scrollable_set(en, EINA_TRUE); - efl_pack(bx, en); - elm_object_focus_set(en, EINA_TRUE); - - bx2 = efl_add(EFL_UI_BOX_CLASS, bx); - efl_gfx_hint_weight_set(bx2, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND); - efl_ui_layout_orientation_set(bx2, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL); - - bt = efl_add(EFL_UI_BUTTON_CLASS, bx2); - efl_text_set(bt, "Image"); - efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_image_clicked, en); - efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0); - efl_pack(bx2, bt); - elm_object_focus_allow_set(bt, EINA_FALSE); - - bt = efl_add(EFL_UI_BUTTON_CLASS, bx2); - efl_text_set(bt, "Emoticon"); - efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_emoticon_clicked, en); - efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0); - efl_pack(bx2, bt); - elm_object_focus_allow_set(bt, EINA_FALSE); - - bt = efl_add(EFL_UI_BUTTON_CLASS, bx2); - efl_text_set(bt, "Factory"); - efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_factory_clicked, en); - efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0); - efl_pack(bx2, bt); - elm_object_focus_allow_set(bt, EINA_FALSE); - - efl_pack(bx, bx2); - efl_gfx_entity_size_set(win, EINA_SIZE2D(480, 320)); -} diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index c78d105..a9970e2 100644 --- a/src/lib/efl/Efl.h +++ b/src/lib/efl/Efl.h @@ -70,7 +70,7 @@ typedef struct tm Efl_Time; typedef struct _Efl_Text_Cursor_Handle Efl_Text_Cursor_Handle; typedef struct _Efl_Text_Cursor_Handle _Efl_Text_Cursor_Handle; -typedef struct _Efl_Text_Annotate_Annotation Efl_Text_Annotate_Annotation; +typedef struct _Efl_Text_Attribute_Handle Efl_Text_Attribute_Handle; #include "interfaces/efl_types.eot.h" @@ -211,7 +211,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command; #include "interfaces/efl_text_font.eo.h" #include "interfaces/efl_text_style.eo.h" #include "interfaces/efl_text_format.eo.h" -#include "interfaces/efl_text_annotate.eo.h" #include "interfaces/efl_text_markup.eo.h" #include "interfaces/efl_text_markup_util.eo.h" diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c index 71162b9..3e94adc 100644 --- a/src/lib/efl/interfaces/efl_interfaces_main.c +++ b/src/lib/efl/interfaces/efl_interfaces_main.c @@ -24,7 +24,6 @@ #include "interfaces/efl_text_font.eo.c" #include "interfaces/efl_text_style.eo.c" #include "interfaces/efl_text_format.eo.c" -#include "interfaces/efl_text_annotate.eo.c" #include "interfaces/efl_text_markup.eo.c" #include "interfaces/efl_gfx_entity.eo.c" diff --git a/src/lib/efl/interfaces/efl_text_annotate.eo b/src/lib/efl/interfaces/efl_text_annotate.eo deleted file mode 100644 index 5ca1df8..0000000 --- a/src/lib/efl/interfaces/efl_text_annotate.eo +++ /dev/null @@ -1,137 +0,0 @@ -import efl_text_types; - -interface @beta Efl.Text_Annotate { - [[Cursor API - ]] - c_prefix: efl_text; - methods { - // Annotation - @property annotation { - [[A new format for $annotation. - - This will replace the format applied by $annotation with $format. - Assumes that $annotation is a handle for an existing annotation, - i.e. one that was added using @.annotation_insert to this object. - Otherwise, this will fail and return $false. - ]] - set { - return: bool; [[$true on success, $false otherwise.]] - } - get { - } - keys { - annotation: ptr(Efl.Text_Annotate_Annotation); [[Given annotation]] - } - values { - format: string; [[The new format for the given annotation]] - } - } - range_annotations_get @const { - [[Returns an iterator of all the handles in a range. - ]] - params { - @in start: ptr(const(Efl.Text_Cursor_Handle)); [[Start of range]] - @in end: ptr(const(Efl.Text_Cursor_Handle)); [[End of range]] - } - return: iterator @move; [[Handle of the Annotation]] - } - annotation_insert { - [[Inserts an annotation format in a specified range [$start, $end - 1]. - - The $format will be applied to the given range, and the $annotation - handle will be returned for further handling. - ]] - params { - @in start: ptr(Efl.Text_Cursor_Handle); [[Start of range]] - @in end: ptr(Efl.Text_Cursor_Handle); [[End of range]] - @in format: string; [[Annotation format]] - } - return: ptr(Efl.Text_Annotate_Annotation); [[Handle of inserted annotation]] - } - annotation_del { - [[Deletes given annotation. - - All formats applied by $annotation will be removed and it will be - deleted. - ]] - params { - @in annotation: ptr(Efl.Text_Annotate_Annotation); [[Annotation to be - removed]] - } - return: bool; [[$true on success, $false otherwise.]] - } - annotation_positions_get { - [[Sets given cursors to the start and end positions of the annotation. - - The cursors $start and $end will be set to the start and end - positions of the given annotation $annotation. - ]] - params { - @in annotation: ptr(const(Efl.Text_Annotate_Annotation)); [[Annotation - handle to query]] - @in start: ptr(Efl.Text_Cursor_Handle); [[Cursor to be set to the start - position of the annotation in the text]] - @in end: ptr(Efl.Text_Cursor_Handle); [[Cursor to be set to the end - 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 - ]] - 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. - ]] - params { - @in an: ptr(const(Efl.Text_Annotate_Annotation)); [[Given annotation to query]] - @out x: int; [[X coordinate of the annotation]] - @out y: int; [[Y coordinate of the annotation]] - @out w: int; [[Width of the annotation]] - @out h: int; [[Height of the annotation]] - } - return: bool; [[$true if given annotation is an object item, $false otherwise]] - } - // Cursor - @property cursor_item_annotation { - [[The object-item annotation at the cursor's position.]] - get { - } - values { - annotation: ptr(Efl.Text_Annotate_Annotation); [[Annotation]] - } - keys { - cur: ptr(Efl.Text_Cursor_Handle); [[Cursor object]] - } - } - cursor_item_insert { - [[Inserts a object item at specified position. - - This adds a placeholder to be queried by higher-level code, - which in turn place graphics on top of it. It essentially places an - OBJECT REPLACEMENT CHARACTER and set a special annotation to it. - ]] - params { - cur: ptr(Efl.Text_Cursor_Handle); [[Cursor object]] - @in item: string; [[Item key to be used in higher-up - code to query and decided what image, emoticon - etc. to embed.]] - @in format: string; [[Size format of the inserted item. - This hints how to size the item in the text.]] - } - return: ptr(Efl.Text_Annotate_Annotation); [[The annotation handle of the - inserted item.]] - } - } -} - diff --git a/src/lib/efl/interfaces/efl_text_types.eot b/src/lib/efl/interfaces/efl_text_types.eot index 9c8d3e5..9ae449c 100644 --- a/src/lib/efl/interfaces/efl_text_types.eot +++ b/src/lib/efl/interfaces/efl_text_types.eot @@ -28,6 +28,4 @@ struct @beta Efl.Ui.Text_Change_Info { merge: bool; [[$true if can be merged with the previous one. Used for example with insertion when something is already selected]] } -type @extern @beta Efl.Text_Annotate_Annotation: __undefined_type; [[EFL text annotations data structure]] - -struct @beta Efl.Text_Cursor_Handle; [[Opaque handle for Text cursors.]] +struct @extern @beta Efl.Text_Attribute_Handle; [[EFL text annotations data structure]] \ No newline at end of file diff --git a/src/lib/efl/interfaces/meson.build b/src/lib/efl/interfaces/meson.build index f45e743..a823e01 100644 --- a/src/lib/efl/interfaces/meson.build +++ b/src/lib/efl/interfaces/meson.build @@ -44,7 +44,6 @@ pub_eo_files = [ 'efl_text_font.eo', 'efl_text_style.eo', 'efl_text_format.eo', - 'efl_text_annotate.eo', 'efl_text_markup.eo', 'efl_text_markup_util.eo', 'efl_gfx_stack.eo', diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.c b/src/lib/elementary/efl_ui_internal_text_interactive.c index 5f623f8..608f672 100644 --- a/src/lib/elementary/efl_ui_internal_text_interactive.c +++ b/src/lib/elementary/efl_ui_internal_text_interactive.c @@ -4,6 +4,7 @@ #include "elm_priv.h" #include "efl_ui_internal_text_interactive.h" +#include "efl_canvas_text_internal.h" #define MY_CLASS EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index 8542df2..411b344 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -153,7 +153,7 @@ struct _Anchor { Eo *obj; char *name; - Efl_Text_Annotate_Annotation *annotation; + Efl_Text_Attribute_Handle *annotation; Eina_List *rects; int gen; Eina_Bool item : 1; @@ -3180,13 +3180,12 @@ _efl_ui_text_efl_access_text_range_extents_get(const Eo *obj, Efl_Ui_Text_Data * } static Efl_Access_Text_Attribute* -_textblock_node_format_to_atspi_text_attr(const Eo *obj, - Efl_Text_Annotate_Annotation *annotation) +_textblock_node_format_to_atspi_text_attr(Efl_Text_Attribute_Handle *annotation) { Efl_Access_Text_Attribute *ret; const char *txt; - txt = efl_text_annotation_get(obj, annotation); + txt = efl_text_attribute_factory_attribute_get(annotation); if (!txt) return NULL; ret = calloc(1, sizeof(Efl_Access_Text_Attribute)); @@ -3202,34 +3201,35 @@ _textblock_node_format_to_atspi_text_attr(const Eo *obj, EOLIAN static Eina_Bool _efl_ui_text_efl_access_text_attribute_get(const Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value) { - Evas_Textblock_Cursor *cur1, *cur2; + Efl_Text_Cursor *cur1, *cur2; Efl_Access_Text_Attribute *attr; Eina_Iterator *annotations; - Efl_Text_Annotate_Annotation *an; + Efl_Text_Attribute_Handle *an; - cur1 = evas_object_textblock_cursor_new(obj); + Eo *mobj = (Eo *)obj; + cur1 = efl_ui_text_cursor_create(mobj); if (!cur1) return EINA_FALSE; - cur2 = evas_object_textblock_cursor_new(obj); + cur2 = efl_ui_text_cursor_create(mobj); if (!cur2) { - evas_textblock_cursor_free(cur1); + efl_del(cur1); return EINA_FALSE; } - evas_textblock_cursor_pos_set(cur1, *start_offset); - evas_textblock_cursor_pos_set(cur2, *end_offset); + efl_text_cursor_position_set(cur1, *start_offset); + efl_text_cursor_position_set(cur2, *end_offset); - annotations = efl_text_range_annotations_get(obj, cur1, cur2); + annotations = efl_text_attribute_factory_range_attributes_get(cur1, cur2); - evas_textblock_cursor_free(cur1); - evas_textblock_cursor_free(cur2); + efl_del(cur1); + efl_del(cur2); if (!annotations) return EINA_FALSE; EINA_ITERATOR_FOREACH(annotations, an) { - attr = _textblock_node_format_to_atspi_text_attr(obj, an); + attr = _textblock_node_format_to_atspi_text_attr(an); if (!attr) continue; if (!strcmp(attr->name, attr_name)) { @@ -3247,35 +3247,35 @@ _efl_ui_text_efl_access_text_attribute_get(const Eo *obj, Efl_Ui_Text_Data *_pd EOLIAN static Eina_List* _efl_ui_text_efl_access_text_text_attributes_get(const Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED, int *start_offset, int *end_offset) { - Evas_Textblock_Cursor *cur1, *cur2; + Efl_Text_Cursor *cur1, *cur2; Eina_List *ret = NULL; Efl_Access_Text_Attribute *attr; Eina_Iterator *annotations; - Efl_Text_Annotate_Annotation *an; - - cur1 = evas_object_textblock_cursor_new(obj); + Efl_Text_Attribute_Handle *an; + Eo *mobj = (Eo *)obj; + cur1 = efl_ui_text_cursor_create(mobj); if (!cur1) return NULL; - cur2 = evas_object_textblock_cursor_new(obj); + cur2 = efl_ui_text_cursor_create(mobj); if (!cur2) { - evas_textblock_cursor_free(cur1); + efl_del(cur1); return NULL; } - evas_textblock_cursor_pos_set(cur1, *start_offset); - evas_textblock_cursor_pos_set(cur2, *end_offset); + efl_text_cursor_position_set(cur1, *start_offset); + efl_text_cursor_position_set(cur2, *end_offset); - annotations = efl_text_range_annotations_get(obj, cur1, cur2); + annotations = efl_text_attribute_factory_range_attributes_get(cur1, cur2); - evas_textblock_cursor_free(cur1); - evas_textblock_cursor_free(cur2); + efl_del(cur1); + efl_del(cur2); if (!annotations) return NULL; EINA_ITERATOR_FOREACH(annotations, an) { - attr = _textblock_node_format_to_atspi_text_attr(obj, an); + attr = _textblock_node_format_to_atspi_text_attr(an); if (!attr) continue; ret = eina_list_append(ret, attr); } @@ -3291,7 +3291,7 @@ _efl_ui_text_efl_access_text_default_attributes_get(const Eo *obj, Efl_Ui_Text_D Efl_Access_Text_Attribute *attr; Efl_Text_Cursor *start, *end; Eina_Iterator *annotations; - Efl_Text_Annotate_Annotation *an; + Efl_Text_Attribute_Handle *an; /* Retrieve all annotations in the text. */ Eo *mobj = (Eo *)obj; /* XXX const */ @@ -3301,11 +3301,11 @@ _efl_ui_text_efl_access_text_default_attributes_get(const Eo *obj, Efl_Ui_Text_D efl_text_cursor_move(start, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_FIRST); efl_text_cursor_move(end, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST); - annotations = efl_text_range_annotations_get(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end)); + annotations = efl_text_attribute_factory_range_attributes_get(start, end); EINA_ITERATOR_FOREACH(annotations, an) { - attr = _textblock_node_format_to_atspi_text_attr(obj, an); + attr = _textblock_node_format_to_atspi_text_attr(an); if (!attr) continue; ret = eina_list_append(ret, attr); } @@ -3677,20 +3677,20 @@ _anchor_format_parse(const char *item) } static Anchor * -_anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Annotate_Annotation *an) +_anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Attribute_Handle *an) { Anchor *anc; Eina_List *i; const char *str; - str = efl_text_annotation_get(obj, an); + str = efl_text_attribute_factory_attribute_get(an); EINA_LIST_FOREACH(sd->anchors, i, anc) { if (anc->annotation == an) break; } - if (!anc && (efl_text_annotation_is_item(obj, an) || !strncmp(str, "a ", 2))) + if (!anc && (efl_text_attribute_factory_attribute_is_item(an) || !strncmp(str, "a ", 2))) { const char *p; @@ -3699,7 +3699,7 @@ _anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Annotate_Annotation *an) { anc->obj = obj; anc->annotation = an; - anc->item = efl_text_annotation_is_item(obj, an); + anc->item = efl_text_attribute_factory_attribute_is_item(an); p = strstr(str, "href="); if (p) { @@ -3723,7 +3723,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd) Eina_Iterator *it; Eina_Position2D off; Efl_Text_Cursor *start, *end; - Efl_Text_Annotate_Annotation *an; + Efl_Text_Attribute_Handle *an; Eina_List *i, *ii; Anchor *anc; @@ -3741,7 +3741,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd) efl_text_cursor_move(start, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_FIRST); efl_text_cursor_move(end, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST); - it = efl_text_range_annotations_get(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end)); + it = efl_text_attribute_factory_range_attributes_get(start, end); efl_del(start); efl_del(end); @@ -3783,8 +3783,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd) } rect = eina_list_data_get(anc->rects); - efl_text_item_geometry_get(sd->text_obj, - anc->annotation, &cx, &cy, &cw, &ch); + efl_text_attribute_factory_item_geometry_get(anc->annotation, &cx, &cy, &cw, &ch); efl_gfx_entity_size_set(rect->obj, EINA_SIZE2D(cw, ch)); efl_gfx_entity_position_set(rect->obj, EINA_POSITION2D(off.x + cx, off.y + cy)); @@ -3798,8 +3797,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd) size_t count; start = efl_ui_text_cursor_create(obj); end = efl_ui_text_cursor_create(obj); - efl_text_annotation_positions_get(obj, anc->annotation, - efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end)); + efl_text_attribute_factory_attribute_cursors_get(anc->annotation, start, end); range = efl_text_cursor_range_geometry_get(start, end); count = eina_list_count(eina_iterator_container_get(range)); diff --git a/src/lib/evas/Efl_Canvas.h b/src/lib/evas/Efl_Canvas.h index a82d6a3..ed30047 100644 --- a/src/lib/evas/Efl_Canvas.h +++ b/src/lib/evas/Efl_Canvas.h @@ -84,6 +84,7 @@ extern "C" { */ #include #include +#include #include #include #include diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index 7b5db77..56971d0 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -155,6 +155,7 @@ struct _Efl_Canvas_Object_Animation_Event * @{ */ #include "canvas/efl_text_cursor.eo.h" +#include "canvas/efl_text_attribute_factory.eo.h" #include "canvas/efl_canvas_text.eo.h" #include "canvas/efl_canvas_text_factory.eo.h" /** diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h index d631cdc..0fa833c 100644 --- a/src/lib/evas/Evas_Internal.h +++ b/src/lib/evas/Evas_Internal.h @@ -318,6 +318,17 @@ EWAPI extern const Efl_Event_Description _EFL_ANIMATION_PLAYER_EVENT_PRE_STARTED */ EAPI Eina_Bool evas_textblock_cursor_at_cluster_as_single_glyph(Evas_Textblock_Cursor *cur,Eina_Bool forward); + + + +/*Attribute Factory Internal function*/ +EAPI const char * efl_text_attribute_factory_attribute_get(Efl_Text_Attribute_Handle *annotation); +EAPI Eina_Iterator * efl_text_attribute_factory_range_attributes_get(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end); +EAPI void efl_text_attribute_factory_attribute_cursors_get(const Efl_Text_Attribute_Handle *handle, Efl_Text_Cursor *start, Efl_Text_Cursor *end); +EAPI void efl_text_attribute_factory_remove(Efl_Text_Attribute_Handle *annotation); +EAPI Eina_Bool efl_text_attribute_factory_attribute_is_item(Efl_Text_Attribute_Handle *annotation); +EAPI Eina_Bool efl_text_attribute_factory_item_geometry_get(const Efl_Text_Attribute_Handle *annotation, int *x, int *y, int *w, int *h); + #ifdef __cplusplus } #endif diff --git a/src/lib/evas/canvas/efl_canvas_text.eo b/src/lib/evas/canvas/efl_canvas_text.eo index 1e53fdb..10c43c7 100644 --- a/src/lib/evas/canvas/efl_canvas_text.eo +++ b/src/lib/evas/canvas/efl_canvas_text.eo @@ -3,7 +3,7 @@ import efl_text_types; class @beta Efl.Canvas.Text extends Efl.Canvas.Object implements Efl.Text, Efl.Canvas.Filter.Internal, Efl.Text_Font, Efl.Text_Style, Efl.Text_Format, - Efl.Text_Annotate, Efl.Text_Markup, Efl.Ui.I18n + Efl.Text_Markup, Efl.Ui.I18n { [[Efl canvas text class]] methods { @@ -236,15 +236,6 @@ class @beta Efl.Canvas.Text extends Efl.Canvas.Object implements Efl.Text, Efl.Text_Format.tabstops { get; set; } Efl.Text_Format.password { get; set; } Efl.Text_Format.replacement_char { get; set; } - Efl.Text_Annotate.annotation { set; get; } - Efl.Text_Annotate.range_annotations_get; - Efl.Text_Annotate.annotation_insert; - Efl.Text_Annotate.annotation_del; - Efl.Text_Annotate.annotation_is_item; - Efl.Text_Annotate.item_geometry_get; - Efl.Text_Annotate.annotation_positions_get; - Efl.Text_Annotate.cursor_item_annotation { get; } - Efl.Text_Annotate.cursor_item_insert; Efl.Text_Markup.markup { set; get; } Efl.Gfx.Entity.scale { set; } } diff --git a/src/lib/evas/canvas/efl_canvas_text_internal.h b/src/lib/evas/canvas/efl_canvas_text_internal.h index 64659ec..9871008 100644 --- a/src/lib/evas/canvas/efl_canvas_text_internal.h +++ b/src/lib/evas/canvas/efl_canvas_text_internal.h @@ -83,10 +83,10 @@ typedef struct _Evas_Object_Textblock_Format Evas_Object_Textblock_Format; typedef struct _Evas_Textblock_Selection_Iterator Evas_Textblock_Selection_Iterator; /** * @internal - * @typedef Efl_Text_Annotate_Annotation_Iterator + * @typedef Efl_Text_Attribute_Handle_Iterator * A textblock annotation iterator. */ -typedef struct _Efl_Text_Annotate_Annotation_Iterator Efl_Text_Annotate_Annotation_Iterator; +typedef struct _Efl_Text_Attribute_Handle_Iterator Efl_Text_Attribute_Handle_Iterator; /** * @internal * @typedef Efl_Canvas_Text_Filter @@ -143,7 +143,7 @@ struct _Evas_Textblock_Node_Format const char *format; /**< Cached, parsed and translated version of orig_format. */ const char *orig_format; /**< Original format information. */ Evas_Object_Textblock_Node_Text *text_node; /**< The text node it's pointing to. */ - Efl_Text_Annotate_Annotation *annotation; /**< Pointer to this node's annotation handle (if exists). */ + Efl_Text_Attribute_Handle *annotation; /**< Pointer to this node's annotation handle (if exists). */ size_t offset; /**< Offset from the last format node of the same text. */ struct { unsigned char l, r, t, b; @@ -166,8 +166,17 @@ struct _Efl_Text_Cursor_Handle Eina_Bool changed : 1; }; +struct _Efl_Text_Attribute_Handle +{ + EINA_INLIST; + Evas_Object *obj; + Evas_Object_Textblock_Node_Format *start_node, *end_node; + Eina_Bool is_item : 1; /**< indicates it is an item/object placeholder */ +}; + void evas_textblock_cursor_line_jump_by(Efl_Text_Cursor_Handle *cur, int by); int _cursor_text_append(Efl_Text_Cursor_Handle *cur, const char *text); +void evas_textblock_async_block(Evas_Object *eo_object); // Used in Efl.Text.Cursor, where multible objects can have same handle. @@ -177,6 +186,76 @@ evas_textblock_cursor_ref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj); // Used in Efl.Text.Cursor, where multible objects can have same handle. void evas_textblock_cursor_unref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj); +void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb); + +/*Annoation Functions*/ +/** + * @internal + * Returns the value of the current data of list node, + * and goes to the next list node. + * + * @param it the iterator. + * @param data the data of the current list node. + * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE. + */ +Eina_Bool +_evas_textblock_annotation_iterator_next(Efl_Text_Attribute_Handle_Iterator *it, void **data); + +/** + * @internal + * Frees the annotation iterator. + * @param it the iterator to free + * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE. + */ +void +_evas_textblock_annotation_iterator_free(Efl_Text_Attribute_Handle_Iterator *it); + + +/** + * @internal + * Creates newly allocated iterator associated to a list. + * @param list The list. + * @return If the memory cannot be allocated, NULL is returned. + * Otherwise, a valid iterator is returned. + */ +Eina_Iterator * +_evas_textblock_annotation_iterator_new(Eina_List *list); + + + +void +_textblock_cursor_pos_at_fnode_set(Efl_Text_Cursor_Handle *cur, + Evas_Object_Textblock_Node_Format *fnode); + + +Eina_Bool +_evas_textblock_annotations_set(Evas_Object *eo_obj, + Efl_Text_Attribute_Handle *an, + Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, + const char *format, Eina_Bool is_item); + +void +_evas_textblock_annotation_remove(Evas_Object *eo_obj, Efl_Canvas_Text_Data *o, + Efl_Text_Attribute_Handle *an, Eina_Bool remove_nodes, Eina_Bool invalidate); + +void +_evas_textblock_annotations_clear(const Evas_Object *eo_obj); + + +Efl_Text_Attribute_Handle * +_evas_textblock_annotations_insert(Eo *eo_obj, + Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, + const char *format, Eina_Bool is_item); + + +Eina_Inlist * +_evas_textblock_annotations_get(Evas_Object *o); + +void +_evas_textblock_annotations_node_format_remove(Evas_Object *o, Evas_Object_Textblock_Node_Format *n, int visual_adjustment); + +void +_evas_textblock_relayout_if_needed(Evas_Object *o); #ifdef EAPI # undef EAPI @@ -213,7 +292,24 @@ evas_textblock_cursor_unref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj); */ EAPI void efl_text_cursor_text_object_set(Eo *cursor, Eo *canvas_text_obj, Eo *text_obj); + +/** + * Internally sets cursor handle(legacy textblock cursor) into cursor object. + * + * @param obj the cursor object. + * @param handle the text cursor handle. + */ +EAPI void efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Handle *handle); + +/** + * Internally gets cursor handle(legacy textblock cursor) from cursor object. + * + * @param obj the cursor object. + * @return the internal text cursor handle. + */ +EAPI Efl_Text_Cursor_Handle *efl_text_cursor_handle_get(const Eo *obj); + #undef EAPI #define EAPI -#endif \ No newline at end of file +#endif//#ifndef _EFL_CANVAS_TEXT_INTERNAL_H diff --git a/src/lib/evas/canvas/efl_text_attribute_factory.c b/src/lib/evas/canvas/efl_text_attribute_factory.c new file mode 100644 index 0000000..2e01ee8 --- /dev/null +++ b/src/lib/evas/canvas/efl_text_attribute_factory.c @@ -0,0 +1,133 @@ +//#define EFL_BETA_API_SUPPORT +#include "evas_common_private.h" +#include "evas_private.h" +#include "efl_canvas_text_internal.h" +#include "efl_text_cursor.eo.h" + +#define MY_CLASS EFL_TEXT_ATTRIBUTE_FACTORY_CLASS + +typedef struct +{ + +} Efl_Text_Attribute_Factory_Data; + +EOLIAN static void +_efl_text_attribute_factory_attribute_insert(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end, const char *format) +{ + EINA_SAFETY_ON_TRUE_RETURN(!efl_text_cursor_handle_get(start) || + !efl_text_cursor_handle_get(end) || + efl_text_cursor_handle_get(start)->obj != efl_text_cursor_handle_get(end)->obj); + + Eo *eo_obj= efl_text_cursor_handle_get(start)->obj; + evas_textblock_async_block(eo_obj); + + _evas_textblock_annotations_insert(eo_obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end), format, + EINA_FALSE); + efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL); +} + +EOLIAN static unsigned int +_efl_text_attribute_factory_attribute_clear(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end) +{ + unsigned int ret = 0; + Eina_Iterator *annotations; + Efl_Text_Attribute_Handle *an; + annotations = efl_text_attribute_factory_range_attributes_get(start, end); + + if (!annotations) return ret; + + EINA_ITERATOR_FOREACH(annotations, an) + { + ret++; + efl_text_attribute_factory_remove(an); + } + eina_iterator_free(annotations); + + return ret; +} + +const char * +efl_text_attribute_factory_attribute_get(Efl_Text_Attribute_Handle *annotation) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), NULL); + + return (annotation->start_node ? annotation->start_node->format : NULL); +} + +Eina_Iterator * +efl_text_attribute_factory_range_attributes_get(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end) +{ + Eina_List *lst = NULL; + Efl_Text_Attribute_Handle *it; + + EINA_SAFETY_ON_TRUE_RETURN_VAL(!efl_text_cursor_handle_get(start) || + !efl_text_cursor_handle_get(end) || + efl_text_cursor_handle_get(start)->obj != efl_text_cursor_handle_get(end)->obj, NULL); + + Eina_Inlist *annotations = _evas_textblock_annotations_get(efl_text_cursor_handle_get(start)->obj); + + EINA_INLIST_FOREACH(annotations, it) + { + Efl_Text_Cursor_Handle start2, end2; + _evas_textblock_cursor_init(&start2, efl_text_cursor_handle_get(start)->obj); + _evas_textblock_cursor_init(&end2, efl_text_cursor_handle_get(start)->obj); + + if (!it->start_node || !it->end_node) continue; + _textblock_cursor_pos_at_fnode_set(&start2, it->start_node); + _textblock_cursor_pos_at_fnode_set(&end2, it->end_node); + evas_textblock_cursor_char_prev(&end2); + if (!((evas_textblock_cursor_compare(&start2, efl_text_cursor_handle_get(end)) > 0) || + (evas_textblock_cursor_compare(&end2, efl_text_cursor_handle_get(start)) < 0))) + { + lst = eina_list_append(lst, it); + } + } + return _evas_textblock_annotation_iterator_new(lst); +} + +void +efl_text_attribute_factory_attribute_cursors_get(const Efl_Text_Attribute_Handle *handle, Efl_Text_Cursor *start, Efl_Text_Cursor *end) +{ + EINA_SAFETY_ON_TRUE_RETURN (!handle || !(handle->obj)); + + efl_text_cursor_text_object_set(start, handle->obj, handle->obj); + efl_text_cursor_text_object_set(end, handle->obj, handle->obj); + _textblock_cursor_pos_at_fnode_set(efl_text_cursor_handle_get(start), handle->start_node); + _textblock_cursor_pos_at_fnode_set(efl_text_cursor_handle_get(end), handle->end_node); +} + +void +efl_text_attribute_factory_remove(Efl_Text_Attribute_Handle *annotation) +{ + EINA_SAFETY_ON_TRUE_RETURN (!annotation || !(annotation->obj)); + + evas_textblock_async_block(annotation->obj); + _evas_textblock_annotation_remove(annotation->obj, NULL, annotation, EINA_TRUE, EINA_TRUE); +} + +Eina_Bool +efl_text_attribute_factory_attribute_is_item(Efl_Text_Attribute_Handle *annotation) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), EINA_FALSE); + + return annotation->is_item; +} + +Eina_Bool +efl_text_attribute_factory_item_geometry_get(const Efl_Text_Attribute_Handle *annotation, int *x, int *y, int *w, int *h) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), EINA_FALSE); + + Efl_Text_Cursor_Handle cur; + + Eo *eo_obj = annotation->obj; + Evas_Object_Protected_Data *obj_data = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + evas_object_async_block(obj_data); + _evas_textblock_relayout_if_needed(eo_obj); + + _evas_textblock_cursor_init(&cur, eo_obj); + _textblock_cursor_pos_at_fnode_set(&cur, annotation->start_node); + return evas_textblock_cursor_format_item_geometry_get(&cur, x, y, w, h); +} + +#include "efl_text_attribute_factory.eo.c" diff --git a/src/lib/evas/canvas/efl_text_attribute_factory.eo b/src/lib/evas/canvas/efl_text_attribute_factory.eo new file mode 100644 index 0000000..52bc871 --- /dev/null +++ b/src/lib/evas/canvas/efl_text_attribute_factory.eo @@ -0,0 +1,37 @@ +import efl_text_types; + +abstract @beta Efl.Text.Attribute.Factory extends Efl.Object { + [[Attribute factory API to manage text attributes. + Use it to insert and remove style attributes (font, size, color, ...) using @Efl.Text.Cursor on EFL Widgets. + + Attributes can be assigned to character ranges, selected using two @Efl.Text.Cursor instances. + Cursor instances are already bound to a text object so there's no need to provide it to this class. + Style is specified using format strings as described in Efl.Canvas.Text.style_set. + + There is no need to instantiate this class. Use directly the @.attribute_insert and @.attribute_clear static methods.]] + methods { + attribute_insert @static { + [[Inserts an attribute format in a specified range [$start, $end - 1]. + + The $format will be applied to the given range. + The passed cursors must belong to same textObject, else insertion will be ignored. + Passed format parameter uses same format as style in Efl.Canvas.Text.style_set. + ]] + params { + start: const(Efl.Text.Cursor); [[Start of range.]] + end: const(Efl.Text.Cursor); [[End of range.]] + format: string; [[Attribute format.]] + } + } + + attribute_clear @static { + [[Clear(remove) attributes at specified range [$start, $end - 1]. + ]] + params { + start: const(Efl.Text.Cursor); [[Start of range.]] + end: const(Efl.Text.Cursor); [[End of range.]] + } + return: uint; [[Number of removed attributes.]] + } + } +} diff --git a/src/lib/evas/canvas/efl_text_cursor.c b/src/lib/evas/canvas/efl_text_cursor.c index cfa87d7..238c952 100644 --- a/src/lib/evas/canvas/efl_text_cursor.c +++ b/src/lib/evas/canvas/efl_text_cursor.c @@ -406,9 +406,10 @@ _efl_text_cursor_range_delete(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Data *pd, Efl evas_textblock_cursor_range_delete(pd->handle, efl_text_cursor_handle_get(cur2)); } -EOLIAN static void -_efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Data *pd, Efl_Text_Cursor_Handle *handle) +EAPI void +efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Handle *handle) { + Efl_Text_Cursor_Data *pd = efl_data_scope_get(obj, MY_CLASS); if (handle == pd->handle) return; @@ -422,9 +423,10 @@ _efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Data *pd, Efl_Text_Cursor_H } } -EOLIAN static Efl_Text_Cursor_Handle * -_efl_text_cursor_handle_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Data *pd) +EAPI Efl_Text_Cursor_Handle * +efl_text_cursor_handle_get(const Eo *obj) { + Efl_Text_Cursor_Data *pd = efl_data_scope_get(obj, MY_CLASS); return pd->handle; } diff --git a/src/lib/evas/canvas/efl_text_cursor.eo b/src/lib/evas/canvas/efl_text_cursor.eo index 0485eb9..01c77fc 100644 --- a/src/lib/evas/canvas/efl_text_cursor.eo +++ b/src/lib/evas/canvas/efl_text_cursor.eo @@ -215,19 +215,6 @@ class @beta Efl.Text.Cursor extends Efl.Object implements Efl.Duplicate{ } } - @property handle { - [[This method should rarely be used by users. It gives you a lightweight handle to a cursor. - - You can either replace the handle to change the object this is working on, or get it for caching - - The handle is freed when the object is freed if set, but otherwise it remains under the control of the caller.]] - set { } - get { } - values { - handle: Efl.Text_Cursor_Handle @by_ref; [[The handle of the cursor object.]] - } - } - @property text_object { [[The text object this cursor is associated with.]] get { } diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index b4dc3b8..0cebc18 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -445,13 +445,6 @@ typedef struct _User_Style_Entry Evas_Textblock_Style *st; const char *key; } User_Style_Entry; -struct _Efl_Text_Annotate_Annotation -{ - EINA_INLIST; - Evas_Object *obj; - Evas_Object_Textblock_Node_Format *start_node, *end_node; - Eina_Bool is_item : 1; /**< indicates it is an item/object placeholder */ -}; #define _FMT(x) (o->default_format.format.x) #define _FMT_INFO(x) (o->default_format.info.x) @@ -487,7 +480,7 @@ struct _Evas_Object_Textblock Eina_List *anchors_item; Eina_List *obstacles; Eina_List *hyphen_items; /* Hyphen items storage to free when clearing lines */ - Efl_Text_Annotate_Annotation *annotations; /* All currently applied annotations on the text. */ + Efl_Text_Attribute_Handle *annotations; /* All currently applied annotations on the text. */ int last_w, last_h; struct { int l, r, t, b; @@ -564,7 +557,7 @@ struct _Evas_Textblock_Selection_Iterator Eina_List *current; /**< Current node in loop. */ }; -struct _Efl_Text_Annotate_Annotation_Iterator +struct _Efl_Text_Attribute_Handle_Iterator { Eina_Iterator iterator; /**< Eina Iterator. */ Eina_List *list; /**< Head of list. */ @@ -663,12 +656,9 @@ static void _evas_textblock_changed(Efl_Canvas_Text_Data *o, Evas_Object *eo_obj static void _evas_textblock_invalidate_all(Efl_Canvas_Text_Data *o); static void _evas_textblock_cursors_update_offset(const Efl_Text_Cursor_Handle *cur, const Evas_Object_Textblock_Node_Text *n, size_t start, int offset); static void _evas_textblock_cursors_set_node(Efl_Canvas_Text_Data *o, const Evas_Object_Textblock_Node_Text *n, Evas_Object_Textblock_Node_Text *new_node); -static void _evas_textblock_annotations_clear(Efl_Canvas_Text_Data *o); -static void _evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *an, Eina_Bool remove_nodes); static Eina_Bool _evas_textblock_cursor_format_is_visible_get(const Efl_Text_Cursor_Handle *cur); static void _evas_textblock_cursor_at_format_set(Efl_Text_Cursor_Handle *cur, const Evas_Object_Textblock_Node_Format *fmt); -static void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb); static Evas_Filter_Program *_format_filter_program_get(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Format *fmt); static const char *_textblock_format_node_from_style_tag(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Node_Format *fnode, const char *format, size_t format_len); #ifdef HAVE_HYPHEN @@ -678,7 +668,6 @@ static const char *_textblock_format_node_from_style_tag(Efl_Canvas_Text_Data *o static Eina_Bool _evas_textblock_cursor_format_append(Efl_Text_Cursor_Handle *cur, const char *format, Evas_Object_Textblock_Node_Format **_fnode, Eina_Bool is_item); EAPI Eina_Bool evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur); -static void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb); static Eina_Bool _evas_textblock_cursor_format_is_visible_get(const Efl_Text_Cursor_Handle *cur); static void _find_layout_item_line_match(Evas_Object *eo_obj, Evas_Object_Textblock_Node_Text *n, size_t pos, Evas_Object_Textblock_Line **lnr, Evas_Object_Textblock_Item **itr); static Evas_Object_Textblock_Node_Format *_evas_textblock_cursor_node_format_at_pos_get(const Efl_Text_Cursor_Handle *cur); @@ -862,7 +851,7 @@ _nodes_clear(const Evas_Object *eo_obj) Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); /* First, clear all annotations that may have spawned format nodes. */ - _evas_textblock_annotations_clear(o); + _evas_textblock_annotations_clear(eo_obj); while (o->text_nodes) { @@ -7222,6 +7211,13 @@ _relayout_if_needed(const Evas_Object *eo_obj, Efl_Canvas_Text_Data *o) return EINA_TRUE; } +void +_evas_textblock_relayout_if_needed(Evas_Object *eo_obj) +{ + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + _relayout_if_needed(eo_obj, o); +} + /** * @internal * Find the layout item and line that match the text node and position passed. @@ -9248,7 +9244,7 @@ _find_layout_item_match(const Efl_Text_Cursor_Handle *cur, Evas_Object_Textblock return previous_format; } -static void +void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb) { memset(cur, 0, sizeof(Efl_Text_Cursor_Handle)); @@ -10392,7 +10388,7 @@ _evas_textblock_node_format_remove_matching(Efl_Canvas_Text_Data *o, if (_FORMAT_IS_CLOSER_OF( fnode->orig_format, fstr + 1, fstr_len - 1)) { - Efl_Text_Annotate_Annotation *an = fmt->annotation; + Efl_Text_Attribute_Handle *an = fmt->annotation; fnode = eina_list_data_get(i); formats = eina_list_remove_list(formats, i); @@ -10402,7 +10398,7 @@ _evas_textblock_node_format_remove_matching(Efl_Canvas_Text_Data *o, if (an) { _evas_textblock_annotation_remove( - o, an, EINA_FALSE); + NULL, o, an, EINA_FALSE, EINA_FALSE); } break; } @@ -10500,6 +10496,13 @@ _evas_textblock_node_format_remove(Efl_Canvas_Text_Data *o, Evas_Object_Textbloc _evas_textblock_node_format_free(o, n); } +void +_evas_textblock_annotations_node_format_remove(Evas_Object *eo_obj, Evas_Object_Textblock_Node_Format *n, int visual_adjustment) +{ + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + _evas_textblock_node_format_remove(o, n, visual_adjustment); +} + /** * @internal * Sets all the offsets of the format nodes between start and end in the text @@ -15945,6 +15948,12 @@ _efl_canvas_text_efl_text_text_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o) return o->utf8; } +void evas_textblock_async_block(Evas_Object *eo_obj) +{ + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + ASYNC_BLOCK; +} + /** * @internal * Returns the value of the current data of list node, @@ -15954,8 +15963,8 @@ _efl_canvas_text_efl_text_text_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o) * @param data the data of the current list node. * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE. */ -static Eina_Bool -_evas_textblock_annotation_iterator_next(Efl_Text_Annotate_Annotation_Iterator *it, void **data) +Eina_Bool +_evas_textblock_annotation_iterator_next(Efl_Text_Attribute_Handle_Iterator *it, void **data) { if (!it->current) return EINA_FALSE; @@ -15972,8 +15981,8 @@ _evas_textblock_annotation_iterator_next(Efl_Text_Annotate_Annotation_Iterator * * @param it the iterator to free * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE. */ -static void -_evas_textblock_annotation_iterator_free(Efl_Text_Annotate_Annotation_Iterator *it) +void +_evas_textblock_annotation_iterator_free(Efl_Text_Attribute_Handle_Iterator *it) { EINA_MAGIC_SET(&it->iterator, 0); it->current = NULL; @@ -15993,7 +16002,7 @@ _evas_textblock_annotation_iterator_new(Eina_List *list) { Evas_Textblock_Selection_Iterator *it; - it = calloc(1, sizeof(Efl_Text_Annotate_Annotation_Iterator)); + it = calloc(1, sizeof(Efl_Text_Attribute_Handle_Iterator)); if (!it) return NULL; EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); @@ -16009,24 +16018,24 @@ _evas_textblock_annotation_iterator_new(Eina_List *list) return &it->iterator; } -static void -_textblock_cursor_pos_at_fnode_set(const Eo *eo_obj EINA_UNUSED, - Efl_Text_Cursor_Handle *cur, +void +_textblock_cursor_pos_at_fnode_set(Efl_Text_Cursor_Handle *cur, Evas_Object_Textblock_Node_Format *fnode) { cur->node = fnode->text_node; cur->pos = _evas_textblock_node_format_pos_get(fnode); } -static Eina_Bool -_textblock_annotation_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o, - Efl_Text_Annotate_Annotation *an, +Eina_Bool +_evas_textblock_annotations_set(Eo *eo_obj, + Efl_Text_Attribute_Handle *an, Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, const char *format, Eina_Bool is_item) { int len; char *buf; Evas_Textblock_Node_Format *fnode; + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); if (an->is_item) { @@ -16058,60 +16067,20 @@ _textblock_annotation_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o, return EINA_TRUE; } -EOLIAN static const char * -_efl_canvas_text_efl_text_annotate_annotation_get(const Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, - Efl_Text_Annotate_Annotation *annotation) +Eina_Inlist * +_evas_textblock_annotations_get(Eo *eo_obj) { - if (!annotation || (annotation->obj != eo_obj)) - { - ERR("Used invalid handle or of a different object"); - return NULL; - } - - return (annotation->start_node ? annotation->start_node->format : NULL); + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + return (Eina_Inlist*)o->annotations; } -EOLIAN static Eina_Bool -_efl_canvas_text_efl_text_annotate_annotation_set(Eo *eo_obj, - Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation, - const char *format) +void +_evas_textblock_annotation_remove(Eo *eo_obj, Efl_Canvas_Text_Data *o, + Efl_Text_Attribute_Handle *an, Eina_Bool remove_nodes, Eina_Bool invalidate) { - ASYNC_BLOCK; - Efl_Text_Cursor_Handle start, end; - Eina_Bool ret = EINA_TRUE; - - if (!annotation || (annotation->obj != eo_obj)) - { - ERR("Used invalid handle or of a different object"); - return EINA_FALSE; - } - - if (!annotation->start_node || !annotation->end_node) return EINA_FALSE; - if (!format || (format[0] == '\0')) return EINA_FALSE; - - _evas_textblock_cursor_init(&start, eo_obj); - _evas_textblock_cursor_init(&end, eo_obj); - - /* XXX: Not efficient but works and saves code */ - _textblock_cursor_pos_at_fnode_set(eo_obj, &start, annotation->start_node); - _textblock_cursor_pos_at_fnode_set(eo_obj, &end, annotation->end_node); - - _evas_textblock_node_format_remove(o, annotation->start_node, 0); - _evas_textblock_node_format_remove(o, annotation->end_node, 0); - - if (!_textblock_annotation_set(eo_obj, o, annotation, &start, &end, format, - EINA_FALSE)) - { - ret = EINA_FALSE; - } - - return ret; -} + if (!o) + o = efl_data_scope_get(eo_obj, MY_CLASS); -static void -_evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o, - Efl_Text_Annotate_Annotation *an, Eina_Bool remove_nodes) -{ if (remove_nodes) { if (an->is_item) @@ -16119,64 +16088,53 @@ _evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o, /* Remove the OBJ character along with the cursor. */ Efl_Text_Cursor_Handle cur; _evas_textblock_cursor_init(&cur, an->obj); - _textblock_cursor_pos_at_fnode_set(an->obj, &cur, an->start_node); + _textblock_cursor_pos_at_fnode_set(&cur, an->start_node); evas_textblock_cursor_char_delete(&cur); return; // 'an' should be deleted after char deletion. } _evas_textblock_node_format_remove(o, an->start_node, 0); _evas_textblock_node_format_remove(o, an->end_node, 0); } - o->annotations = (Efl_Text_Annotate_Annotation *) + o->annotations = (Efl_Text_Attribute_Handle *) eina_inlist_remove(EINA_INLIST_GET(o->annotations), EINA_INLIST_GET(an)); free(an); -} + if (invalidate) + { + o->format_changed = EINA_TRUE; -static void -_evas_textblock_annotations_clear(Efl_Canvas_Text_Data *o) -{ - Efl_Text_Annotate_Annotation *an; + //XXX: It's a workaround. The underlying problem is that only new format + // nodes are checks when their respective text nodes are invalidated (see + // _format_changes_invalidate_text_nodes). Complete removal of the format + // nodes was not handled properly (as formats could only be removed via + // text changes e.g. deleting characters). + _evas_textblock_invalidate_all(o); - EINA_INLIST_FREE(o->annotations, an) - { - _evas_textblock_annotation_remove(o, an, EINA_TRUE); + _evas_textblock_changed(o, eo_obj); } } -EOLIAN static Eina_Bool -_efl_canvas_text_efl_text_annotate_annotation_del(Eo *eo_obj EINA_UNUSED, - Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation) +void +_evas_textblock_annotations_clear(const Eo *eo_obj) { - ASYNC_BLOCK; - if (!annotation || (annotation->obj != eo_obj)) + Efl_Text_Attribute_Handle *an; + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); + + EINA_INLIST_FREE(o->annotations, an) { - ERR("Used invalid handle or of a different object"); - return EINA_FALSE; + _evas_textblock_annotation_remove(NULL, o, an, EINA_TRUE, EINA_FALSE); } - - _evas_textblock_annotation_remove(o, annotation, EINA_TRUE); - o->format_changed = EINA_TRUE; - - //XXX: It's a workaround. The underlying problem is that only new format - // nodes are checks when their respective text nodes are invalidated (see - // _format_changes_invalidate_text_nodes). Complete removal of the format - // nodes was not handled properly (as formats could only be removed via - // text changes e.g. deleting characters). - _evas_textblock_invalidate_all(o); - - _evas_textblock_changed(o, eo_obj); - return EINA_TRUE; } -static Efl_Text_Annotate_Annotation * -_textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o, - Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, +Efl_Text_Attribute_Handle * +_evas_textblock_annotations_insert(Eo *eo_obj, Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, const char *format, Eina_Bool is_item) { - Efl_Text_Annotate_Annotation *ret = NULL; + Efl_Text_Attribute_Handle *ret = NULL; Eina_Strbuf *buf; Eina_Bool first = EINA_TRUE; const char *item; + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); if (!format || (format[0] == '\0') || evas_textblock_cursor_compare(start, end) > 0) @@ -16215,15 +16173,15 @@ _textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o, format = eina_strbuf_string_get(buf); if (format && (format[0] != '\0')) { - ret = calloc(1, sizeof(Efl_Text_Annotate_Annotation)); + ret = calloc(1, sizeof(Efl_Text_Attribute_Handle)); ret->obj = eo_obj; - o->annotations = (Efl_Text_Annotate_Annotation *) + o->annotations = (Efl_Text_Attribute_Handle *) eina_inlist_append(EINA_INLIST_GET(o->annotations), EINA_INLIST_GET(ret)); - _textblock_annotation_set(eo_obj, o, ret, start, end, format, is_item); + _evas_textblock_annotations_set(eo_obj, ret, start, end, format, is_item); ret->is_item = is_item; _evas_textblock_changed(o, eo_obj); } @@ -16233,123 +16191,6 @@ _textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o, return ret; } -EOLIAN static Efl_Text_Annotate_Annotation * -_efl_canvas_text_efl_text_annotate_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o, - Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end, - const char *format) -{ - ASYNC_BLOCK; - Efl_Text_Annotate_Annotation *ret; - - ret = _textblock_annotation_insert(eo_obj, o, start, end, format, - EINA_FALSE); - efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL); - return ret; -} - -EOLIAN static Eina_Iterator * -_efl_canvas_text_efl_text_annotate_range_annotations_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, - const Evas_Textblock_Cursor *start, const Evas_Textblock_Cursor *end) -{ - Eina_List *lst = NULL; - Efl_Text_Annotate_Annotation *it; - - EINA_INLIST_FOREACH(o->annotations, it) - { - Efl_Text_Cursor_Handle start2, end2; - _evas_textblock_cursor_init(&start2, eo_obj); - _evas_textblock_cursor_init(&end2, eo_obj); - - if (!it->start_node || !it->end_node) continue; - _textblock_cursor_pos_at_fnode_set(eo_obj, &start2, it->start_node); - _textblock_cursor_pos_at_fnode_set(eo_obj, &end2, it->end_node); - evas_textblock_cursor_char_prev(&end2); - if (!((evas_textblock_cursor_compare(&start2, end) > 0) || - (evas_textblock_cursor_compare(&end2, start) < 0))) - { - lst = eina_list_append(lst, it); - } - } - return _evas_textblock_annotation_iterator_new(lst); -} - -EOLIAN static Efl_Text_Annotate_Annotation * -_efl_canvas_text_efl_text_annotate_cursor_item_insert(Eo *eo_obj, - Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Handle *cur, - const char *item, const char *format) -{ - Eina_Strbuf *buf = eina_strbuf_new(); - - eina_strbuf_append_printf(buf, "%s href=%s", format, item); - - Efl_Text_Annotate_Annotation *ret = - _textblock_annotation_insert(cur->obj, o, cur, cur, - eina_strbuf_string_get(buf), EINA_TRUE); - eina_strbuf_free(buf); - efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL); - return ret; -} - -EOLIAN static Efl_Text_Annotate_Annotation * -_efl_canvas_text_efl_text_annotate_cursor_item_annotation_get(const Eo *eo_obj EINA_UNUSED, - Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Handle *cur) -{ - Eina_Iterator *it; - Efl_Text_Annotate_Annotation *data, *ret = NULL; - - it = efl_text_range_annotations_get(cur->obj, - cur, cur); - EINA_ITERATOR_FOREACH(it, data) - { - if (data->is_item) - { - ret = data; - break; - } - } - eina_iterator_free(it); - return ret; -} - -EOLIAN static Eina_Bool -_efl_canvas_text_efl_text_annotate_annotation_is_item(Eo *eo_obj EINA_UNUSED, - Efl_Canvas_Text_Data *o EINA_UNUSED, - Efl_Text_Annotate_Annotation *annotation) -{ - if (!annotation || (annotation->obj != eo_obj)) - { - ERR("Used invalid handle or of a different object"); - return EINA_FALSE; - } - - return annotation->is_item; -} - -EOLIAN static Eina_Bool -_efl_canvas_text_efl_text_annotate_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, - const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) -{ - Efl_Text_Cursor_Handle cur; - - Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); - evas_object_async_block(obj); - _relayout_if_needed(eo_obj, o); - - _evas_textblock_cursor_init(&cur, eo_obj); - _textblock_cursor_pos_at_fnode_set(eo_obj, &cur, an->start_node); - return _evas_textblock_cursor_format_item_geometry_get(&cur, cx, cy, cw, ch); -} - -EOLIAN static void -_efl_canvas_text_efl_text_annotate_annotation_positions_get(Eo *eo_obj, - Efl_Canvas_Text_Data *o EINA_UNUSED, - const Efl_Text_Annotate_Annotation *annotation, - Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end) -{ - _textblock_cursor_pos_at_fnode_set(eo_obj, start, annotation->start_node); - _textblock_cursor_pos_at_fnode_set(eo_obj, end, annotation->end_node); -} - static void _canvas_text_format_changed(Eo *eo_obj, Efl_Canvas_Text_Data *o) { diff --git a/src/lib/evas/canvas/meson.build b/src/lib/evas/canvas/meson.build index d9e6798..07dd725 100644 --- a/src/lib/evas/canvas/meson.build +++ b/src/lib/evas/canvas/meson.build @@ -56,6 +56,7 @@ pub_eo_files = [ 'efl_canvas_event_grabber.eo', 'efl_text_cursor.eo', 'efl_canvas_text.eo', + 'efl_text_attribute_factory.eo', 'efl_canvas_object_animation.eo', ] @@ -208,7 +209,8 @@ evas_src += files([ 'evas_canvas3d_node_callback.h', 'evas_canvas3d_eet.c', 'efl_canvas_object_animation.c', - 'efl_text_cursor.c' + 'efl_text_cursor.c', + 'efl_text_attribute_factory.c' ]) evas_include_directories += include_directories('.') diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index 860c674..163d403 100644 --- a/src/tests/evas/evas_test_textblock.c +++ b/src/tests/evas/evas_test_textblock.c @@ -37,6 +37,7 @@ static const char *style_buf = Evas_Object *tb; \ Evas_Textblock_Style *st; \ Evas_Textblock_Cursor *cur; \ + Efl_Text_Cursor *cur_obj; \ evas = EVAS_TEST_INIT_EVAS(); \ evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \ tb = evas_object_textblock_add(evas); \ @@ -48,6 +49,9 @@ static const char *style_buf = fail_if(strcmp(style_buf, evas_textblock_style_get(st))); \ evas_object_textblock_style_set(tb, st); \ cur = evas_object_textblock_cursor_new(tb); \ + cur_obj =efl_canvas_text_cursor_create(tb);\ + (void) cur_obj;\ + (void) cur;\ do \ { \ } \ @@ -58,6 +62,7 @@ do \ { \ evas_textblock_cursor_free(cur); \ evas_object_del(tb); \ + efl_del(cur_obj); \ evas_textblock_style_free(st); \ evas_free(evas); \ } \ @@ -4304,43 +4309,6 @@ EFL_START_TEST(evas_textblock_text_iface) } EFL_END_TEST; -static void -_test_check_annotation(Evas_Object *tb, - size_t start_pos, size_t end_pos, - size_t len, const char **formats) -{ - Efl_Text_Annotate_Annotation *an; - Efl_Text_Cursor_Handle *start, *end; - - start = evas_object_textblock_cursor_new(tb); - end = evas_object_textblock_cursor_new(tb); - - evas_textblock_cursor_pos_set(start, start_pos); - evas_textblock_cursor_pos_set(end, end_pos); - - Eina_Iterator *it = - efl_text_range_annotations_get(tb, start, end); - - evas_textblock_cursor_free(start); - evas_textblock_cursor_free(end); - - size_t i = 0; - EINA_ITERATOR_FOREACH(it, an) - { - const char *fmt = efl_text_annotation_get(tb, - an); - ck_assert_msg((i < len), - "No formats to check but current annotation is: %s\n", fmt); - ck_assert_str_eq(fmt, *formats); - formats++; - i++; - } - ck_assert_msg((i == len), - "Expected next format (index %lu): %s, but reached end of annotations\n", - i, *formats); - - eina_iterator_free(it); -} #define _COMP_STR(...) ((const char *[]) { __VA_ARGS__ }) #define _CREATE_PARAMS(X) (sizeof(X) / sizeof(X[0])), (X) @@ -4349,11 +4317,10 @@ _test_check_annotation(Evas_Object *tb, EFL_START_TEST(evas_textblock_annotation) { START_TB_TEST(); - Efl_Text_Annotate_Annotation *an, *an2; - Efl_Text_Cursor_Handle *start, *end; + Efl_Text_Cursor *start, *end; - start = evas_object_textblock_cursor_new(tb); - end = evas_object_textblock_cursor_new(tb); + start = efl_canvas_text_cursor_create(tb); + end = efl_canvas_text_cursor_create(tb); const char *buf = "This text will check annotation." @@ -4365,167 +4332,21 @@ EFL_START_TEST(evas_textblock_annotation) efl_text_set(tb, buf); /* Check some trivial cases */ - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 3); - ck_assert(!efl_text_annotation_insert(tb, start, end, NULL)); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 3); - ck_assert(!efl_text_annotation_insert(tb, start, end, "")); - evas_textblock_cursor_pos_set(start, 1); - evas_textblock_cursor_pos_set(end, 0); - ck_assert(!efl_text_annotation_insert(tb, start, end, "color=#fff")); - - /* Insert and check correct positions */ - _test_check_annotation(tb, 0, 10, _COMP_PARAMS()); - - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 3); - efl_text_annotation_insert(tb, start, end, "font_weight=bold"); - _test_check_annotation(tb, 0, 2, _COMP_PARAMS("font_weight=bold")); - _test_check_annotation(tb, 0, 2, _COMP_PARAMS("font_weight=bold")); - _test_check_annotation(tb, 4, 10, _COMP_PARAMS()); - - evas_textblock_cursor_pos_set(start, 50); - evas_textblock_cursor_pos_set(end, 60); - efl_text_annotation_insert(tb, start, end, "color=#0ff"); - _test_check_annotation(tb, 0, 49, _COMP_PARAMS("font_weight=bold")); - _test_check_annotation(tb, 0, 50, _COMP_PARAMS("font_weight=bold", "color=#0ff")); - _test_check_annotation(tb, 0, 55, _COMP_PARAMS("font_weight=bold", "color=#0ff")); - _test_check_annotation(tb, 0, 59, _COMP_PARAMS("font_weight=bold", "color=#0ff")); - _test_check_annotation(tb, 40, 50, _COMP_PARAMS("color=#0ff")); - _test_check_annotation(tb, 40, 51, _COMP_PARAMS("color=#0ff")); - _test_check_annotation(tb, 40, 61, _COMP_PARAMS("color=#0ff")); - _test_check_annotation(tb, 59, 60, _COMP_PARAMS("color=#0ff")); - _test_check_annotation(tb, 60, 61, _COMP_PARAMS()); - - /* See that annotation's positions are updated as text is inserted */ - efl_text_set(tb, "hello"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 2); - an = efl_text_annotation_insert(tb, start, end, "color=#fff"); - _test_check_annotation(tb, 2, 3, _COMP_PARAMS()); - evas_textblock_cursor_pos_set(cur, 0); - evas_textblock_cursor_text_append(cur, "a"); - _test_check_annotation(tb, 2, 3, _COMP_PARAMS("color=#fff")); - _test_check_annotation(tb, 3, 4, _COMP_PARAMS()); - - /* Replace annotations's format */ - efl_text_annotation_set(tb, an, "font_size=14"); - _test_check_annotation(tb, 2, 3, _COMP_PARAMS("font_size=14")); - _test_check_annotation(tb, 3, 4, _COMP_PARAMS()); - efl_text_set(tb, "hello world"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 2); - an = efl_text_annotation_insert(tb, start, end, "color=#fff"); - evas_textblock_cursor_pos_set(start, 2); - evas_textblock_cursor_pos_set(end, 3); - an2 = efl_text_annotation_insert(tb, start, end, "font_size=14"); - _test_check_annotation(tb, 0, 1, _COMP_PARAMS("color=#fff")); - _test_check_annotation(tb, 2, 3, _COMP_PARAMS("font_size=14")); - _test_check_annotation(tb, 0, 3, _COMP_PARAMS("color=#fff", "font_size=14")); - efl_text_annotation_set(tb, an, "font_size=10"); - efl_text_annotation_set(tb, an2, "color=#000"); - _test_check_annotation(tb, 2, 3, _COMP_PARAMS("color=#000")); - _test_check_annotation(tb, 0, 1, _COMP_PARAMS("font_size=10")); - _test_check_annotation(tb, 0, 3, _COMP_PARAMS("font_size=10", "color=#000")); - - /* Delete annotations directly */ - efl_text_set(tb, "hello world"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 2); - an = efl_text_annotation_insert(tb, start, end, "color=#fff"); - evas_textblock_cursor_pos_set(start, 3); - evas_textblock_cursor_pos_set(end, 4); - an2 = efl_text_annotation_insert(tb, start, end, "font_size=14"); - efl_text_annotation_del(tb, an); - _test_check_annotation(tb, 0, 3, _COMP_PARAMS("font_size=14")); - efl_text_annotation_del(tb, an2); - _test_check_annotation(tb, 0, 3, _COMP_PARAMS()); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 1); - an = efl_text_annotation_insert(tb, start, end, "color=#fff"); - _test_check_annotation(tb, 1, 3, _COMP_PARAMS()); - _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff")); - efl_text_annotation_del(tb, an); - _test_check_annotation(tb, 0, 0, _COMP_PARAMS()); - - /* Check blocking of "item formats" */ - efl_text_set(tb, "hello world"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 1); - efl_text_annotation_insert(tb, start, end, "ps"); - _test_check_annotation(tb, 0, 1, _COMP_PARAMS()); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 1); - efl_text_annotation_insert(tb, start, end, "color=#fff"); - _test_check_annotation(tb, 0, 1, _COMP_PARAMS("color=#fff")); - evas_textblock_cursor_pos_set(start, 2); - evas_textblock_cursor_pos_set(end, 3); - efl_text_annotation_insert(tb, start, end, "br"); - evas_textblock_cursor_pos_set(start, 6); - evas_textblock_cursor_pos_set(end, 7); - efl_text_annotation_insert(tb, start, end, "item"); - _test_check_annotation(tb, 0, 8, _COMP_PARAMS("color=#fff")); - - /* Check "item" annotations */ - efl_text_set(tb, "abcd"); - evas_textblock_cursor_pos_set(cur, 4); - an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16"); - _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16 href=")); - - /* Check that format is not extended if it's an "object item" */ - evas_textblock_cursor_pos_set(cur, 5); - evas_textblock_cursor_text_prepend(cur, "a"); - _test_check_annotation(tb, 5, 7, _COMP_PARAMS()); - _test_check_annotation(tb, 0, 3, _COMP_PARAMS()); - - /* Remove annotation of "item" also removes the OBJ character */ - { - int blen, len; - evas_textblock_cursor_pos_set(cur, 5); - blen = evas_textblock_cursor_paragraph_text_length_get(cur); - efl_text_annotation_del(tb, an); - len = evas_textblock_cursor_paragraph_text_length_get(cur); - ck_assert_int_eq(len, blen - 1); - _test_check_annotation(tb, 0, 5, _COMP_PARAMS()); - } - - /* Using annotations with new text API */ - efl_text_set(tb, "hello"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 5); - efl_text_annotation_insert(tb, start, end, "color=#fff"); - _test_check_annotation(tb, 3, 3, _COMP_PARAMS("color=#fff")); - /* Old API */ - evas_textblock_cursor_pos_set(cur, 5); - evas_textblock_cursor_text_prepend(cur, "a"); - _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff")); - _test_check_annotation(tb, 5, 5, _COMP_PARAMS()); - - /* Specific case with PS */ - efl_text_set(tb, "hello\nworld"); - evas_textblock_cursor_pos_set(start, 0); - evas_textblock_cursor_pos_set(end, 5); - efl_text_annotation_insert(tb, start, end, "color=#fff"); - _test_check_annotation(tb, 4, 4, _COMP_PARAMS("color=#fff")); - evas_textblock_cursor_pos_set(cur, 4); - /* Cursor position is now: hello|\nworld */ - evas_textblock_cursor_text_prepend(cur, "a"); - _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff")); - _test_check_annotation(tb, 5, 5, _COMP_PARAMS("color=#fff")); - - /* Test getting of object item */ - evas_textblock_cursor_pos_set(cur, 4); - an = efl_text_cursor_item_annotation_get(tb, cur); - ck_assert(!an); - an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16"); - evas_textblock_cursor_pos_set(cur, 4); - an = efl_text_cursor_item_annotation_get(tb, cur); - ck_assert(an); - ck_assert_str_eq("size=16x16 href=", efl_text_annotation_get(tb, an)); + efl_text_cursor_position_set(start, 0); + efl_text_cursor_position_set(end, 3); + efl_text_attribute_factory_attribute_insert(start, end, "font_size=80"); + efl_text_cursor_position_set(start, 1); + efl_text_cursor_position_set(end, 2); + efl_text_attribute_factory_attribute_insert(start, end, "font=arial"); + efl_text_cursor_position_set(start, 2); + efl_text_cursor_position_set(end, 3); + efl_text_attribute_factory_attribute_insert(start, end, "color=#fff"); - END_TB_TEST(); + efl_text_cursor_position_set(start, 0); + efl_text_cursor_position_set(end, 3); + unsigned int count = efl_text_attribute_factory_attribute_clear(start, end); + fail_if(count != 3); } EFL_END_TEST; @@ -4543,7 +4364,7 @@ EFL_END_TEST; fail_if(!efl_canvas_text_style_get(txt, NULL) || \ strcmp(style_buf, efl_canvas_text_style_get(txt, NULL))); \ cur_obj = efl_canvas_text_cursor_create(txt);\ - cur = efl_text_cursor_handle_get(cur_obj); \ + cur = evas_object_textblock_cursor_new(txt); \ fail_if(!cur); \ do \ { \ @@ -4554,6 +4375,7 @@ while (0) do \ { \ efl_del(cur_obj); \ + evas_textblock_cursor_free(cur); \ efl_del(txt); \ evas_free(evas); \ } \