diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index a78850aa31..1d91bf5a4b 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 d56fddb78d..e06006703e 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/bin/eolian_mono/eolian/mono/alias_definition.hh b/src/bin/eolian_mono/eolian/mono/alias_definition.hh index 31d86fe10d..d7fda07cb5 100644 --- a/src/bin/eolian_mono/eolian/mono/alias_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/alias_definition.hh @@ -56,6 +56,10 @@ struct alias_definition_generator alias_type_doc = utils::replace_all(alias_type, "<", "<"); alias_type_doc = utils::replace_all(alias_type_doc, ">", ">"); + std::string alias_since; + if (!documentation_helpers::generate_since_tag_line(std::back_inserter(alias_since), alias.documentation, scope_tab, context)) + return false; + std::string const alias_name = utils::remove_all(alias.eolian_name, '_'); if (!as_generator( documentation @@ -63,7 +67,9 @@ struct alias_definition_generator << "{\n" << scope_tab << "private " << alias_type << " payload;\n\n" - << scope_tab << "/// Converts an instance of " << alias_type_doc << " to this struct.\n" + << scope_tab << "/// Converts an instance of " << alias_type_doc << " to this struct.\n" + << alias_since + << scope_tab << "/// \n" << scope_tab << "/// The value to be converted.\n" << scope_tab << "/// A struct with the given value.\n" << scope_tab << "public static implicit operator " << alias_name << "(" << alias_type << " value)\n" @@ -71,7 +77,9 @@ struct alias_definition_generator << scope_tab << scope_tab << "return new " << alias_name << "{payload=value};\n" << scope_tab << "}\n\n" - << scope_tab << "/// Converts an instance of this struct to " << alias_type_doc << ".\n" + << scope_tab << "/// Converts an instance of this struct to " << alias_type_doc << ".\n" + << alias_since + << scope_tab << "/// \n" << scope_tab << "/// The value to be converted packed in this struct.\n" << scope_tab << "/// The actual value the alias is wrapping.\n" << scope_tab << "public static implicit operator " << alias_type << "(" << alias_name << " value)\n" diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index b57dc4a6de..0a2179b167 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -649,8 +649,24 @@ struct documentation_string_generator } const documentation_string {}; -} // namespace eolian_mono +namespace documentation_helpers +{ +template +bool generate_since_tag_line(OutputIterator sink, attributes::documentation_def const& doc, Indent indentation, Context context) +{ + if (doc.since.empty()) + return true; + + return as_generator + ( + indentation << ("/// Since EFL " + doc.since + ".\n") + ).generate(sink, attributes::unused, context); +} + +} // documentation_helpers + +} // namespace eolian_mono namespace efl { namespace eolian { namespace grammar { diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh index 76bad3baa2..2c304fcd0f 100644 --- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh @@ -40,15 +40,21 @@ struct enum_definition_generator if(!name_helpers::open_namespaces(sink, enum_.namespaces, context)) return false; - if(!as_generator(documentation).generate(sink, enum_, context)) - return false; + std::string enum_name = name_helpers::typedecl_managed_name(enum_); + std::string flags_attribute; + + // CA1717 + if (utils::ends_with(enum_name, "Flags") || utils::ends_with(enum_name, "InputHints")) // Special provision while Text api is revamped + flags_attribute = "[Flags]"; if(!as_generator ( - "[Efl.Eo.BindingEntity]\n" - "public enum " << string << "\n{\n" + documentation + << flags_attribute + << "[Efl.Eo.BindingEntity]\n" + "public enum " << enum_name << "\n{\n" ) - .generate(sink, name_helpers::typedecl_managed_name(enum_), context)) + .generate(sink, enum_, context)) return false; // iterate enum fiels diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 81d5956535..653acc78fc 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -410,6 +410,10 @@ struct klass auto implementable_methods = helpers::get_all_registerable_methods(cls, context); bool root = !helpers::has_regular_ancestor(cls); auto const& indent = current_indentation(inative_cxt); + std::string klass_since; + + if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, indent, context)) + return false; std::string base_name; if(!root) @@ -421,7 +425,10 @@ struct klass if(!as_generator ( indent << lit("/// Wrapper for native methods and virtual method delegates.\n") - << indent << "/// For internal use by generated code only.\n" + << indent << "/// For internal use by generated code only.\n" + << klass_since + << indent << "/// \n" + << indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n" << indent << "internal new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" << indent << "{\n" ).generate(sink, attributes::unused, inative_cxt)) @@ -437,7 +444,9 @@ struct klass } if(!as_generator( - indent << scope_tab << "/// Gets the list of Eo operations to override.\n" + indent << scope_tab << "/// Gets the list of Eo operations to override.\n" + << klass_since + << indent << "/// \n" << indent << scope_tab << "/// The list of Eo operations to be overload.\n" << indent << scope_tab << "internal override System.Collections.Generic.List GetEoOps(System.Type type, bool includeInherited)\n" << indent << scope_tab << "{\n" @@ -485,9 +494,14 @@ struct klass ).generate(sink, attributes::unused, inative_cxt)) return false; + if (!klass_since.empty()) + klass_since = static_cast(scope_tab) + klass_since; + // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces) if(!as_generator( - indent << scope_tab << "/// Returns the Eo class for the native methods of this class.\n" + indent << scope_tab << "/// Returns the Eo class for the native methods of this class.\n" + << klass_since + << indent << scope_tab << "/// \n" << indent << scope_tab << "/// The native class pointer.\n" << indent << scope_tab << "internal override IntPtr GetEflClass()\n" << indent << scope_tab << "{\n" @@ -558,9 +572,15 @@ struct klass return !blacklist::is_function_blacklisted(ctor.function, context); }); + std::string klass_since; + if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, scope_tab, context)) + return false; + // Public (API) constructors if (!as_generator( - scope_tab << "/// Initializes a new instance of the class.\n" + scope_tab << "/// Initializes a new instance of the class.\n" + << klass_since + << scope_tab << "/// \n" << scope_tab << "/// Parent instance.\n" << *(documentation) // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters. @@ -572,13 +592,17 @@ struct klass << scope_tab << scope_tab << "FinishInstantiation();\n" << scope_tab << "}\n\n" << scope_tab << "/// Subclasses should override this constructor if they are expected to be instantiated from native code.\n" - << scope_tab << "/// Do not call this constructor directly.\n" + << scope_tab << "/// Do not call this constructor directly.\n" + << klass_since + << scope_tab << "/// \n" << scope_tab << "/// Tag struct storing the native handle of the object being constructed.\n" << scope_tab << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n" << scope_tab << "{\n" << scope_tab << "}\n\n" << scope_tab << "/// Initializes a new instance of the class.\n" - << scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n" + << scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n" + << klass_since + << scope_tab << "/// \n" << scope_tab << "/// The native pointer to be wrapped.\n" << scope_tab << "internal " << inherit_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n" << scope_tab << "{\n" @@ -605,7 +629,9 @@ struct klass return as_generator( scope_tab << "/// Initializes a new instance of the class.\n" - << scope_tab << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.\n" + << scope_tab << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.\n" + << klass_since + << scope_tab << "/// \n" << scope_tab << "/// The pointer to the base native Eo class.\n" << scope_tab << "/// The Efl.Object parent of this instance.\n" << scope_tab << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n" diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c index e07aa9f666..5713313a1b 100644 --- a/src/lib/ecore/ecore_timer.c +++ b/src/lib/ecore/ecore_timer.c @@ -15,6 +15,17 @@ #define ECORE_TIMER_CHECK(obj) if (!efl_isa((obj), MY_CLASS)) return +#define EFL_LOOP_TIMER_DATA_GET(o, td) \ + Efl_Loop_Timer_Data *td = efl_data_scope_safe_get(o, EFL_LOOP_TIMER_CLASS) + +#define EFL_LOOP_TIMER_DATA_GET_OR_RETURN(o, ptr, ...) \ + EFL_LOOP_TIMER_DATA_GET(o, ptr); \ + if (EINA_UNLIKELY(!ptr)) \ + { \ + ERR("No data for timer %p", o); \ + return __VA_ARGS__; \ + } + struct _Ecore_Timer_Legacy { Ecore_Task_Cb func; @@ -178,7 +189,6 @@ EAPI Ecore_Timer * ecore_timer_add(double in, Ecore_Task_Cb func, const void *data) { Ecore_Timer_Legacy *legacy; - Efl_Loop_Timer_Data *td; Eo *timer; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); @@ -194,7 +204,7 @@ ecore_timer_add(double in, Ecore_Task_Cb func, const void *data) timer = efl_add(MY_CLASS, efl_main_loop_get(), efl_event_callback_array_add(efl_added, legacy_timer(), legacy), efl_loop_timer_interval_set(efl_added, in)); - td = efl_data_scope_get(timer, MY_CLASS); + EFL_LOOP_TIMER_DATA_GET_OR_RETURN(timer, td, NULL); td->legacy = legacy; return timer; } @@ -203,7 +213,6 @@ EAPI Ecore_Timer * ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data) { Ecore_Timer_Legacy *legacy; - Efl_Loop_Timer_Data *td; Eo *timer; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); @@ -220,7 +229,7 @@ ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data) efl_event_callback_array_add(efl_added, legacy_timer(), legacy), efl_loop_timer_loop_reset(efl_added), efl_loop_timer_interval_set(efl_added, in)); - td = efl_data_scope_get(timer, MY_CLASS); + EFL_LOOP_TIMER_DATA_GET_OR_RETURN(timer, td, NULL); td->legacy = legacy; return timer; } @@ -228,14 +237,12 @@ ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data) EAPI void * ecore_timer_del(Ecore_Timer *timer) { - Efl_Loop_Timer_Data *td; void *data; if (!timer) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - td = efl_data_scope_safe_get(timer, MY_CLASS); + EFL_LOOP_TIMER_DATA_GET(timer, td); // If legacy == NULL, this means double free or something if ((!td) || (!td->legacy)) { diff --git a/src/lib/ecore/efl_boolean_model.eo b/src/lib/ecore/efl_boolean_model.eo index f8ee356713..fa5b1405c0 100644 --- a/src/lib/ecore/efl_boolean_model.eo +++ b/src/lib/ecore/efl_boolean_model.eo @@ -25,7 +25,7 @@ class @beta Efl.Boolean_Model extends Efl.Composite_Model @in name: string; [[The name of the property to examine.]] @in request: bool; [[The value to look for.]] } - return: iterator; [[The iterator that is valid until any change is made on the model.]] + return: iterator @move; [[The iterator that is valid until any change is made on the model.]] } } implements { diff --git a/src/lib/ecore/efl_core_command_line.eo b/src/lib/ecore/efl_core_command_line.eo index 6eec372954..24849be70d 100644 --- a/src/lib/ecore/efl_core_command_line.eo +++ b/src/lib/ecore/efl_core_command_line.eo @@ -50,7 +50,7 @@ mixin @beta Efl.Core.Command_Line requires Efl.Object { } command_access { [[ Get the accessor which enables access to each argument that got passed to this object. ]] - return : accessor; + return : accessor @move; } @property command_array { [[ Use an array to fill this object diff --git a/src/lib/ecore/efl_core_env.eo b/src/lib/ecore/efl_core_env.eo index 593a3a3cf5..c17e0a1440 100644 --- a/src/lib/ecore/efl_core_env.eo +++ b/src/lib/ecore/efl_core_env.eo @@ -47,7 +47,7 @@ class @beta Efl.Core.Env extends Efl.Object implements Efl.Duplicate { } values { - iter : iterator; + iter : iterator @move; } } } diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index c78d105c5b..a9970e21ca 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_gfx_image.eo b/src/lib/efl/interfaces/efl_gfx_image.eo index 40ee6ed76f..b9d962b9ab 100644 --- a/src/lib/efl/interfaces/efl_gfx_image.eo +++ b/src/lib/efl/interfaces/efl_gfx_image.eo @@ -217,9 +217,9 @@ interface Efl.Gfx.Image } get {} values { - horizontal: iterator(null); [[Representation of areas that are + horizontal: iterator(null) @move; [[Representation of areas that are stretchable in the image horizontal space.]] - vertical: iterator(null); [[Representation of areas that are + vertical: iterator(null) @move; [[Representation of areas that are stretchable in the image vertical space.]] } } diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c index 71162b94fe..3e94adcb5e 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 5ca1df8eb8..0000000000 --- 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 64eb39329e..159975ea8c 100644 --- a/src/lib/efl/interfaces/efl_text_types.eot +++ b/src/lib/efl/interfaces/efl_text_types.eot @@ -22,6 +22,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/efl_ui_view_factory.eo b/src/lib/efl/interfaces/efl_ui_view_factory.eo index 728c25907c..f4774300a5 100644 --- a/src/lib/efl/interfaces/efl_ui_view_factory.eo +++ b/src/lib/efl/interfaces/efl_ui_view_factory.eo @@ -10,7 +10,7 @@ class @beta Efl.Ui.View_Factory params { factory: Efl.Ui.Factory; [[The factory to use for requesting the new object from and generating the created event onto.]] - models: iterator; [[Efl iterator providing the model to be associated to the new item. It should + models: iterator @move; [[Efl iterator providing the model to be associated to the new item. It should remain valid until the end of the function call.]] } return: future; [[Created UI object]] diff --git a/src/lib/efl/interfaces/meson.build b/src/lib/efl/interfaces/meson.build index f45e743f94..a823e01b0c 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_access_action.eo b/src/lib/elementary/efl_access_action.eo index acaad80188..8f70f0efb1 100644 --- a/src/lib/elementary/efl_access_action.eo +++ b/src/lib/elementary/efl_access_action.eo @@ -47,7 +47,7 @@ mixin @beta Efl.Access.Action get @pure_virtual { } values { - actions: list; + actions: list @move; [[Contains statically allocated strings.]] } } diff --git a/src/lib/elementary/efl_access_object.eo b/src/lib/elementary/efl_access_object.eo index d7392f275e..fc16ea2194 100644 --- a/src/lib/elementary/efl_access_object.eo +++ b/src/lib/elementary/efl_access_object.eo @@ -263,7 +263,7 @@ mixin @beta Efl.Access.Object requires Efl.Object } relations_get @protected @beta @const { [[Gets an all relations between accessible object and other accessible objects.]] - return: iterator; [[Accessible relation set]] + return: iterator @move; [[Accessible relation set]] } @property role @beta { [[The role of the object in accessibility domain.]] diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo index 1b0256f663..5bb11e7036 100644 --- a/src/lib/elementary/efl_ui_focus_manager.eo +++ b/src/lib/elementary/efl_ui_focus_manager.eo @@ -92,7 +92,7 @@ interface Efl.Ui.Focus.Manager { ]] get {} values { - border_elements : iterator; [[An iterator + border_elements : iterator @move; [[An iterator over the border objects.]] } } @@ -107,7 +107,7 @@ interface Efl.Ui.Focus.Manager { viewport : Eina.Rect; [[The rectangle defining the viewport.]] } values { - viewport_elements : iterator; [[An iterator over the viewport border objects.]] + viewport_elements : iterator @move; [[An iterator over the viewport border objects.]] } } @property root { diff --git a/src/lib/elementary/efl_ui_format.eo b/src/lib/elementary/efl_ui_format.eo index a05cc0b071..3e2bd287bb 100644 --- a/src/lib/elementary/efl_ui_format.eo +++ b/src/lib/elementary/efl_ui_format.eo @@ -81,7 +81,7 @@ mixin Efl.Ui.Format requires Efl.Object performance reasons. ]] values { - values: accessor; [[Accessor over a list of value-text pairs. + values: accessor @move; [[Accessor over a list of value-text pairs. The method will dispose of the accessor, but not of its contents. For convenience, Eina offers a range of helper diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.c b/src/lib/elementary/efl_ui_internal_text_interactive.c index 5f623f83d5..608f6729fe 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 e57fc9c23d..73f010e7af 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); } @@ -3659,20 +3659,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; @@ -3681,7 +3681,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) { @@ -3705,7 +3705,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; @@ -3723,7 +3723,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); @@ -3765,8 +3765,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)); @@ -3780,8 +3779,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/elementary/efl_ui_view_model.c b/src/lib/elementary/efl_ui_view_model.c index 0580ff7d41..0194e47a87 100644 --- a/src/lib/elementary/efl_ui_view_model.c +++ b/src/lib/elementary/efl_ui_view_model.c @@ -183,6 +183,7 @@ _efl_ui_view_model_property_logic_add(Eo *obj, Efl_Ui_View_Model_Data *pd, logic->sources = eina_list_append(logic->sources, eina_stringshare_add(source)); efl_ui_view_model_property_bind(obj, source, property); } + eina_iterator_free(bound); return 0; } diff --git a/src/lib/elementary/efl_ui_view_model.eo b/src/lib/elementary/efl_ui_view_model.eo index d296c8c4ae..d5dcdbeaf8 100644 --- a/src/lib/elementary/efl_ui_view_model.eo +++ b/src/lib/elementary/efl_ui_view_model.eo @@ -76,8 +76,8 @@ class Efl.Ui.View_Model extends Efl.Composite_Model with the above property name.]] set: EflUiViewModelPropertySet; [[Define the set callback called when the @Efl.Model.property.set is called with the above property name.]] - binded: iterator; [[Iterator of property name to bind with this defined property see - @.property_bind.]] + binded: iterator @move; [[Iterator of property name to bind with this defined property see + @.property_bind.]] } return: Eina.Error; } diff --git a/src/lib/elementary/efl_ui_win.eo b/src/lib/elementary/efl_ui_win.eo index bca1b4a574..602acf506b 100644 --- a/src/lib/elementary/efl_ui_win.eo +++ b/src/lib/elementary/efl_ui_win.eo @@ -721,7 +721,7 @@ class Efl.Ui.Win extends Efl.Ui.Widget implements Efl.Canvas.Scene, Efl.Access.W hover: bool @optional; [[$false by default, $true means to include fingers that are currently hovering.]] } - return: iterator; [[Iterator to pointer positions]] + return: iterator @move; [[Iterator to pointer positions]] } @property win_rotation @beta { [[The rotation of this window diff --git a/src/lib/eolian_cxx/grammar/indentation.hpp b/src/lib/eolian_cxx/grammar/indentation.hpp index b88a14d392..3bf5d07dbe 100644 --- a/src/lib/eolian_cxx/grammar/indentation.hpp +++ b/src/lib/eolian_cxx/grammar/indentation.hpp @@ -53,6 +53,11 @@ struct scope_tab_generator int n; int m; + + explicit operator std::string() const + { + return std::string(n * m, ' '); + } }; template <> @@ -71,6 +76,12 @@ struct scope_tab_terminal { return {1}; } + + explicit operator std::string() const + { + return static_cast(scope_tab_generator{1}); + } + } const scope_tab = {}; template <> diff --git a/src/lib/evas/Efl_Canvas.h b/src/lib/evas/Efl_Canvas.h index a82d6a31cd..ed300478e0 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 7b5db77653..56971d0a14 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 d631cdcde5..0fa833c362 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 1e53fdbc93..10c43c71e8 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 64659ec887..9871008d5a 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 0000000000..2e01ee8cae --- /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 0000000000..52bc871880 --- /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 cfa87d7bba..238c9529b3 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 0485eb9e06..01c77fc688 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 e854d167e2..98cfc9f1f2 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -419,13 +419,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) @@ -461,7 +454,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; @@ -524,7 +517,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. */ @@ -604,12 +597,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 @@ -619,7 +609,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); @@ -803,7 +792,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) { @@ -6966,6 +6955,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. @@ -8953,7 +8949,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)); @@ -10082,7 +10078,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); @@ -10092,7 +10088,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; } @@ -10190,6 +10186,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 @@ -15219,6 +15222,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, @@ -15228,8 +15237,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; @@ -15246,8 +15255,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; @@ -15267,7 +15276,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); @@ -15283,24 +15292,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) { @@ -15332,60 +15341,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 (!o) + o = efl_data_scope_get(eo_obj, MY_CLASS); - 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; -} - -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) @@ -15393,64 +15362,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; + + //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); + } } -static void -_evas_textblock_annotations_clear(Efl_Canvas_Text_Data *o) +void +_evas_textblock_annotations_clear(const Eo *eo_obj) { - Efl_Text_Annotate_Annotation *an; + Efl_Text_Attribute_Handle *an; + Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); EINA_INLIST_FREE(o->annotations, an) { - _evas_textblock_annotation_remove(o, an, EINA_TRUE); + _evas_textblock_annotation_remove(NULL, o, an, EINA_TRUE, EINA_FALSE); } } -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) -{ - ASYNC_BLOCK; - if (!annotation || (annotation->obj != eo_obj)) - { - ERR("Used invalid handle or of a different object"); - return 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) @@ -15489,15 +15447,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); } @@ -15507,123 +15465,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 d9e6798b9b..07dd725b28 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/scripts/pyolian/eolian.py b/src/scripts/pyolian/eolian.py index 9ab6abd01e..e7681208c7 100644 --- a/src/scripts/pyolian/eolian.py +++ b/src/scripts/pyolian/eolian.py @@ -23,6 +23,7 @@ a way that this folder will be available on PYTHON_PATH, fe: from pyolian.generator import Template """ +import os from enum import IntEnum import atexit from ctypes import cast, byref, c_char_p, c_void_p, c_int @@ -520,6 +521,44 @@ class Eolian_State(Eolian_Unit): return bool(lib.eolian_state_check(self)) +# Helper functions ################################################### + +def parse_folders(folders): + """Loads a new database scanning the given folders. + + For example: + + SCAN_FOLDER = os.path.join(eolian.in_tree_src_dir(), 'src', 'lib') + eolian_db = eolian.parse_folders(SCAN_FOLDER) + """ + + db = Eolian_State() + if not isinstance(db, Eolian_State): + raise (RuntimeError('Eolian, failed to create Eolian state')) + + if isinstance(folders, str): + folders = [folders] + + for folder in folders: + # eolian source tree scan + if not db.directory_add(folder): + raise (RuntimeError('Eolian, failed to scan source dirsectory')) + + # Parse all known eo files + if not db.all_eot_files_parse(): + raise (RuntimeError('Eolian, failed to parse all EOT files')) + + if not db.all_eo_files_parse(): + raise (RuntimeError('Eolian, failed to parse all EO files')) + + return db + +def in_tree_src_dir(): + """Returns the root folder of this script's source tree""" + script_path = os.path.dirname(os.path.realpath(__file__)) + return os.path.abspath(os.path.join(script_path, '..', '..', '..')) + + # Namespace Utility Class ################################################### class Namespace(object): @@ -732,6 +771,23 @@ class Class(Object): def extensions(self): return Iterator(Class, lib.eolian_class_extensions_get(self)) + @cached_property + def extensions_hierarchy(self): + visited = set() + queue = [ext for ext in self.extensions] + + while queue: + current = queue.pop() + + if current in visited: + continue + + visited.add(current) + + queue.extend(current.extensions) + + return visited + @cached_property def inherits_full(self): li = [] @@ -739,6 +795,7 @@ class Class(Object): def do_class_recursive(cls): if cls.parent: li.append(cls.parent) + do_class_recursive(cls.parent) for other in cls.extensions: if other not in li: li.append(other) diff --git a/src/scripts/pyolian/test_eolian.py b/src/scripts/pyolian/test_eolian.py index 4aa4588640..133b279084 100755 --- a/src/scripts/pyolian/test_eolian.py +++ b/src/scripts/pyolian/test_eolian.py @@ -699,3 +699,16 @@ class TestEolianExpression(object): # exp.binary_operator # TODO find a better test (only works for BINARY expr) # exp.binary_lhs # TODO find a better test (only works for BINARY expr) # exp.binary_rhs # TODO find a better test (only works for BINARY expr) + +class TestEolianInherits(object): + def test_inherits_full(self, eolian_db): + cls = eolian_db.class_by_name_get('Efl.Ui.Widget') + assert 'Efl.Object' in cls.inherits_full + + def test_extensions_hierarchy(self, eolian_db): + cls = eolian_db.class_by_name_get('Efl.Ui.Widget') + + # inherited extension + assert any(x.name == 'Efl.Gfx.Stack' for x in cls.extensions_hierarchy) + # direct extension + assert any(x.name == 'Efl.Access.Object' for x in cls.extensions_hierarchy) diff --git a/src/tests/efl_mono/Inheritance.cs b/src/tests/efl_mono/Inheritance.cs index 1595759994..852a639029 100644 --- a/src/tests/efl_mono/Inheritance.cs +++ b/src/tests/efl_mono/Inheritance.cs @@ -142,9 +142,9 @@ class TestInheritance CreateAndCheckInheritedObjects(out parentWRef, out childWRef); - // Two invocations to iterate a the child wasn't being released with a single one - Test.CollectAndIterate(); - Test.CollectAndIterate(); + // We need some extra iterations of the main loop to allow the async callbacks + // registered from the Dispose method to the main loop to run. + Test.CollectAndIterate(10, 10); var parent = (Dummy.TestObject) parentWRef.Target; var child = (Dummy.TestObject) childWRef.Target; diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index 860c674397..163d403ef2 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()); + 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"); - 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)); - - 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); \ } \