diff --git a/src/bin/elementary/test_gfx_filters.c b/src/bin/elementary/test_gfx_filters.c index 988c0769c4..47e83d7707 100644 --- a/src/bin/elementary/test_gfx_filters.c +++ b/src/bin/elementary/test_gfx_filters.c @@ -514,10 +514,11 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve "blur { 3, ox = 1, oy = 1, color = 'black' }" "blend { color = 'lime' }"; - o = code = efl_add(EFL_UI_TEXT_EDITABLE_CLASS, win, - efl_ui_text_scrollable_set(efl_added, 1), - efl_text_multiline_set(efl_added, 1)); - efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed_hack, win); + o = code = efl_add(EFL_UI_TEXT_CLASS, win, + efl_ui_text_scrollable_set(efl_added, EINA_TRUE), + efl_text_interactive_editable_set(efl_added, EINA_TRUE), + efl_text_multiline_set(efl_added, EINA_TRUE)); + efl_event_callback_add(o, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, _code_changed_hack, win); // Insert filter code inside style string: DEFAULT='blah blah ' efl_gfx_filter_program_set(o, code_filter, "code"); diff --git a/src/examples/elementary/efl_ui_list_example_1.c b/src/examples/elementary/efl_ui_list_example_1.c index 49cd52250c..f8f5c5b683 100644 --- a/src/examples/elementary/efl_ui_list_example_1.c +++ b/src/examples/elementary/efl_ui_list_example_1.c @@ -17,7 +17,6 @@ # include # include # include -# include # include #define NUM_ITEMS 400 diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index 1703b16529..0c4b649730 100644 --- a/src/lib/efl/Efl.h +++ b/src/lib/efl/Efl.h @@ -146,7 +146,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command; #include "interfaces/efl_ui_draggable.eo.h" #include "interfaces/efl_ui_scrollable.eo.h" #include "interfaces/efl_ui_scrollbar.eo.h" -#include "interfaces/efl_ui_text_selectable.eo.h" #include "interfaces/efl_ui_container_selectable.eo.h" #include "interfaces/efl_ui_zoom.eo.h" @@ -213,6 +212,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command; #include "interfaces/efl_text_format.eo.h" #include "interfaces/efl_text_markup.eo.h" #include "interfaces/efl_text_markup_util.eo.h" +#include "interfaces/efl_input_text.eo.h" /** * @brief Get a proxy object referring to a part of an object. diff --git a/src/lib/efl/interfaces/efl_input_text.eo b/src/lib/efl/interfaces/efl_input_text.eo new file mode 100644 index 0000000000..37d3acb978 --- /dev/null +++ b/src/lib/efl/interfaces/efl_input_text.eo @@ -0,0 +1,274 @@ +enum @beta Efl.Input_Text.Panel_Layout_Type +{ + [[Input panel (virtual keyboard) layout types. + Type of input panel (virtual keyboard) to use - this is a hint and may not provide exactly what is desired. + ]] + normal, [[Default layout.]] + number, [[Number layout.]] + email, [[Email layout.]] + url, [[URL layout.]] + phonenumber, [[Phone Number layout.]] + ip, [[IP layout.]] + month, [[Month layout.]] + numberonly, [[Number Only layout.]] + invalid, [[Never use this.]] + hex, [[Hexadecimal layout.]] + terminal, [[Command-line terminal layout including esc, alt, ctrl key, so on (no auto-correct, no auto-capitalization).]] + password, [[Like normal, but no auto-correct, no auto-capitalization etc.]] + datetime, [[Date and time layout + + @since 1.8]] + emoticon, [[Emoticon layout + + @since 1.10]] + voice [[Voice layout, but if the IME does not support voice layout, then normal layout will be shown. + + @since 1.19]] +} + +enum @beta Efl.Input_Text.Panel_Language_Type +{ + [[Input panel (virtual keyboard) language modes. + ]] + automatic, [[Automatic]] + alphabet [[Alphabet]] +} + +enum @beta Efl.Input_Text.Capitalize_Type +{ + [[Autocapitalization Types. + Choose method of auto-capitalization. + ]] + none, [[No auto-capitalization when typing.]] + word, [[Autocapitalize each word typed.]] + sentence, [[Autocapitalize the start of each sentence.]] + allcharacter [[Autocapitalize all letters.]] +} + +enum @beta Efl.Input_Text.Panel_Return_Key_Type +{ + [["Return" Key types on the input panel (virtual keyboard). + ]] + default, [[Default.]] + done, [[Done.]] + go, [[Go.]] + join, [[Join.]] + login, [[Login.]] + next, [[Next.]] + search, [[Search string or magnifier icon.]] + send, [[Send.]] + signin [[Sign-in + + @since 1.8]] +} + +enum @beta Efl.Input_Text.Panel_Return_Key_State +{ + [["Return" Key state on the input panel (virtual keyboard). + ]] + auto, [[The return key on input panel is disabled when the entry has no text, + if entry has text, return key is enabled. + ]] + enabled, [[The return key on input panel is enabled.]] + disabled, [[The return key on input panel is disabled.]] +} + +enum @beta Efl.Input_Text.Hints_Type +{ + [[Enumeration that defines the types of Input Hints. + + @since 1.12 + ]] + none = 0, [[No active hints + + @since 1.12]] + auto_complete = 1 << 0, [[Suggest word auto completion + + @since 1.12]] + sensitive_data = 1 << 1, [[Typed text should not be stored. + + @since 1.12]] + autofill_credit_card_expiration_date = 0x100, [[ Autofill hint for a credit card expiration date + + @since 1.21]] + autofill_credit_card_expiration_day = 0x200, [[Autofill hint for a credit card expiration day + + @since 1.21]] + autofill_credit_card_expiration_month = 0x300, [[ Autofill hint for a credit card expiration month + + @since 1.21]] + autofill_credit_card_expiration_year = 0x400, [[ Autofill hint for a credit card expiration year + + @since 1.21]] + autofill_credit_card_number = 0x500, [[ Autofill hint for a credit card number + + @since 1.21]] + autofill_email_address = 0x600, [[ Autofill hint for an email address + + @since 1.21]] + autofill_name = 0x700, [[ Autofill hint for a user's real name + + @since 1.21]] + autofill_phone = 0x800, [[ Autofill hint for a phone number + + @since 1.21]] + autofill_postal_address = 0x900, [[ Autofill hint for a postal address + + @since 1.21]] + autofill_postal_code = 0xA00, [[ Autofill hint for a postal code + + @since 1.21]] + autofill_id = 0xB00 [[ Autofill hint for a user's ID + + @since 1.21]] +} + +interface @beta Efl.Input_Text { + [[All the functionality relating to input hints + ]] + methods { + @property input_panel_show_on_demand { + [[Set/Get the attribute to show the input panel in case of only a user's explicit Mouse Up event. + It doesn't request to show the input panel even though it has focus.]] + set { + } + get { + } + values { + ondemand: bool; [[If $true, the input panel will be shown in case of only Mouse up event. + (Focus event will be ignored.) + ]] + } + } + + // FIXME: I don't understand why this is needed in addition to Layout + @property input_panel_language { + [[The language mode of the input panel. + This API can be used if you want to show the alphabet keyboard mode.]] + set { + } + get { + } + values { + lang: Efl.Input_Text.Panel_Language_Type; [[Language to be set to the input panel.]] + } + } + + // FIXME: What is this? + @property input_panel_layout_variation { + [[The input panel layout variation of the entry.]] + set { + } + get { + } + values { + variation: int; [[Layout variation type.]] + } + } + + // FIXME: input_capitalize/capitalization ? + @property autocapitalization { + [[The autocapitalization type on the immodule.]] + set { + } + get { + } + values { + autocapital_type: Efl.Input_Text.Capitalize_Type; [[The type of autocapitalization.]] + } + } + + // FIXME: rename + @property predictable { + [[Whether the entry should allow predictive text.]] + set { + } + get { + } + values { + prediction: bool; [[Whether the entry should allow predictive text.]] + } + } + // FIXME: I agree with Mike, looks bad + @property input_hint { + [[The input hint which allows input methods to fine-tune their behavior.]] + set { + } + get { + } + values { + hints: Efl.Input_Text.Hints_Type; [[Input hint.]] + } + } + @property input_panel_layout { + [[The input panel layout of the entry.]] + set { + } + get { + } + values { + layout: Efl.Input_Text.Panel_Layout_Type(Efl.Input_Text.Panel_Layout_Type.invalid); [[Layout type.]] + } + } + @property input_panel_return_key_type { + [[The "return" key type. This type is used to set string or icon on the "return" key of the input panel. + An input panel displays the string or icon associated with this type.]] + set { + } + get { + } + values { + return_key_type: Efl.Input_Text.Panel_Return_Key_Type; [[The type of "return" key on the input panel.]] + } + } + // FIXME: shouldn't this be "autoshow" or something? + @property input_panel_autoshow { + [[The attribute to show the input panel automatically.]] + set { + } + get { + } + values { + enabled: bool; [[If $true, the input panel is appeared when entry is clicked or has a focus.]] + } + } + + @property input_panel_return_key_state { + [[State for the return key on the input panel see @Efl.Input_Text.Panel_Return_Key_State.]] + set { + } + get { + } + values { + state: Efl.Input_Text.Panel_Return_Key_State; [[Enable state for return key, see @Efl.Input_Text.Panel_Return_Key_State.]] + } + } + + input_panel_show { + [[Show the input panel (virtual keyboard) based on the input panel property of entry such as layout, autocapital types and so on. + + Note that input panel is shown or hidden automatically according to the focus state of entry widget. + This API can be used in the case of manually controlling by using @.input_panel_autoshow.set(en, $false). + ]] + } + + input_panel_hide { + [[Hide the input panel (virtual keyboard). + Note that input panel is shown or hidden automatically according to the focus state of entry widget. + This API can be used in the case of manually controlling by using @.input_panel_autoshow.set(en, $false). + ]] + } + + @property input_panel_imdata { + [[Set/Get the input panel-specific data to deliver to the input panel. + + This API is used by applications to deliver specific data to the input panel. + The data format MUST be negotiated by both application and the input panel. + The size and format of data are defined by the input panel. + ]] + values { + value: slice; [[The specific data to be set/get to the input panel.]] + } + } + } +} \ No newline at end of file diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c index 3e94adcb5e..8635ed5778 100644 --- a/src/lib/efl/interfaces/efl_interfaces_main.c +++ b/src/lib/efl/interfaces/efl_interfaces_main.c @@ -25,6 +25,7 @@ #include "interfaces/efl_text_style.eo.c" #include "interfaces/efl_text_format.eo.c" #include "interfaces/efl_text_markup.eo.c" +#include "interfaces/efl_input_text.eo.c" #include "interfaces/efl_gfx_entity.eo.c" #include "interfaces/efl_gfx_buffer.eo.c" @@ -72,7 +73,6 @@ #include "interfaces/efl_ui_scrollable.eo.c" #include "interfaces/efl_ui_scrollbar.eo.c" #include "interfaces/efl_ui_container_selectable.eo.c" -#include "interfaces/efl_ui_text_selectable.eo.c" #include "interfaces/efl_ui_zoom.eo.c" diff --git a/src/lib/efl/interfaces/efl_text_types.eot b/src/lib/efl/interfaces/efl_text_types.eot index 159975ea8c..c0451e03aa 100644 --- a/src/lib/efl/interfaces/efl_text_types.eot +++ b/src/lib/efl/interfaces/efl_text_types.eot @@ -10,7 +10,7 @@ enum Efl.Text_Bidirectional_Type { inherit [[Inherit text type]] } -struct @beta Efl.Ui.Text_Change_Info { +struct @beta Efl.Text_Change_Info { [[This structure includes all the information about content changes. It's meant to be used to implement undo/redo. @@ -22,4 +22,11 @@ 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]] } +struct @beta Efl.Text_Range { + [[This structure includes text position range (from/to). + ]] + start: int; [[The start postion.]] + end: int; [[The end position.]] +} + 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_text_selectable.eo b/src/lib/efl/interfaces/efl_ui_text_selectable.eo deleted file mode 100644 index 13dda60d9e..0000000000 --- a/src/lib/efl/interfaces/efl_ui_text_selectable.eo +++ /dev/null @@ -1,13 +0,0 @@ -interface @beta Efl.Ui.Text_Selectable -{ - [[Efl UI text selectable interface]] - event_c_prefix: efl_ui; - events { - selection,paste: void; [[Called when selection is pasted]] - selection,copy: void; [[Called when selection is copied]] - selection,cut: void; [[Called when selection is cut]] - selection,start: void; [[Called at selection start]] - selection,changed: void; [[Called when selection is changed]] - selection,cleared: void; [[Called when selection is cleared]] - } -} diff --git a/src/lib/efl/interfaces/meson.build b/src/lib/efl/interfaces/meson.build index a823e01b0c..c5bad7e54e 100644 --- a/src/lib/efl/interfaces/meson.build +++ b/src/lib/efl/interfaces/meson.build @@ -10,7 +10,6 @@ pub_legacy_eo_files = [ 'efl_ui_scrollable.eo', 'efl_ui_scrollbar.eo', 'efl_ui_container_selectable.eo', - 'efl_ui_text_selectable.eo', 'efl_ui_zoom.eo', ] @@ -94,6 +93,7 @@ pub_eo_files = [ 'efl_gfx_text_class.eo', 'efl_gfx_size_class.eo', 'efl_cached_item.eo', + 'efl_input_text.eo', ] foreach eo_file : pub_eo_files diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h index 377f63bd68..c1678c443e 100644 --- a/src/lib/elementary/Efl_Ui.h +++ b/src/lib/elementary/Efl_Ui.h @@ -227,7 +227,6 @@ typedef void (*Context_Item_Clicked_Cb)(void *data, Eo *obj, void *event_info); # include # include -# include # include # include diff --git a/src/lib/elementary/efl_text_interactive.eo b/src/lib/elementary/efl_text_interactive.eo index d5c261f5a2..a614810d7e 100644 --- a/src/lib/elementary/efl_text_interactive.eo +++ b/src/lib/elementary/efl_text_interactive.eo @@ -13,11 +13,11 @@ interface @beta Efl.Text_Interactive extends Efl.Text, Efl.Text_Font, } } @property selection_allowed { - [[Whether or not selection is allowed on this object]] + [[Whether or not selection is allowed on this object.]] set {} get {} values { - allowed: bool; [[$true if enabled, $false otherwise]] + allowed: bool; [[$true if enabled, $false otherwise.]] } } @property selection_cursors { @@ -50,11 +50,34 @@ interface @beta Efl.Text_Interactive extends Efl.Text, Efl.Text_Font, if not, the entry is read-only and no user input is allowed.]] } } - select_none { + all_unselect { [[Clears the selection.]] } + all_select { + [[Select all the content.]] + } + @property have_selection { + [[Whether the entry have a selected text. + ]] + get { + } + values { + selected: bool; [[If $true, entry have selected text, $false otherwise.]] + } + } } events { - text,selection,changed: void; [[The selection on the object has changed. Query using @.selection_cursors]] + preedit,changed: void; [[Called when entry preedit changed.]] + have_selection,changed: bool; [[Called when @.have_selection property value changed.]] + selection,changed: Efl.Text_Range; [[Called when selection has changed. Query using @.selection_cursors.]] + redo,request: void; [[Called when redo is requested]] + undo,request: void; [[Called when undo is requested]] + changed,user: Efl.Text_Change_Info; [[The content has changed due to user interaction.]] + // FIXME: efl_ui_text doesn't support anchor callbacks yet. + //anchor,down: Elm.Entry_Anchor_Info; [[Called on anchor down]] + //anchor,hover,opened: Elm.Entry_Anchor_Hover_Info; [[Called when hover opened]] + //anchor,in: Elm.Entry_Anchor_Info; [[Called on anchor in]] + //anchor,out: Elm.Entry_Anchor_Info; [[Called on anchor out]] + //anchor,up: Elm.Entry_Anchor_Info; [[called on anchor up]] } } diff --git a/src/lib/elementary/efl_ui_clock.c b/src/lib/elementary/efl_ui_clock.c index 462f2be615..38d9fc99db 100644 --- a/src/lib/elementary/efl_ui_clock.c +++ b/src/lib/elementary/efl_ui_clock.c @@ -200,7 +200,7 @@ field_create(Eo *obj, Efl_Ui_Clock_Type field_type) field_obj = efl_add(EFL_UI_TEXT_CLASS,obj, efl_text_multiline_set(efl_added, EINA_FALSE), efl_text_interactive_editable_set(efl_added, EINA_FALSE), - efl_ui_text_input_panel_enabled_set(efl_added, EINA_FALSE), + efl_input_text_input_panel_autoshow_set(efl_added, EINA_FALSE), efl_ui_text_context_menu_disabled_set(efl_added, EINA_TRUE)); } evas_object_data_set(field_obj, "_field_type", (void *)field_type); diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.c b/src/lib/elementary/efl_ui_internal_text_interactive.c index 608f6729fe..c5bda6b59d 100644 --- a/src/lib/elementary/efl_ui_internal_text_interactive.c +++ b/src/lib/elementary/efl_ui_internal_text_interactive.c @@ -13,20 +13,28 @@ typedef struct _Efl_Ui_Internal_Text_Interactive_Data { - Efl_Text_Cursor *sel_start, *sel_end; - Efl_Text_Cursor *main_cursor; - Efl_Text_Cursor *preedit_start, *preedit_end; - Eina_List *seq; - char *selection; - Eina_Bool composing : 1; - Eina_Bool selecting : 1; - Eina_Bool have_selection : 1; - Eina_Bool select_allow : 1; - Eina_Bool editable : 1; - Eina_Bool had_sel : 1; - Eina_Bool input_panel_enable : 1; - Eina_Bool prediction_allow : 1; - Eina_Bool anchors_updated : 1; + Efl_Text_Cursor *sel_start, *sel_end; + Efl_Text_Cursor *main_cursor; + Efl_Text_Cursor *preedit_start, *preedit_end; + Ecore_Timer *pw_timer; + Eina_List *seq; + char *selection; + Eina_Bool composing : 1; + Eina_Bool selecting : 1; + Eina_Bool have_selection : 1; + Eina_Bool select_allow : 1; + Eina_Bool editable : 1; + Eina_Bool had_sel : 1; + Eina_Bool prediction_allow : 1; + Eina_Bool anchors_updated : 1; + Eina_Bool auto_return_key : 1; + int input_panel_layout_variation; + Efl_Input_Text_Panel_Layout_Type input_panel_layout; + Efl_Input_Text_Capitalize_Type autocapital_type; + Efl_Input_Text_Panel_Language_Type input_panel_lang; + Efl_Input_Text_Panel_Return_Key_Type input_panel_return_key_type; + Efl_Input_Text_Hints_Type input_hints; + Efl_Input_Text_Panel_Return_Key_State input_panel_return_key_state; #ifdef HAVE_ECORE_IMF Eina_Bool have_preedit : 1; @@ -41,7 +49,32 @@ static void _sel_enable(Efl_Text_Cursor *c EINA_UNUSED, Evas_Object *o EINA_UNUS static void _sel_extend(Efl_Text_Cursor *c, Evas_Object *o, Efl_Ui_Internal_Text_Interactive_Data *en); static void _sel_clear(Evas_Object *o EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en); static const char *_entry_selection_get(Efl_Ui_Internal_Text_Interactive *obj, Efl_Ui_Internal_Text_Interactive_Data *en); -static void _entry_imf_cursor_info_set(Eo *obj, Efl_Text_Cursor *cur, Efl_Ui_Internal_Text_Interactive_Data *en); +static void _entry_imf_cursor_info_set(Efl_Ui_Internal_Text_Interactive_Data *en); + +static void +_text_filter_format_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, const char *text); + +static Efl_Text_Change_Info * +_text_filter_text_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo); + +static Efl_Text_Change_Info * +_text_filter_markup_prepend_internal(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo); + +static Efl_Text_Change_Info * +_text_filter_markup_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo); #ifdef HAVE_ECORE_IMF static void @@ -102,12 +135,55 @@ _entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSE return EINA_TRUE; } +static void +_return_key_update(Evas_Object *obj) +{ +#ifdef HAVE_ECORE_IMF + Eina_Bool return_key_disabled = EINA_FALSE; + Efl_Ui_Internal_Text_Interactive_Data *sd = efl_data_scope_get(obj, MY_CLASS); + + if (sd->input_panel_return_key_state != EFL_INPUT_TEXT_PANEL_RETURN_KEY_STATE_AUTO) return; + + if (efl_canvas_text_is_empty_get(obj) == EINA_TRUE) + return_key_disabled = EINA_TRUE; + + if (sd->imf_context) + ecore_imf_context_input_panel_return_key_disabled_set(sd->imf_context, return_key_disabled); +#else + (void)obj; +#endif +} + +Eina_Bool +_entry_hide_visible_password(Eo *obj) +{ + Eina_Bool b_ret = EINA_FALSE; + const Evas_Object_Textblock_Node_Format *node; + node = evas_textblock_node_format_first_get(obj); + for (; node; node = evas_textblock_node_format_next_get(node)) + { + const char *text = evas_textblock_node_format_text_get(node); + if (text) + { + if (!strcmp(text, "+ password=off")) + { + evas_textblock_node_format_remove_pair(obj, + (Evas_Object_Textblock_Node_Format *)node); + b_ret = EINA_TRUE; + } + } + } + + return b_ret; +} + static void _entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void *event_info) { Efl_Canvas_Text *obj = data; Efl_Ui_Internal_Text_Interactive_Data *en = efl_data_scope_get(obj, MY_CLASS); char *commit_str = event_info; + Efl_Text_Change_Info *info = NULL; if (en->have_selection) { @@ -130,49 +206,211 @@ _entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, void return; } -#if 0 - Edje_Entry_Change_Info *info = NULL; - if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && - _password_show_last) - _entry_hide_visible_password(en->rp); - if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && - _password_show_last && (!en->preedit_start)) + if (efl_text_password_get(obj) && (!en->preedit_start)) { - info = _text_filter_text_prepend(en, cur, commit_str, + info = _text_filter_text_prepend(obj, en, en->main_cursor, commit_str, "+ password=off", "- password", EINA_TRUE, EINA_TRUE); - if (info) - { - if (en->pw_timer) - { - ecore_timer_del(en->pw_timer); - en->pw_timer = NULL; - } - if (_password_show_last_timeout >= 0) - en->pw_timer = ecore_timer_add - (_password_show_last_timeout, - _password_timer_cb, en); - } } else { - info = _text_filter_text_prepend(en, cur, commit_str, + info = _text_filter_text_prepend(obj, en, en->main_cursor, commit_str, NULL, NULL, EINA_TRUE, EINA_TRUE); } _entry_imf_cursor_info_set(en); - _anchors_get(cur, obj, en); if (info) { - _emit("entry,changed", rp->part->name); - _emit_full("entry,changed,user", rp->part->name, - info, _free_entry_change_info); - _emit("cursor,changed", rp->part->name); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, info); + eina_stringshare_del(info->content); + free(info); + info = NULL; } _entry_imf_cursor_info_set(en); - _entry_real_part_configure(rp); +} + +static Efl_Text_Change_Info * +_text_filter_markup_prepend_internal(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) +{ + Eina_Bool have_sel = EINA_FALSE; + + if ((clearsel) && (en->have_selection)) + { + _sel_range_del_emit(obj, en); + have_sel = EINA_TRUE; + } + +#ifdef HAVE_ECORE_IMF + // For skipping useless commit + if (en->have_preedit && (!text || !strcmp(text, ""))) + en->commit_cancel = EINA_TRUE; + else + en->commit_cancel = EINA_FALSE; #endif + if (text) + { + Efl_Text_Change_Info *info = NULL; + + if (changeinfo) + { + info = calloc(1, sizeof(*info)); + info->insert = EINA_TRUE; + info->content = eina_stringshare_add(text); + info->length = + eina_unicode_utf8_get_len(info->content); + } + if (info) + { + if (have_sel) + { + info->merge = EINA_TRUE; + } + info->position = + efl_text_cursor_position_get(efl_text_interactive_main_cursor_get(obj)); + } + if (fmtpre) _text_filter_format_prepend(obj, en, efl_text_interactive_main_cursor_get(obj), fmtpre); + //evas_object_textblock_text_markup_prepend(c, text); + efl_text_cursor_text_insert(c, text); + free(text); + if (fmtpost) _text_filter_format_prepend(obj, en, efl_text_interactive_main_cursor_get(obj), fmtpost); + return info; + } + return NULL; +} + +static Efl_Text_Change_Info * +_text_filter_markup_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) +{ + char *text2; + + EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); + + if ((clearsel) && (en->have_selection)) + { + _sel_range_del_emit(obj, en); + } + + text2 = strdup(text); + if (text2) + { + Efl_Text_Change_Info *info; + + info = _text_filter_markup_prepend_internal(obj, en, c, text2, + fmtpre, fmtpost, + clearsel, changeinfo); + return info; + } + return NULL; +} + +static Efl_Text_Change_Info * +_text_filter_text_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, + const char *text, + const char *fmtpre, const char *fmtpost, + Eina_Bool clearsel, Eina_Bool changeinfo) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); + + if ((clearsel) && (en->have_selection)) + { + _sel_range_del_emit(obj, en); + } + + if (text) + { + char *markup_text; + Efl_Text_Change_Info *info = NULL; + + markup_text = evas_textblock_text_utf8_to_markup(NULL, text); + if (markup_text) + info = _text_filter_markup_prepend_internal(obj, en, c, markup_text, + fmtpre, fmtpost, + clearsel, changeinfo); + return info; + } + return NULL; +} + +static void +_text_filter_format_prepend(Efl_Canvas_Text *obj, Efl_Ui_Internal_Text_Interactive_Data *en, + Efl_Text_Cursor *c, const char *text) +{ + EINA_SAFETY_ON_NULL_RETURN(text); + + if (text) + { + const char *s; + char *markup_text; + size_t size; + + s = text; + if (*s == '+') + { + s++; + while (*s == ' ') + s++; + if (!*s) + { + return; + } + size = strlen(s); + markup_text = (char *)malloc(size + 3); + if (markup_text) + { + *(markup_text) = '<'; + memcpy((markup_text + 1), s, size); + *(markup_text + size + 1) = '>'; + *(markup_text + size + 2) = '\0'; + } + } + else if (s[0] == '-') + { + s++; + while (*s == ' ') + s++; + if (!*s) + { + return; + } + size = strlen(s); + markup_text = (char *)malloc(size + 4); + if (markup_text) + { + *(markup_text) = '<'; + *(markup_text + 1) = '/'; + memcpy((markup_text + 2), s, size); + *(markup_text + size + 2) = '>'; + *(markup_text + size + 3) = '\0'; + } + } + else + { + size = strlen(s); + markup_text = (char *)malloc(size + 4); + if (markup_text) + { + *(markup_text) = '<'; + memcpy((markup_text + 1), s, size); + *(markup_text + size + 1) = '/'; + *(markup_text + size + 2) = '>'; + *(markup_text + size + 3) = '\0'; + } + } + if (markup_text) + _text_filter_markup_prepend_internal(obj, en, c, markup_text, + NULL, NULL, + EINA_FALSE, EINA_FALSE); + } } static void @@ -181,6 +419,7 @@ _entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUS Efl_Canvas_Text *obj = data; Efl_Text_Cursor *cur = efl_text_interactive_main_cursor_get(obj); Efl_Ui_Internal_Text_Interactive_Data *en = efl_data_scope_get(obj, MY_CLASS); + Efl_Text_Change_Info *info = NULL; int cursor_pos; int preedit_start_pos, preedit_end_pos; char *preedit_string; @@ -256,38 +495,22 @@ _entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUS // For skipping useless commit if (!preedit_end_state) en->have_preedit = EINA_TRUE; -#if 0 - if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && - _password_show_last) - { - Edje_Entry_Change_Info *info; - _entry_hide_visible_password(en->rp); - info = _text_filter_markup_prepend(en, cur, + if (efl_text_password_get(obj)) + { + _entry_hide_visible_password(obj); + info = _text_filter_markup_prepend(obj, en, cur, eina_strbuf_string_get(buf), "+ password=off", "- password", EINA_TRUE, EINA_TRUE); - if (info) - { - if (en->pw_timer) - { - ecore_timer_del(en->pw_timer); - en->pw_timer = NULL; - } - if (_password_show_last_timeout >= 0) - en->pw_timer = ecore_timer_add - (_password_show_last_timeout, - _password_timer_cb, en); - free(info); - } } else - _text_filter_markup_prepend(en, cur, + _text_filter_markup_prepend(obj, en, cur, eina_strbuf_string_get(buf), NULL, NULL, EINA_TRUE, EINA_FALSE); -#endif + eina_strbuf_free(buf); } @@ -316,7 +539,14 @@ _entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUS efl_text_cursor_position_set(cur, preedit_start_pos + cursor_pos); } - _entry_imf_cursor_info_set(obj, cur, en); + if (info) + { + _entry_imf_cursor_info_set(en); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_PREEDIT_CHANGED, info); + eina_stringshare_del(info->content); + free(info); + info = NULL; + } /* delete attribute list */ if (attrs) @@ -336,7 +566,7 @@ _entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_U Efl_Ui_Internal_Text_Interactive_Data *en = efl_data_scope_get(obj, MY_CLASS); Ecore_IMF_Event_Delete_Surrounding *ev = event_info; Efl_Text_Cursor *del_start, *del_end; - Efl_Ui_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; int cursor_pos; int start, end; char *tmp; @@ -362,10 +592,10 @@ _entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx EINA_U efl_text_cursor_range_delete(del_start, del_end); - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED_USER, &info); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); free(tmp); - _entry_imf_cursor_info_set(obj, cur, en); + _entry_imf_cursor_info_set(en); end: efl_del(del_start); @@ -418,13 +648,13 @@ _entry_imf_retrieve_selection_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, #endif static void -_entry_imf_cursor_location_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor *cur, Efl_Ui_Internal_Text_Interactive_Data *en) +_entry_imf_cursor_location_set(Efl_Ui_Internal_Text_Interactive_Data *en) { #ifdef HAVE_ECORE_IMF Eina_Rect rect; if (!en->imf_context) return; - rect = efl_text_cursor_geometry_get(cur, EFL_TEXT_CURSOR_TYPE_BEFORE); + rect = efl_text_cursor_geometry_get(en->main_cursor ,EFL_TEXT_CURSOR_TYPE_BEFORE); ecore_imf_context_cursor_location_set(en->imf_context, rect.x, rect.y, rect.w, rect.h); // FIXME: ecore_imf_context_bidi_direction_set(en->imf_context, (Ecore_IMF_BiDi_Direction)dir); #else @@ -433,7 +663,7 @@ _entry_imf_cursor_location_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor *cur, Efl_Ui } static void -_entry_imf_cursor_info_set(Eo *obj, Efl_Text_Cursor *cur, Efl_Ui_Internal_Text_Interactive_Data *en) +_entry_imf_cursor_info_set(Efl_Ui_Internal_Text_Interactive_Data *en) { int cursor_pos; @@ -448,11 +678,11 @@ _entry_imf_cursor_info_set(Eo *obj, Efl_Text_Cursor *cur, Efl_Ui_Internal_Text_I cursor_pos = efl_text_cursor_position_get(en->sel_end); } else - cursor_pos = efl_text_cursor_position_get(cur); + cursor_pos = efl_text_cursor_position_get(en->main_cursor); ecore_imf_context_cursor_position_set(en->imf_context, cursor_pos); - _entry_imf_cursor_location_set(obj, cur, en); + _entry_imf_cursor_location_set(en); #else (void)en; #endif @@ -463,13 +693,13 @@ _focus_in_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void { #ifdef HAVE_ECORE_IMF Efl_Ui_Internal_Text_Interactive_Data *en = efl_data_scope_get(obj, MY_CLASS); - Efl_Text_Cursor *cur; if (!en->imf_context) return; - cur = efl_text_interactive_main_cursor_get(obj); ecore_imf_context_focus_in(en->imf_context); - _entry_imf_cursor_info_set(obj, cur, en); + _entry_imf_cursor_info_set(en); + + _return_key_update(obj); #endif } @@ -541,9 +771,28 @@ _sel_enable(Efl_Text_Cursor *c EINA_UNUSED, en->selection = NULL; } + Eina_Bool b_value = EINA_TRUE; + efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); _entry_imf_context_reset(en); } +static void +_emit_sel_state( Eo *o, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + if (!efl_text_cursor_compare(en->sel_start, en->sel_end)) + { + Eina_Bool b_value = EINA_FALSE; + efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); + } + else + { + Efl_Text_Range range = {0}; + range.start = efl_text_cursor_position_get(en->sel_start); + range.end = efl_text_cursor_position_get(en->sel_end); + efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED, &range); + } +} + static void _sel_extend(Efl_Text_Cursor *c, Evas_Object *o, Efl_Ui_Internal_Text_Interactive_Data *en) { @@ -553,14 +802,15 @@ _sel_extend(Efl_Text_Cursor *c, Evas_Object *o, Efl_Ui_Internal_Text_Interactive efl_text_cursor_copy(c, en->sel_end); - _entry_imf_cursor_info_set(o, c, en); + _entry_imf_cursor_info_set(en); if (en->selection) { free(en->selection); en->selection = NULL; } - efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_TEXT_SELECTION_CHANGED, NULL); + + _emit_sel_state(o, en); } static void @@ -575,24 +825,51 @@ _sel_clear(Evas_Object *o EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en if (en->have_selection) { en->have_selection = EINA_FALSE; + Eina_Bool b_value = en->have_selection; efl_text_cursor_copy(en->sel_start, en->sel_end); - efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_TEXT_SELECTION_CHANGED, NULL); + efl_event_callback_call(o, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); } } -static void -_efl_ui_internal_text_interactive_efl_text_interactive_select_none( +EOLIAN static void +_efl_ui_internal_text_interactive_efl_text_interactive_all_unselect( Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) { _sel_clear(obj, en); } +EOLIAN static Eina_Bool +_efl_ui_internal_text_interactive_efl_text_interactive_have_selection_get( + const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + return !efl_text_cursor_equal(en->sel_start, en->sel_end); +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_text_interactive_all_select( + Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + if (!efl_text_interactive_selection_allowed_get(obj)) + return; + + Efl_Text_Cursor *cur = efl_text_interactive_main_cursor_get(obj); + _entry_imf_context_reset(en); + + efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_FIRST); + _entry_imf_context_reset(en); + _sel_init(cur, obj, en); + efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST); + _sel_extend(cur, obj, en); +} + + static void _range_del_emit(Evas_Object *obj, Efl_Text_Cursor *cur1, Efl_Text_Cursor *cur2) { size_t start, end; char *tmp; - Efl_Ui_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; start = efl_text_cursor_position_get(cur1); end = efl_text_cursor_position_get(cur2); @@ -608,8 +885,7 @@ _range_del_emit(Evas_Object *obj, Efl_Text_Cursor *cur1, Efl_Text_Cursor *cur2) efl_text_cursor_range_delete(cur1, cur2); - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED_USER, &info); - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED, NULL); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); if (tmp) free(tmp); } @@ -621,26 +897,83 @@ _sel_range_del_emit(Evas_Object *obj, Efl_Ui_Internal_Text_Interactive_Data *en) } static void -_delete_emit(Eo *obj, Efl_Text_Cursor *c, Efl_Ui_Internal_Text_Interactive_Data *en EINA_UNUSED, size_t pos) +_delete_emit(Eo *obj, Efl_Text_Cursor *c, Efl_Ui_Internal_Text_Interactive_Data *en EINA_UNUSED, size_t pos, + Eina_Bool backspace) { - Efl_Ui_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; - Eina_Unicode content[2]; - content[0] = efl_text_cursor_content_get(c); - content[1] = 0; - if (!content[0]) - return; + Eo * cur = efl_duplicate(c); + if (backspace) + { + if (!efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHAR_PREV)) + { + return; + } + efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHAR_NEXT); + } + else + { + if (!efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHAR_NEXT)) + { + return; + } + efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHAR_PREV); + } + efl_unref(cur); + cur = NULL; - char *tmp = eina_unicode_unicode_to_utf8(content, NULL); + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + char *tmp = NULL; + info.insert = EINA_FALSE; + if (backspace) + { + + Evas_Textblock_Cursor *cc = evas_object_textblock_cursor_new(obj); + evas_textblock_cursor_copy(efl_text_cursor_handle_get(c), cc); + Eina_Bool remove_cluster = evas_textblock_cursor_at_cluster_as_single_glyph(cc,EINA_FALSE); + if (remove_cluster) + { + evas_textblock_cursor_cluster_prev(cc); + } + else + { + evas_textblock_cursor_char_prev(cc); + } + + info.position = evas_textblock_cursor_pos_get(cc); + info.length = pos -info.position; + + tmp = evas_textblock_cursor_range_text_get(efl_text_cursor_handle_get(c), cc, EVAS_TEXTBLOCK_TEXT_MARKUP); + evas_textblock_cursor_range_delete(efl_text_cursor_handle_get(c), cc); + evas_textblock_cursor_free(cc); + } + else + { + Evas_Textblock_Cursor *cc = evas_object_textblock_cursor_new(obj); + evas_textblock_cursor_copy(efl_text_cursor_handle_get(c), cc); + + Eina_Bool remove_cluster = evas_textblock_cursor_at_cluster_as_single_glyph(cc,EINA_TRUE); + if (remove_cluster) + { + evas_textblock_cursor_cluster_next(cc); + } + else + { + evas_textblock_cursor_char_next(cc); + } + + info.position = pos; + info.length = evas_textblock_cursor_pos_get(cc) - info.position; + + tmp = evas_textblock_cursor_range_text_get(efl_text_cursor_handle_get(c), cc, EVAS_TEXTBLOCK_TEXT_MARKUP); + evas_textblock_cursor_range_delete(efl_text_cursor_handle_get(c), cc); + evas_textblock_cursor_free(cc); + } info.insert = EINA_FALSE; info.position = pos; info.length = 1; info.content = tmp; - efl_text_cursor_char_delete(c); - - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED_USER, &info); - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED, NULL); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); if (tmp) free(tmp); } @@ -719,7 +1052,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void char *string = (char *)ev->string; Eina_Bool free_string = EINA_FALSE; Eina_Bool changed_user = EINA_FALSE; - Efl_Ui_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; if (!ev->key) return; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; @@ -729,6 +1062,25 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void /* FIXME: Maybe allow selctions to happen even when not editable. */ if (!en->editable) return; +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + { + Ecore_IMF_Event_Key_Down ecore_ev; + //FIXME + //ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); + if (!en->composing) + { + if (ecore_imf_context_filter_event(en->imf_context, + ECORE_IMF_EVENT_KEY_DOWN, + (Ecore_IMF_Event *)&ecore_ev)) + { + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return; + } + } + } +#endif + cur = efl_text_interactive_main_cursor_get(obj); old_cur_pos = efl_text_cursor_position_get(cur); if (old_cur_pos < 0) return; @@ -849,7 +1201,6 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void _range_del_emit(obj, cur, tc); - //efl_del(tc); efl_del(tc); } else if ((alt) && (shift)) @@ -864,10 +1215,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void } else { - if (efl_text_cursor_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHAR_PREV)) - { - _delete_emit(obj, cur, en, old_cur_pos - 1); - } + _delete_emit(obj, cur, en, old_cur_pos, EINA_TRUE); } } _sel_clear(obj, en); @@ -903,7 +1251,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void } else { - _delete_emit(obj, cur, en, old_cur_pos); + _delete_emit(obj, cur, en, old_cur_pos, EINA_FALSE); } } _sel_clear(obj, en); @@ -939,6 +1287,54 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void _key_down_sel_post(obj, cur, en, shift); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; } +#if defined(__APPLE__) && defined(__MACH__) + else if ((super) && (!strcmp(ev->keyname, "a"))) +#else + else if ((control) && (!strcmp(ev->keyname, "a"))) +#endif + { + _compose_seq_reset(en); + if (shift) + { + efl_text_interactive_all_unselect(obj); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + } + else + { + efl_text_interactive_all_select(obj); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + } + } +#if defined(__APPLE__) && defined(__MACH__) + else if ((super) && (!strcmp(ev->keyname, "z"))) +#else + else if ((control) && (!strcmp(ev->keyname, "z"))) +#endif + { + _compose_seq_reset(en); + if (shift) + { + // redo + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_REDO_REQUEST, NULL); + } + else + { + // undo + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_UNDO_REQUEST, NULL); + } + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + } +#if defined(__APPLE__) && defined(__MACH__) + else if ((super) && (!shift) && (!strcmp(ev->keyname, "y"))) +#else + else if ((control) && (!shift) && (!strcmp(ev->keyname, "y"))) +#endif + { + _compose_seq_reset(en); + // redo + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_REDO_REQUEST, NULL); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + } else if (shift && !strcmp(ev->key, "Tab")) { _compose_seq_reset(en); @@ -1064,9 +1460,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void end: if (changed_user) { - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED_USER, &info); - /* FIXME: this is kinda gross */ - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED, NULL); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); } (void) 0; } @@ -1213,9 +1607,6 @@ _mouse_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EIN } } - if (ev->button == 2) - { - } end: (void) 0; } @@ -1258,7 +1649,7 @@ _mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void en->selecting = EINA_FALSE; } - _entry_imf_cursor_info_set(obj, cur, en); + _entry_imf_cursor_info_set(en); } static void @@ -1349,8 +1740,6 @@ _efl_ui_internal_text_interactive_efl_object_finalize(Eo *obj, Efl_Ui_Internal_T efl_event_callback_add(efl_text_interactive_main_cursor_get(obj), EFL_TEXT_CURSOR_EVENT_CHANGED, _sel_cursor_changed, obj); - en->input_panel_enable = EINA_TRUE; - #ifdef HAVE_ECORE_IMF { const char *ctx_id; @@ -1416,10 +1805,33 @@ done: return efl_finalize(efl_super(obj, MY_CLASS)); } +EOLIAN static void +_efl_ui_internal_text_interactive_efl_text_text_set(Eo *eo_obj, Efl_Ui_Internal_Text_Interactive_Data *o, + const char *text) +{ + efl_text_set(efl_super(eo_obj, MY_CLASS), text); + efl_text_cursor_move(o->main_cursor, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST); +} + +EOLIAN void +_efl_ui_internal_text_interactive_efl_text_markup_markup_set(Eo *eo_obj, Efl_Ui_Internal_Text_Interactive_Data *o, + const char *text) +{ + efl_text_markup_set(efl_super(eo_obj, MY_CLASS), text); + efl_text_cursor_move(o->main_cursor, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST); +} + EOLIAN static void _efl_ui_internal_text_interactive_efl_text_interactive_selection_allowed_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *pd, Eina_Bool allowed) { + if (pd->select_allow == allowed) + return; + pd->select_allow = allowed; + if (!allowed) + { + _sel_clear(obj, pd); + } } EOLIAN static Eina_Bool @@ -1456,5 +1868,332 @@ _efl_ui_internal_text_interactive_efl_text_interactive_editable_get(const Eo *ob return sd->editable; } +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_hide(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_hide(en->imf_context); +#else + (void)en; +#endif +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_language_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Efl_Input_Text_Panel_Language_Type lang) +{ + en->input_panel_lang = lang; +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_language_set(en->imf_context, (Ecore_IMF_Input_Panel_Lang)lang); +#else + (void)en; + (void)lang; +#endif +} + + +EOLIAN static Efl_Input_Text_Panel_Language_Type +_efl_ui_internal_text_interactive_efl_input_text_input_panel_language_get(const Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + return en->input_panel_lang; + (void)obj; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_imdata_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Eina_Slice slice) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_imdata_set(en->imf_context, slice.mem, slice.len); +#else + (void)en; + (void)data; + (void)len; +#endif +} + + +EOLIAN static Eina_Slice +_efl_ui_internal_text_interactive_efl_input_text_input_panel_imdata_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + Eina_Slice slice = {0}; + +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + { + int len; + ecore_imf_context_input_panel_imdata_get(en->imf_context, &slice.mem, &len); + slice.len = (size_t)len; + } +#else + (void)en; + (void)data; + (void)len; +#endif + return slice; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_return_key_type_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Efl_Input_Text_Panel_Return_Key_Type return_key_type) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_return_key_type_set(en->imf_context, (Ecore_IMF_Input_Panel_Return_Key_Type)return_key_type); +#else + (void)en; + (void)return_key_type; +#endif +} + + +EOLIAN static Efl_Input_Text_Panel_Return_Key_Type +_efl_ui_internal_text_interactive_efl_input_text_input_panel_return_key_type_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + return (Efl_Input_Text_Panel_Return_Key_Type)ecore_imf_context_input_panel_return_key_type_get(en->imf_context); + return EFL_INPUT_TEXT_PANEL_RETURN_KEY_TYPE_DEFAULT; +#else + return EFL_INPUT_TEXT_PANEL_RETURN_KEY_TYPE_DEFAULT; + (void)en; +#endif +} + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_return_key_state_set(Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en, Efl_Input_Text_Panel_Return_Key_State state) +{ + if (en->input_panel_return_key_state == state) + return; + + en->input_panel_return_key_state = state; + +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + { + switch (state) + { + case EFL_INPUT_TEXT_PANEL_RETURN_KEY_STATE_ENABLED: + ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, EINA_TRUE); + break; + case EFL_INPUT_TEXT_PANEL_RETURN_KEY_STATE_DISABLED: + ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, EINA_FALSE); + break; + case EFL_INPUT_TEXT_PANEL_RETURN_KEY_STATE_AUTO: + _return_key_update(obj); + break; + default: + break; + } + } +#else + (void)obj; + (void)en; + (void)disabled; +#endif +} + + +EOLIAN static Efl_Input_Text_Panel_Return_Key_State +_efl_ui_internal_text_interactive_efl_input_text_input_panel_return_key_state_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + return en->input_panel_return_key_state; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_show_on_demand_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Eina_Bool ondemand) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_show_on_demand_set(en->imf_context, ondemand); +#else + (void)en; + (void)ondemand; +#endif +} + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_layout_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *sd, Efl_Input_Text_Panel_Layout_Type layout) +{ + sd->input_panel_layout = layout; + +#ifdef HAVE_ECORE_IMF + if (sd->imf_context) + ecore_imf_context_input_panel_layout_set(sd->imf_context, (Ecore_IMF_Input_Panel_Layout)layout); +#endif + + if (layout == EFL_INPUT_TEXT_PANEL_LAYOUT_TYPE_PASSWORD) + efl_input_text_input_hint_set(obj, ((sd->input_hints & ~EFL_INPUT_TEXT_HINTS_TYPE_AUTO_COMPLETE) | EFL_INPUT_TEXT_HINTS_TYPE_SENSITIVE_DATA)); + else if (layout == EFL_INPUT_TEXT_PANEL_LAYOUT_TYPE_TERMINAL) + efl_input_text_input_hint_set(obj, (sd->input_hints & ~EFL_INPUT_TEXT_HINTS_TYPE_AUTO_COMPLETE)); +} + +EOLIAN static Efl_Input_Text_Panel_Layout_Type +_efl_ui_internal_text_interactive_efl_input_text_input_panel_layout_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *sd) +{ + return sd->input_panel_layout; +} + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_layout_variation_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *sd, int variation) +{ + sd->input_panel_layout_variation = variation; + +#ifdef HAVE_ECORE_IMF + if (sd->imf_context) + ecore_imf_context_input_panel_layout_variation_set(sd->imf_context, variation); +#else + (void)variation; +#endif +} + +EOLIAN static int +_efl_ui_internal_text_interactive_efl_input_text_input_panel_layout_variation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *sd) +{ + return sd->input_panel_layout_variation; +} + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_show(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_show(en->imf_context); +#else + (void)en; +#endif +} + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_panel_autoshow_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Eina_Bool enabled) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled); +#else + (void)en; + (void)enabled; +#endif +} + +EOLIAN static Eina_Bool +_efl_ui_internal_text_interactive_efl_input_text_input_panel_autoshow_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + return ecore_imf_context_input_panel_enabled_get(en->imf_context); +#else + (void)en; +#endif + return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_internal_text_interactive_efl_input_text_input_panel_show_on_demand_get(const Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + { + Eina_Bool ret = ecore_imf_context_input_panel_show_on_demand_get(en->imf_context); + return ret; + } +#else + (void)en; +#endif + return EINA_FALSE; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_predictable_set(Eo *obj EINA_UNUSED, Efl_Ui_Internal_Text_Interactive_Data *en, Eina_Bool prediction) +{ + en->prediction_allow = prediction; +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_prediction_allow_set(en->imf_context, prediction); +#else + (void)en; + (void)prediction; +#endif +} + + +EOLIAN static Eina_Bool +_efl_ui_internal_text_interactive_efl_input_text_predictable_get(const Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) +{ + return en->prediction_allow; + (void)obj; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_input_hint_set(Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en, Efl_Input_Text_Hints_Type input_hints) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + ecore_imf_context_input_hint_set(en->imf_context, (Ecore_IMF_Input_Hints)input_hints); + (void)obj; +#else + (void)obj; + (void)en; + (void)input_hints; +#endif +} + + +EOLIAN static Efl_Input_Text_Hints_Type +_efl_ui_internal_text_interactive_efl_input_text_input_hint_get(const Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + return (Efl_Input_Text_Hints_Type)ecore_imf_context_input_hint_get(en->imf_context); + (void)obj; +#else + (void)obj; + (void)en; +#endif + + return ELM_INPUT_HINT_NONE; +} + + +EOLIAN static void +_efl_ui_internal_text_interactive_efl_input_text_autocapitalization_set(Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en, Efl_Input_Text_Capitalize_Type autocapital_type) +{ +#ifdef HAVE_ECORE_IMF + if (efl_text_password_get(obj) == EINA_TRUE) + autocapital_type = EFL_INPUT_TEXT_CAPITALIZE_TYPE_NONE; + + if (en->imf_context) + ecore_imf_context_autocapital_type_set(en->imf_context, (Ecore_IMF_Autocapital_Type)autocapital_type); + + (void)obj; +#else + (void)obj; + (void)en; + (void)autocapital_type; +#endif +} + + +EOLIAN static Efl_Input_Text_Capitalize_Type +_efl_ui_internal_text_interactive_efl_input_text_autocapitalization_get(const Eo *obj, Efl_Ui_Internal_Text_Interactive_Data *en) +{ +#ifdef HAVE_ECORE_IMF + if (en->imf_context) + return (Efl_Input_Text_Capitalize_Type)ecore_imf_context_autocapital_type_get(en->imf_context); + return EFL_INPUT_TEXT_CAPITALIZE_TYPE_NONE; + (void)obj; +#else + return EFL_INPUT_TEXT_CAPITALIZE_TYPE_NONE; + (void)obj; + (void)en; +#endif +} + #include "efl_ui_internal_text_interactive.eo.c" #include "efl_text_interactive.eo.c" diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.eo b/src/lib/elementary/efl_ui_internal_text_interactive.eo index 666cd83a0f..8c8a4cd1f1 100644 --- a/src/lib/elementary/efl_ui_internal_text_interactive.eo +++ b/src/lib/elementary/efl_ui_internal_text_interactive.eo @@ -1,4 +1,4 @@ -class @beta Efl.Ui.Internal.Text.Interactive extends Efl.Canvas.Text implements Efl.Text_Interactive +class @beta Efl.Ui.Internal.Text.Interactive extends Efl.Canvas.Text implements Efl.Text_Interactive, Efl.Input_Text { [[An internal object in charge of the interactive aspect of the text widget. @@ -11,6 +11,23 @@ class @beta Efl.Ui.Internal.Text.Interactive extends Efl.Canvas.Text implements Efl.Text_Interactive.selection_allowed { get; set; } Efl.Text_Interactive.selection_cursors { get; } Efl.Text_Interactive.editable { get; set; } - Efl.Text_Interactive.select_none; + Efl.Text_Interactive.all_unselect; + Efl.Text_Interactive.all_select; + Efl.Text_Interactive.have_selection {get; } + Efl.Text.text { set; } + Efl.Text_Markup.markup { set; } + Efl.Input_Text.input_panel_show_on_demand { get; set; } + Efl.Input_Text.input_panel_language { get; set; } + Efl.Input_Text.input_panel_layout_variation { get; set; } + Efl.Input_Text.autocapitalization { get; set; } + Efl.Input_Text.input_panel_return_key_state { get; set; } + Efl.Input_Text.predictable { get; set; } + Efl.Input_Text.input_hint { get; set; } + Efl.Input_Text.input_panel_layout { get; set; } + Efl.Input_Text.input_panel_return_key_type { get; set; } + Efl.Input_Text.input_panel_autoshow { get; set; } + Efl.Input_Text.input_panel_show; + Efl.Input_Text.input_panel_hide; + Efl.Input_Text.input_panel_imdata { get; set; } } } diff --git a/src/lib/elementary/efl_ui_tags.c b/src/lib/elementary/efl_ui_tags.c index 2a8fb8417a..9ce1f0166d 100644 --- a/src/lib/elementary/efl_ui_tags.c +++ b/src/lib/elementary/efl_ui_tags.c @@ -472,7 +472,7 @@ _mouse_clicked_signal_cb(void *data EINA_UNUSED, { Efl_Ui_Tags_Data *sd = efl_data_scope_get(obj, EFL_UI_TAGS_CLASS); - if (sd->editable) efl_ui_text_input_panel_show(sd->entry); + if (sd->editable) efl_input_text_input_panel_show(sd->entry); efl_event_callback_call(obj, EFL_INPUT_EVENT_CLICKED, NULL); } @@ -758,7 +758,7 @@ _view_init(Evas_Object *obj, Efl_Ui_Tags_Data *sd) efl_text_multiline_set(efl_added, EINA_FALSE), efl_text_set(efl_added, ""), efl_ui_text_cnp_mode_set(efl_added, EFL_UI_SELECTION_FORMAT_MARKUP), - efl_ui_text_input_panel_enabled_set(efl_added, EINA_FALSE), + efl_input_text_input_panel_autoshow_set(efl_added, EINA_FALSE), efl_text_interactive_editable_set(efl_added, EINA_TRUE), efl_composite_attach(obj, efl_added)); diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index 906984b4a0..e05c2edb94 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -73,15 +73,9 @@ struct _Efl_Ui_Text_Data int cursor_pos; Elm_Scroller_Policy policy_h, policy_v; Elm_Wrap_Type line_wrap; - Efl_Ui_Input_Panel_Layout input_panel_layout; - Efl_Ui_Autocapital_Type autocapital_type; - Efl_Ui_Input_Panel_Language_Type input_panel_lang; - Efl_Ui_Input_Panel_Return_Key_Type input_panel_return_key_type; - Efl_Ui_Input_Hints input_hints; Efl_Text_Cursor *sel_handler_cursor; void *input_panel_imdata; int input_panel_imdata_len; - int input_panel_layout_variation; int validators; struct { @@ -108,43 +102,23 @@ struct _Efl_Ui_Text_Data Eina_Future *primary; Eina_Future *clipboard; } sel_future; - Eina_Bool input_panel_return_key_disabled : 1; - Eina_Bool drag_selection_asked : 1; Eina_Bool sel_handler_disabled : 1; Eina_Bool start_handler_down : 1; Eina_Bool start_handler_shown : 1; Eina_Bool end_handler_down : 1; Eina_Bool end_handler_shown : 1; - Eina_Bool input_panel_enable : 1; - Eina_Bool prediction_allow : 1; - Eina_Bool selection_asked : 1; - Eina_Bool auto_return_key : 1; - Eina_Bool have_selection : 1; Eina_Bool deferred_decoration_selection : 1; Eina_Bool deferred_decoration_cursor : 1; Eina_Bool deferred_decoration_anchor : 1; Eina_Bool context_menu : 1; Eina_Bool long_pressed : 1; - Eina_Bool cur_changed : 1; - Eina_Bool single_line : 1; - Eina_Bool can_write : 1; Eina_Bool auto_save : 1; - Eina_Bool password : 1; - Eina_Bool editable : 1; // FIXME: This is redundant because of text interactive and should be removed - Eina_Bool disabled : 1; - Eina_Bool h_bounce : 1; - Eina_Bool v_bounce : 1; Eina_Bool has_text : 1; Eina_Bool use_down : 1; Eina_Bool sel_mode : 1; - Eina_Bool sel_allow : 1; Eina_Bool changed : 1; Eina_Bool scroll : 1; - Eina_Bool input_panel_show_on_demand : 1; - Eina_Bool anchors_updated : 1; - Eina_Bool fallback_item_provider_disabled : 1; Eina_Bool text_changed : 1; - Eina_Bool text_resized : 1; Eina_Bool calc_force : 1; Eina_Bool cursor_update : 1; }; @@ -211,7 +185,8 @@ struct _Selection_Loss_Data #define EFL_UI_TEXT_CHUNK_SIZE 10000 #define EFL_UI_TEXT_DELAY_WRITE_TIME 2.0 -#define ENTRY_PASSWORD_MASK_CHARACTER 0x002A +#define ENTRY_PASSWORD_MASK_CHARACTER 0x002A +#define ENTRY_PASSWORD_MASK_CHARACTER_UTF8 "\x2A" static Eina_List *entries = NULL; @@ -233,13 +208,13 @@ static void _update_decorations(Eo *obj); static void _create_text_cursors(Eo *obj, Efl_Ui_Text_Data *sd); static void _efl_ui_text_changed_cb(void *data, const Efl_Event *event); static void _efl_ui_text_changed_user_cb(void *data, const Efl_Event *event); +static void _efl_ui_text_selection_start_clear_cb(void *data, const Efl_Event *event); static void _efl_ui_text_selection_changed_cb(void *data, const Efl_Event *event); static void _efl_ui_text_cursor_changed_cb(void *data, const Efl_Event *event); static void _text_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED); static void _scroller_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED); static void _text_position_changed_cb(void *data, const Efl_Event *event EINA_UNUSED); static void _efl_ui_text_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); -static void _efl_ui_text_select_none(Eo *obj, Efl_Ui_Text_Data *sd); static const char* _efl_ui_text_selection_get(const Eo *obj, Efl_Ui_Text_Data *sd); static void _edje_signal_emit(Efl_Ui_Text_Data *obj, const char *sig, const char *src); static void _decoration_defer_all(Eo *obj); @@ -385,25 +360,6 @@ _efl_ui_text_guide_update(Evas_Object *obj, sd->has_text = has_text; } -static void -_validate(Evas_Object *obj) -{ - EFL_UI_TEXT_DATA_GET(obj, sd); - Eina_Bool res; - Efl_Ui_Validate_Content_Info vc; - Eina_Strbuf *buf; - - if (sd->validators == 0) return; - - vc.text = edje_object_part_text_get(sd->entry_edje, "efl.text"); - res = efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_VALIDATE, (void *)&vc); - buf = eina_strbuf_new(); - eina_strbuf_append_printf(buf, "validation,%s,%s", vc.signal, res == EINA_FALSE ? "fail" : "pass"); - edje_object_signal_emit(sd->scr_edje, eina_strbuf_string_get(buf), "efl"); - eina_tmpstr_del(vc.signal); - eina_strbuf_free(buf); -} - static void _filter_free(Elm_Entry_Markup_Filter *tf) { @@ -503,7 +459,7 @@ _update_selection_handler(Eo *obj) Evas_Coord sx, sy, sh; Evas_Coord ex, ey, eh; - if (!sd->have_selection) + if (!efl_text_interactive_have_selection_get(obj)) { _hide_selection_handler(obj); return; @@ -605,7 +561,7 @@ _selection_data_cb(void *data EINA_UNUSED, Eo *obj, Efl_Ui_Selection_Data *sel_data) { Efl_Text_Cursor *cur, *start, *end; - Efl_Ui_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; char *buf = eina_slice_strdup(sel_data->content); size_t len = sel_data->content.len; @@ -614,8 +570,7 @@ _selection_data_cb(void *data EINA_UNUSED, Eo *obj, if (!efl_text_cursor_equal(start, end)) { efl_text_cursor_range_delete(start, end); - EFL_UI_TEXT_DATA_GET(obj, sd); - _efl_ui_text_select_none(obj, sd); + efl_text_interactive_all_unselect(obj); } cur = efl_text_interactive_main_cursor_get(obj); info.insert = EINA_TRUE; @@ -630,7 +585,7 @@ _selection_data_cb(void *data EINA_UNUSED, Eo *obj, { efl_text_cursor_text_insert(cur, buf); } - efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_CHANGED_USER, &info); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); free(buf); } @@ -696,9 +651,7 @@ _dnd_drop_cb(void *data EINA_UNUSED, static Elm_Sel_Format _get_drop_format(Evas_Object *obj) { - EFL_UI_TEXT_DATA_GET(obj, sd); - - if ((sd->editable) && (!sd->single_line) && (!sd->password) && (!sd->disabled)) + if (efl_text_interactive_editable_get(obj) && (efl_text_multiline_get(obj)) && (!efl_text_password_get(obj)) && (!efl_ui_widget_disabled_get(obj))) return EFL_UI_SELECTION_FORMAT_MARKUP | EFL_UI_SELECTION_FORMAT_IMAGE; return EFL_UI_SELECTION_FORMAT_MARKUP; } @@ -724,7 +677,6 @@ _efl_ui_text_efl_ui_widget_disabled_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool edje_object_signal_emit(sd->scr_edje, emission, "efl"); elm_interface_scrollable_freeze_set(obj, efl_ui_widget_disabled_get(obj)); } - sd->disabled = efl_ui_widget_disabled_get(obj); if (!efl_ui_widget_disabled_get(obj)) { @@ -766,31 +718,6 @@ _efl_ui_text_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Text_Data *sd) elm_widget_element_update(obj, sd->entry_edje, elm_widget_theme_element_get(obj)); - if (elm_widget_disabled_get(obj)) - edje_object_signal_emit(sd->entry_edje, "efl,state,disabled", "efl"); - - edje_object_part_text_input_panel_layout_set - (sd->entry_edje, "efl.text", (Edje_Input_Panel_Layout)sd->input_panel_layout); - edje_object_part_text_input_panel_layout_variation_set - (sd->entry_edje, "efl.text", sd->input_panel_layout_variation); - edje_object_part_text_autocapital_type_set - (sd->entry_edje, "efl.text", (Edje_Text_Autocapital_Type)sd->autocapital_type); - edje_object_part_text_prediction_allow_set - (sd->entry_edje, "efl.text", sd->prediction_allow); - edje_object_part_text_input_hint_set - (sd->entry_edje, "efl.text", (Edje_Input_Hints)sd->input_hints); - edje_object_part_text_input_panel_enabled_set - (sd->entry_edje, "efl.text", sd->input_panel_enable); - edje_object_part_text_input_panel_imdata_set - (sd->entry_edje, "efl.text", sd->input_panel_imdata, - sd->input_panel_imdata_len); - edje_object_part_text_input_panel_return_key_type_set - (sd->entry_edje, "efl.text", (Edje_Input_Panel_Return_Key_Type)sd->input_panel_return_key_type); - edje_object_part_text_input_panel_return_key_disabled_set - (sd->entry_edje, "efl.text", sd->input_panel_return_key_disabled); - edje_object_part_text_input_panel_show_on_demand_set - (sd->entry_edje, "efl.text", sd->input_panel_show_on_demand); - // elm_entry_cursor_pos_set -> cursor,changed -> widget_show_region_set // -> smart_objects_calculate will call all smart calculate functions, // and one of them can delete elm_entry. @@ -835,7 +762,7 @@ _cursor_geometry_recalc(Evas_Object *obj) Evas_Coord cx, cy, cw, ch; Eina_Rect rc; - if (!sd->editable) return; + if (!efl_text_interactive_editable_get(obj)) return; cx = cy = cw = ch = 0; x2 = y2 = w2 = h2 = 0; @@ -882,8 +809,6 @@ _efl_ui_text_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Text_Data *sd) return; } - sd->single_line = !efl_text_multiline_get(sd->text_obj); - sd->calc_force = EINA_FALSE; sd->last.layout.w = sz.w; sd->last.layout.h = sz.h; @@ -891,7 +816,7 @@ _efl_ui_text_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Text_Data *sd) if (sd->scroll) { - if (sd->single_line) + if (!efl_text_multiline_get(obj)) { efl_ui_internal_text_scroller_mode_set(sd->scroller, EFL_UI_TEXT_SCROLLER_MODE_SINGLELINE); @@ -905,7 +830,7 @@ _efl_ui_text_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Text_Data *sd) efl_canvas_group_calculate(sd->scroller); min = efl_gfx_hint_size_min_get(sd->scroller); - if (sd->single_line) + if (!efl_text_multiline_get(obj)) { efl_ui_internal_text_scroller_mode_set(sd->scroller, EFL_UI_TEXT_SCROLLER_MODE_SINGLELINE); @@ -925,7 +850,7 @@ _efl_ui_text_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Text_Data *sd) efl_event_freeze(sd->text_obj); efl_gfx_entity_size_set(sd->text_obj, EINA_SIZE2D(sz.w, 0)); /* ignore current object size for single-line since we always need to know the actual size */ - if (sd->single_line) + if (!efl_text_multiline_get(obj)) min = efl_canvas_text_size_native_get(sd->text_obj); else min = efl_canvas_text_size_formatted_get(sd->text_obj); @@ -937,28 +862,13 @@ _efl_ui_text_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Text_Data *sd) } } -static void -_return_key_enabled_check(Evas_Object *obj) -{ - Eina_Bool return_key_disabled = EINA_FALSE; - - EFL_UI_TEXT_DATA_GET(obj, sd); - - if (!sd->auto_return_key) return; - - if (efl_canvas_text_is_empty_get(obj) == EINA_TRUE) - return_key_disabled = EINA_TRUE; - - efl_ui_text_input_panel_return_key_disabled_set(obj, return_key_disabled); -} - EOLIAN static Eina_Bool _efl_ui_text_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Text_Data *sd) { Evas_Object *top; Eina_Bool top_is_win = EINA_FALSE; - if (!sd->editable) return EINA_FALSE; + if (!efl_text_interactive_editable_get(obj)) return EINA_FALSE; top = elm_widget_top_get(obj); if (top && efl_isa(top, EFL_UI_WIN_CLASS)) @@ -972,12 +882,10 @@ _efl_ui_text_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Text_Data *sd) if (sd->scroll) edje_object_signal_emit(sd->scr_edje, "efl,action,focus", "efl"); - if (top && top_is_win && sd->input_panel_enable && !sd->input_panel_show_on_demand) + if (top && top_is_win && efl_input_text_input_panel_autoshow_get(obj) && !efl_input_text_input_panel_show_on_demand_get(obj)) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON); if (_elm_config->atspi_mode) efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, EINA_TRUE); - _return_key_enabled_check(obj); - _validate(obj); } else { @@ -988,14 +896,14 @@ _efl_ui_text_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Text_Data *sd) edje_object_signal_emit(sd->scr_edje, "efl,action,unfocus", "efl"); evas_object_focus_set(sw, EINA_FALSE); - if (top && top_is_win && sd->input_panel_enable) + if (top && top_is_win && efl_input_text_input_panel_autoshow_get(obj)) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF); if (_elm_config->atspi_mode) efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, EINA_FALSE); if (_elm_config->selection_clear_enable) { - if ((sd->have_selection) && (!sd->hoversel)) + if ((efl_text_interactive_have_selection_get(obj)) && (!sd->hoversel)) { sd->sel_mode = EINA_FALSE; elm_widget_scroll_hold_pop(obj); @@ -1019,7 +927,7 @@ _efl_ui_text_efl_ui_widget_interest_region_get(const Eo *obj EINA_UNUSED, Efl_Ui r = efl_text_cursor_geometry_get( efl_text_interactive_main_cursor_get(obj), EFL_TEXT_CURSOR_TYPE_BEFORE); - if (sd->single_line) + if (!efl_text_multiline_get(obj)) { evas_object_geometry_get(sd->entry_edje, NULL, NULL, NULL, &r.h); r.y = 0; @@ -1085,7 +993,7 @@ _hover_dismissed_cb(void *data, const Efl_Event *event EINA_UNUSED) { if (!_elm_config->desktop_entry) { - if (!sd->password) + if (!efl_text_password_get(data)) edje_object_part_text_select_allow_set (sd->entry_edje, "efl.text", EINA_TRUE); } @@ -1102,14 +1010,14 @@ _hover_selected_cb(void *data, { EFL_UI_TEXT_DATA_GET(data, sd); - if (!sd->sel_allow) return; + if (!efl_text_interactive_selection_allowed_get(obj)) return; sd->sel_mode = EINA_TRUE; edje_object_part_text_select_none(sd->entry_edje, "efl.text"); if (!_elm_config->desktop_entry) { - if (!sd->password) + if (!efl_text_password_get(data)) edje_object_part_text_select_allow_set (sd->entry_edje, "efl.text", EINA_TRUE); } @@ -1119,45 +1027,22 @@ _hover_selected_cb(void *data, elm_widget_scroll_hold_push(data); } -static void -_paste_cb(Eo *obj) -{ - Efl_Ui_Selection_Format formats = EFL_UI_SELECTION_FORMAT_TEXT | - EFL_UI_SELECTION_FORMAT_MARKUP; - - efl_ui_selection_get(obj, EFL_UI_SELECTION_TYPE_CLIPBOARD, formats, - NULL, _selection_data_cb, NULL, 1); - -} - static void _hoversel_item_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - _paste_cb(data); -} - -static void -_selection_clear(void *data, Efl_Ui_Selection_Type selection) -{ - EFL_UI_TEXT_DATA_GET(data, sd); - - if (!sd->have_selection) return; - if ((selection == EFL_UI_SELECTION_TYPE_CLIPBOARD) || - (selection == EFL_UI_SELECTION_TYPE_PRIMARY)) - { - _efl_ui_text_select_none(data, sd); - } - _selection_defer(data, sd); + efl_ui_text_selection_paste(data); } static Eina_Value _selection_lost_cb(void *data, const Eina_Value value) { Selection_Loss_Data *sdata = data; - _selection_clear(sdata->obj, sdata->stype); - EFL_UI_TEXT_DATA_GET(sdata->obj, sd); + EFL_UI_TEXT_DATA_GET(sdata->obj, sd); + + efl_text_interactive_all_unselect(sdata->obj); + _selection_defer(sdata->obj, sd); switch (sdata->stype) { case EFL_UI_SELECTION_TYPE_CLIPBOARD: @@ -1230,52 +1115,12 @@ end: free(sel); } -static void -_cut_cb(Eo *obj) -{ - Efl_Text_Cursor *start, *end; - EFL_UI_TEXT_DATA_GET(obj, sd); - - efl_event_callback_call(obj, EFL_UI_EVENT_SELECTION_CUT, NULL); - /* Store it */ - sd->sel_mode = EINA_FALSE; - if (!_elm_config->desktop_entry) - edje_object_part_text_select_allow_set - (sd->entry_edje, "efl.text", EINA_FALSE); - edje_object_signal_emit(sd->entry_edje, "efl,state,select,off", "efl"); - - if (!_elm_config->desktop_entry) - elm_widget_scroll_hold_pop(obj); - - _selection_store(EFL_UI_SELECTION_TYPE_CLIPBOARD, obj); - efl_text_interactive_selection_cursors_get(obj, &start, &end); - efl_text_cursor_range_delete(start, end); - _efl_ui_text_select_none(obj, sd); -} - static void _hoversel_item_cut_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - _cut_cb(data); -} - -static void -_copy_cb(Eo *obj) -{ - EFL_UI_TEXT_DATA_GET(obj, sd); - - efl_event_callback_call(obj, EFL_UI_EVENT_SELECTION_COPY, NULL); - sd->sel_mode = EINA_FALSE; - if (!_elm_config->desktop_entry) - { - edje_object_part_text_select_allow_set - (sd->entry_edje, "efl.text", EINA_FALSE); - edje_object_signal_emit(sd->entry_edje, "efl,state,select,off", "efl"); - elm_widget_scroll_hold_pop(obj); - } - _selection_store(EFL_UI_SELECTION_TYPE_CLIPBOARD, obj); + efl_ui_text_selection_cut(data); } static void @@ -1283,7 +1128,7 @@ _hoversel_item_copy_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - _copy_cb(data); + efl_ui_text_selection_copy(data); } static void @@ -1340,8 +1185,8 @@ _menu_call(Evas_Object *obj) if (!sd->items) { /* prevent stupid blank hoversel */ - if (sd->have_selection && sd->password) return; - if (_elm_config->desktop_entry && (!sd->have_selection) && ((!sd->editable) || (!ownersel))) + if (efl_text_interactive_have_selection_get(obj) && efl_text_password_get(obj)) return; + if (_elm_config->desktop_entry && (!efl_text_interactive_have_selection_get(obj)) && ((!efl_text_interactive_editable_get(obj)) || (!ownersel))) return; } if (sd->hoversel) evas_object_del(sd->hoversel); @@ -1364,18 +1209,18 @@ _menu_call(Evas_Object *obj) efl_event_callback_add (sd->hoversel, ELM_HOVERSEL_EVENT_DISMISSED, _hover_dismissed_cb, obj); - if (sd->have_selection) + if (efl_text_interactive_have_selection_get(obj)) { - if (!sd->password) + if (!efl_text_password_get(obj)) { - if (sd->editable) + if (efl_text_interactive_editable_get(obj)) elm_hoversel_item_add (sd->hoversel, E_("Cut"), NULL, ELM_ICON_NONE, _hoversel_item_cut_cb, obj); elm_hoversel_item_add (sd->hoversel, E_("Copy"), NULL, ELM_ICON_NONE, _hoversel_item_copy_cb, obj); - if (sd->editable && ownersel) + if (efl_text_interactive_editable_get(obj) && ownersel) elm_hoversel_item_add (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE, _hoversel_item_paste_cb, obj); @@ -1388,16 +1233,16 @@ _menu_call(Evas_Object *obj) { if (!sd->sel_mode) { - if (sd->sel_allow && !_elm_config->desktop_entry) + if (efl_text_interactive_selection_allowed_get(obj) && !_elm_config->desktop_entry) { - if (!sd->password) + if (!efl_text_password_get(obj)) elm_hoversel_item_add (sd->hoversel, E_("Select"), NULL, ELM_ICON_NONE, _hover_selected_cb, obj); } if (ownersel) { - if (sd->editable) + if (efl_text_interactive_editable_get(obj)) elm_hoversel_item_add (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE, _hoversel_item_paste_cb, obj); @@ -1474,17 +1319,17 @@ _key_down_cb(void *data, { if (!strncmp(ev->key, "c", 1)) { - _copy_cb(data); + efl_ui_text_selection_copy(data); on_hold = EINA_TRUE; } else if (!strncmp(ev->key, "x", 1)) { - _cut_cb(data); + efl_ui_text_selection_cut(data); on_hold = EINA_TRUE; } else if (!strncmp(ev->key, "v", 1)) { - _paste_cb(data); + efl_ui_text_selection_paste(data); on_hold = EINA_TRUE; } } @@ -1503,12 +1348,18 @@ _mouse_down_cb(void *data, EFL_UI_TEXT_DATA_GET(data, sd); - if (sd->disabled) return; + if (efl_ui_widget_disabled_get(data)) return; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; sd->downx = ev->canvas.x; sd->downy = ev->canvas.y; sd->long_pressed = EINA_FALSE; + + if (ev->button == 2) + { + efl_ui_text_selection_paste(data); + } + /* If right button is pressed and context menu disabled is true, * then only context menu will appear */ if (ev->button == 3 && (!_elm_config->context_menu_disabled)) @@ -1533,7 +1384,7 @@ _mouse_up_cb(void *data, EFL_UI_TEXT_DATA_GET(data, sd); - if (sd->disabled) return; + if (efl_ui_widget_disabled_get(data)) return; if (ev->button == 1) { efl_input_clickable_longpress_abort(data, 1); @@ -1556,7 +1407,7 @@ _mouse_up_cb(void *data, if (efl_isa(top, EFL_UI_WIN_CLASS)) top_is_win = EINA_TRUE; - if (top_is_win && sd->input_panel_enable && sd->input_panel_show_on_demand) + if (top_is_win && efl_input_text_input_panel_autoshow_get(data) && efl_input_text_input_panel_show_on_demand_get(data)) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON); } } @@ -1582,7 +1433,7 @@ _mouse_move_cb(void *data, EFL_UI_TEXT_DATA_GET(data, sd); - if (sd->disabled) return; + if (efl_ui_widget_disabled_get(data)) return; if (ev->buttons == 1) { if (sd->long_pressed) @@ -1953,30 +1804,6 @@ _efl_ui_text_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Text_Data *sd, Ev evas_object_raise(sd->hit_rect); } -static void -_cb_added(void *data EINA_UNUSED, const Efl_Event *ev) -{ - const Efl_Callback_Array_Item_Full *event = ev->info; - - EFL_UI_TEXT_DATA_GET(ev->object, sd); - // XXX: BUG - not walking the array until a NULL entry - if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) - sd->validators++; -} - -static void -_cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev) -{ - const Efl_Callback_Array_Item_Full *event = ev->info; - - EFL_UI_TEXT_DATA_GET(ev->object, sd); - // XXX: BUG - not walking the array until a NULL entry - if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) - sd->validators--; - return; - -} - static void _update_guide_text(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) { @@ -2133,9 +1960,12 @@ _efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *sd) efl_event_callback_add(obj, EFL_INPUT_EVENT_LONGPRESSED, _long_press_cb, obj); text_obj = efl_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj); - efl_event_callback_forwarder_add(text_obj, EFL_UI_TEXT_EVENT_CHANGED_USER, obj); - efl_event_callback_forwarder_add(text_obj, EFL_UI_TEXT_EVENT_CHANGED, obj); - efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_TEXT_SELECTION_CHANGED, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_REDO_REQUEST, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_UNDO_REQUEST, obj); + efl_event_callback_forwarder_add(text_obj, EFL_TEXT_INTERACTIVE_EVENT_PREEDIT_CHANGED, obj); sd->text_obj = text_obj; sd->text_guide_obj = efl_add(EFL_CANVAS_TEXT_CLASS, obj); sd->text_table = efl_add(EFL_UI_TABLE_CLASS, obj); @@ -2146,8 +1976,8 @@ _efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *sd) sd->line_wrap = ELM_WRAP_WORD; sd->context_menu = EINA_TRUE; sd->auto_save = EINA_TRUE; - sd->editable = EINA_TRUE; - sd->sel_allow = EINA_TRUE; + efl_text_interactive_editable_set(obj, EINA_TRUE); + efl_text_interactive_selection_allowed_set(obj, EINA_TRUE); sd->drop_format = EFL_UI_SELECTION_FORMAT_MARKUP | EFL_UI_SELECTION_FORMAT_IMAGE; sd->last.scroll = EINA_SIZE2D(0, 0); sd->sel_handler_disabled = EINA_TRUE; @@ -2176,13 +2006,10 @@ _efl_ui_text_efl_object_finalize(Eo *obj, CRI("Failed to set layout!"); efl_access_object_role_set(obj, EFL_ACCESS_ROLE_ENTRY); - efl_event_callback_add(obj, EFL_EVENT_CALLBACK_ADD, _cb_added, NULL); - efl_event_callback_add(obj, EFL_EVENT_CALLBACK_DEL, _cb_deleted, NULL); //TODO: complete the usage of the text theme _update_text_theme(obj, sd); //efl_text_font_set(sd->text_obj, "Sans", 12); - sd->single_line = !efl_text_multiline_get(sd->text_obj); efl_pack_table(sd->text_table, sd->text_obj, 0, 0, 1, 1); efl_pack_table(sd->text_table, sd->text_guide_obj, 0, 0, 1, 1); @@ -2199,11 +2026,13 @@ _efl_ui_text_efl_object_finalize(Eo *obj, (sd->entry_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set (sd->entry_edje, EVAS_HINT_FILL, EVAS_HINT_FILL); - efl_event_callback_add(sd->text_obj, EFL_UI_TEXT_EVENT_CHANGED_USER, + efl_event_callback_add(sd->text_obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, _efl_ui_text_changed_user_cb, obj); efl_event_callback_add(sd->text_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, _efl_ui_text_changed_cb, obj); - efl_event_callback_add(sd->text_obj, EFL_TEXT_INTERACTIVE_EVENT_TEXT_SELECTION_CHANGED, + efl_event_callback_add(sd->text_obj, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, + _efl_ui_text_selection_start_clear_cb, obj); + efl_event_callback_add(sd->text_obj, EFL_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED, _efl_ui_text_selection_changed_cb, obj); efl_event_callback_add(efl_text_interactive_main_cursor_get(sd->text_obj), EFL_TEXT_CURSOR_EVENT_CHANGED, _efl_ui_text_cursor_changed_cb, obj); @@ -2225,12 +2054,12 @@ _efl_ui_text_efl_object_finalize(Eo *obj, efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _text_size_changed_cb, obj); - efl_ui_widget_focus_allow_set(obj, sd->editable); + efl_ui_widget_focus_allow_set(obj, efl_text_interactive_editable_get(obj)); - efl_ui_text_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL); - efl_ui_text_input_panel_enabled_set(obj, EINA_TRUE); - efl_ui_text_prediction_allow_set(obj, EINA_TRUE); - efl_ui_text_input_hint_set(obj, ELM_INPUT_HINT_AUTO_COMPLETE); + efl_input_text_input_panel_layout_set(obj, EFL_INPUT_TEXT_PANEL_LAYOUT_TYPE_NORMAL); + efl_input_text_input_panel_autoshow_set(obj, EINA_TRUE); + efl_input_text_predictable_set(obj, EINA_TRUE); + efl_input_text_input_hint_set(obj, EFL_INPUT_TEXT_HINTS_TYPE_AUTO_COMPLETE); _mirrored_set(obj, efl_ui_mirrored_get(obj)); @@ -2311,12 +2140,14 @@ _efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd) } EOLIAN static void -_efl_ui_text_password_mode_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool password) +_efl_ui_text_efl_text_format_password_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool password) { password = !!password; - if (sd->password == password) return; - sd->password = password; + if (efl_text_password_get(obj) == password) return; + if (!efl_text_replacement_char_get(obj)) + efl_text_replacement_char_set(obj, ENTRY_PASSWORD_MASK_CHARACTER_UTF8); + efl_text_password_set(sd->text_obj, password); elm_drop_target_del(obj, sd->drop_format, _dnd_enter_cb, NULL, @@ -2325,33 +2156,27 @@ _efl_ui_text_password_mode_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool password _dnd_drop_cb, NULL); if (password) { - sd->single_line = EINA_TRUE; + efl_text_multiline_set(obj, EINA_FALSE); sd->line_wrap = ELM_WRAP_NONE; - efl_ui_text_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA)); + efl_input_text_input_hint_set(obj, ((efl_input_text_input_hint_get(obj) & ~EFL_INPUT_TEXT_HINTS_TYPE_AUTO_COMPLETE) | EFL_INPUT_TEXT_HINTS_TYPE_SENSITIVE_DATA)); efl_access_object_role_set(obj, EFL_ACCESS_ROLE_PASSWORD_TEXT); } else { + efl_text_multiline_set(obj, EINA_TRUE); sd->drop_format = _get_drop_format(obj); elm_drop_target_add(obj, sd->drop_format, _dnd_enter_cb, NULL, _dnd_leave_cb, NULL, _dnd_pos_cb, NULL, _dnd_drop_cb, NULL); - - efl_ui_text_input_hint_set(obj, ((sd->input_hints | ELM_INPUT_HINT_AUTO_COMPLETE) & ~ELM_INPUT_HINT_SENSITIVE_DATA)); + efl_input_text_input_hint_set(obj, ((efl_input_text_input_hint_get(obj) | EFL_INPUT_TEXT_HINTS_TYPE_AUTO_COMPLETE) & ~EFL_INPUT_TEXT_HINTS_TYPE_SENSITIVE_DATA)); efl_access_object_role_set(obj, EFL_ACCESS_ROLE_ENTRY); } efl_ui_widget_theme_apply(obj); } -EOLIAN static Eina_Bool -_efl_ui_text_password_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->password; -} - static void _efl_ui_text_calc_force(Eo *obj, Efl_Ui_Text_Data *sd) { @@ -2361,11 +2186,11 @@ _efl_ui_text_calc_force(Eo *obj, Efl_Ui_Text_Data *sd) } static const char* -_efl_ui_text_selection_get(const Eo *obj, Efl_Ui_Text_Data *sd) +_efl_ui_text_selection_get(const Eo *obj, Efl_Ui_Text_Data *sd EINA_UNUSED) { Efl_Text_Cursor *start_obj, *end_obj; - if ((sd->password)) return NULL; + if ((efl_text_password_get(obj))) return NULL; efl_text_interactive_selection_cursors_get(obj, &start_obj, &end_obj); return efl_text_cursor_range_text_get(start_obj, end_obj); @@ -2410,9 +2235,10 @@ _efl_ui_text_cursor_create(Eo *obj, Efl_Ui_Text_Data *pd) EOLIAN static void _efl_ui_text_efl_text_interactive_editable_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool editable) { + if (efl_text_interactive_editable_get(obj) == editable) return; + efl_text_interactive_editable_set(efl_super(obj, MY_CLASS), editable); - if (sd->editable == editable) return; - sd->editable = editable; + efl_ui_widget_theme_apply(obj); efl_ui_widget_focus_allow_set(obj, editable); @@ -2443,33 +2269,11 @@ _efl_ui_text_efl_text_interactive_editable_set(Eo *obj, Efl_Ui_Text_Data *sd, Ei } static void -_efl_ui_text_select_none(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - if ((sd->password)) return; - if (sd->sel_mode) - { - sd->sel_mode = EINA_FALSE; - if (!_elm_config->desktop_entry) - edje_object_part_text_select_allow_set - (sd->entry_edje, "efl.text", EINA_FALSE); - edje_object_signal_emit(sd->entry_edje, "efl,state,select,off", "efl"); - } - if (sd->have_selection) - efl_event_callback_call(obj, EFL_UI_EVENT_SELECTION_CLEARED, NULL); - - sd->have_selection = EINA_FALSE; - _edje_signal_emit(sd, "selection,cleared", "efl.text"); - efl_text_interactive_select_none(sd->text_obj); - - _hide_selection_handler(obj); -} - -static void -_efl_ui_text_select_region_set(Eo *obj, Efl_Ui_Text_Data *sd, int start, int end) +_efl_ui_text_select_region_set(Eo *obj, Efl_Ui_Text_Data *sd EINA_UNUSED, int start, int end) { Efl_Text_Cursor *sel_start, *sel_end; - if ((sd->password)) return; + if (efl_text_password_get(obj)) return; efl_text_interactive_selection_cursors_get(obj, &sel_start, &sel_end); @@ -2477,62 +2281,71 @@ _efl_ui_text_select_region_set(Eo *obj, Efl_Ui_Text_Data *sd, int start, int end efl_text_cursor_position_set(sel_end, end); } -EOLIAN static void -_efl_ui_text_cursor_selection_end(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - edje_object_part_text_select_extend(sd->entry_edje, "efl.text"); -} - EOLIAN static void _efl_ui_text_selection_cut(Eo *obj, Efl_Ui_Text_Data *sd) { - if ((sd->password)) return; - _cut_cb(obj); + Efl_Text_Cursor *start, *end; + Efl_Text_Change_Info info = { NULL, 0, 0, 0, 0 }; + char *tmp; + int end_pos, start_pos; + + /* Store it */ + sd->sel_mode = EINA_FALSE; + if (!_elm_config->desktop_entry) + edje_object_part_text_select_allow_set + (sd->entry_edje, "efl.text", EINA_FALSE); + edje_object_signal_emit(sd->entry_edje, "efl,state,select,off", "efl"); + + if (!_elm_config->desktop_entry) + elm_widget_scroll_hold_pop(obj); + + /*In password mode, cut will remove text only*/ + if (!efl_text_password_get(obj)) + _selection_store(EFL_UI_SELECTION_TYPE_CLIPBOARD, obj); + efl_text_interactive_selection_cursors_get(obj, &start, &end); + + start_pos = efl_text_cursor_position_get(start); + end_pos = efl_text_cursor_position_get(end); + tmp = efl_text_cursor_range_text_get(start, end); + info.insert = EINA_FALSE; + info.position = start_pos; + info.length = end_pos - start_pos; + info.content = tmp; + efl_text_cursor_range_delete(start, end); + efl_event_callback_call(obj, EFL_TEXT_INTERACTIVE_EVENT_CHANGED_USER, &info); + free(tmp); + tmp = NULL; + efl_text_interactive_all_unselect(obj); + + efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_SELECTION_CUT, NULL); } EOLIAN static void _efl_ui_text_selection_copy(Eo *obj, Efl_Ui_Text_Data *sd) { - if ((sd->password)) return; - _copy_cb(obj); -} + if (efl_text_password_get(obj)) return; -EOLIAN static void -_efl_ui_text_selection_paste(Eo *obj, Efl_Ui_Text_Data *sd) -{ - if ((sd->password)) return; - _paste_cb(obj); -} - -EOLIAN static void -_efl_ui_text_context_menu_clear(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - Elm_Entry_Context_Menu_Item *it; - - EINA_LIST_FREE(sd->items, it) + sd->sel_mode = EINA_FALSE; + if (!_elm_config->desktop_entry) { - eina_stringshare_del(it->label); - eina_stringshare_del(it->icon_file); - eina_stringshare_del(it->icon_group); - free(it); + edje_object_part_text_select_allow_set + (sd->entry_edje, "efl.text", EINA_FALSE); + edje_object_signal_emit(sd->entry_edje, "efl,state,select,off", "efl"); + elm_widget_scroll_hold_pop(obj); } + _selection_store(EFL_UI_SELECTION_TYPE_CLIPBOARD, obj); + efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_SELECTION_COPY, NULL); } EOLIAN static void -_efl_ui_text_context_menu_item_add(Eo *obj, Efl_Ui_Text_Data *sd, const char *label, const char *icon_file, Efl_Ui_Icon_Type icon_type, Context_Item_Clicked_Cb func, const void *data) +_efl_ui_text_selection_paste(Eo *obj, Efl_Ui_Text_Data *sd EINA_UNUSED) { - Elm_Entry_Context_Menu_Item *it; + Efl_Ui_Selection_Format formats = EFL_UI_SELECTION_FORMAT_TEXT | EFL_UI_SELECTION_FORMAT_MARKUP; - it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item)); - if (!it) return; + efl_ui_selection_get(obj, EFL_UI_SELECTION_TYPE_CLIPBOARD, formats, + NULL, _selection_data_cb, NULL, 1); - sd->items = eina_list_append(sd->items, it); - it->obj = obj; - it->label = eina_stringshare_add(label); - it->icon_file = eina_stringshare_add(icon_file); - it->icon_type = (Elm_Icon_Type)icon_type; - it->func = func; - it->data = (void *)data; + efl_event_callback_call(obj, EFL_UI_TEXT_EVENT_SELECTION_PASTE, NULL); } EOLIAN static void @@ -2652,198 +2465,6 @@ _efl_ui_text_scrollable_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) return sd->scroll; } -EOLIAN static void -_efl_ui_text_input_panel_layout_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Efl_Ui_Input_Panel_Layout layout) -{ - sd->input_panel_layout = layout; - - edje_object_part_text_input_panel_layout_set - (sd->entry_edje, "efl.text", (Edje_Input_Panel_Layout)layout); - - if (layout == EFL_UI_INPUT_PANEL_LAYOUT_PASSWORD) - efl_ui_text_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA)); - else if (layout == EFL_UI_INPUT_PANEL_LAYOUT_TERMINAL) - efl_ui_text_input_hint_set(obj, (sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE)); -} - -EOLIAN static Efl_Ui_Input_Panel_Layout -_efl_ui_text_input_panel_layout_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_layout; -} - -EOLIAN static void -_efl_ui_text_input_panel_layout_variation_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, int variation) -{ - sd->input_panel_layout_variation = variation; - - edje_object_part_text_input_panel_layout_variation_set - (sd->entry_edje, "efl.text", variation); -} - -EOLIAN static int -_efl_ui_text_input_panel_layout_variation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_layout_variation; -} - -EOLIAN static void -_efl_ui_text_autocapital_type_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Efl_Ui_Autocapital_Type autocapital_type) -{ - sd->autocapital_type = autocapital_type; - edje_object_part_text_autocapital_type_set - (sd->entry_edje, "efl.text", (Edje_Text_Autocapital_Type)autocapital_type); -} - -EOLIAN static Efl_Ui_Autocapital_Type -_efl_ui_text_autocapital_type_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->autocapital_type; -} - -EOLIAN static void -_efl_ui_text_prediction_allow_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool prediction) -{ - sd->prediction_allow = prediction; - edje_object_part_text_prediction_allow_set - (sd->entry_edje, "efl.text", prediction); -} - -EOLIAN static Eina_Bool -_efl_ui_text_prediction_allow_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->prediction_allow; -} - -EOLIAN static void -_efl_ui_text_input_hint_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Efl_Ui_Input_Hints hints) -{ - sd->input_hints = hints; - - edje_object_part_text_input_hint_set - (sd->entry_edje, "efl.text", (Edje_Input_Hints)hints); -} - -EOLIAN static Efl_Ui_Input_Hints -_efl_ui_text_input_hint_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_hints; -} - -EOLIAN static void -_efl_ui_text_input_panel_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool enabled) -{ - sd->input_panel_enable = enabled; - edje_object_part_text_input_panel_enabled_set - (sd->entry_edje, "efl.text", enabled); -} - -EOLIAN static Eina_Bool -_efl_ui_text_input_panel_enabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_enable; -} - -EOLIAN static void -_efl_ui_text_input_panel_show(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - edje_object_part_text_input_panel_show(sd->entry_edje, "efl.text"); -} - -EOLIAN static void -_efl_ui_text_input_panel_hide(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - - edje_object_part_text_input_panel_hide(sd->entry_edje, "efl.text"); -} - -EOLIAN static void -_efl_ui_text_input_panel_language_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Efl_Ui_Input_Panel_Language_Type lang) -{ - sd->input_panel_lang = lang; - edje_object_part_text_input_panel_language_set - (sd->entry_edje, "efl.text", (Edje_Input_Panel_Lang)lang); -} - -EOLIAN static Efl_Ui_Input_Panel_Language_Type -_efl_ui_text_input_panel_language_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_lang; -} - -EOLIAN static void -_efl_ui_text_input_panel_imdata_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, const void *data, int len) -{ - free(sd->input_panel_imdata); - - sd->input_panel_imdata = calloc(1, len); - sd->input_panel_imdata_len = len; - memcpy(sd->input_panel_imdata, data, len); - - edje_object_part_text_input_panel_imdata_set - (sd->entry_edje, "efl.text", sd->input_panel_imdata, - sd->input_panel_imdata_len); -} - -EOLIAN static void -_efl_ui_text_input_panel_imdata_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, void *data, int *len) -{ - edje_object_part_text_input_panel_imdata_get - (sd->entry_edje, "efl.text", data, len); -} - -EOLIAN static void -_efl_ui_text_input_panel_return_key_type_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Efl_Ui_Input_Panel_Return_Key_Type return_key_type) -{ - sd->input_panel_return_key_type = return_key_type; - - edje_object_part_text_input_panel_return_key_type_set - (sd->entry_edje, "efl.text", (Edje_Input_Panel_Return_Key_Type)return_key_type); -} - -EOLIAN static Efl_Ui_Input_Panel_Return_Key_Type -_efl_ui_text_input_panel_return_key_type_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_return_key_type; -} - -EOLIAN static void -_efl_ui_text_input_panel_return_key_disabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool disabled) -{ - sd->input_panel_return_key_disabled = disabled; - - edje_object_part_text_input_panel_return_key_disabled_set - (sd->entry_edje, "efl.text", disabled); -} - -EOLIAN static Eina_Bool -_efl_ui_text_input_panel_return_key_disabled_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_return_key_disabled; -} - -EOLIAN static void -_efl_ui_text_input_panel_return_key_autoenabled_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool enabled) -{ - sd->auto_return_key = enabled; - _return_key_enabled_check(obj); -} - -EOLIAN static void -_efl_ui_text_input_panel_show_on_demand_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool ondemand) -{ - sd->input_panel_show_on_demand = ondemand; - - edje_object_part_text_input_panel_show_on_demand_set - (sd->entry_edje, "efl.text", ondemand); -} - -EOLIAN static Eina_Bool -_efl_ui_text_input_panel_show_on_demand_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd) -{ - return sd->input_panel_show_on_demand; -} - EOLIAN static Eina_Bool _efl_ui_text_efl_ui_widget_on_access_activate(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Efl_Ui_Activate act) { @@ -2855,7 +2476,7 @@ _efl_ui_text_efl_ui_widget_on_access_activate(Eo *obj, Efl_Ui_Text_Data *_pd EIN !evas_object_freeze_events_get(obj)) { efl_event_callback_call(obj, EFL_INPUT_EVENT_CLICKED, NULL); - if (sd->editable && sd->input_panel_enable) + if (efl_text_interactive_editable_get(obj) && efl_input_text_input_panel_autoshow_get(obj)) edje_object_part_text_input_panel_show(sd->entry_edje, "efl.text"); } return EINA_TRUE; @@ -2871,7 +2492,7 @@ _efl_ui_text_efl_access_text_character_get(const Eo *obj, Efl_Ui_Text_Data *_pd Eina_Unicode ret = 0; if (offset < 0) return ret; - if (_pd->password) return ENTRY_PASSWORD_MASK_CHARACTER; + if (efl_text_password_get(obj)) return ENTRY_PASSWORD_MASK_CHARACTER; txt = efl_text_get(obj); if (!txt) return ret; @@ -2956,7 +2577,7 @@ _efl_ui_text_efl_access_text_string_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_D evas_textblock_cursor_free(cur); evas_textblock_cursor_free(cur2); - if (ret && pd->password) + if (ret && efl_text_password_get(obj)) { int i = 0; while (ret[i] != '\0') @@ -2995,7 +2616,7 @@ _efl_ui_text_efl_access_text_access_text_get(const Eo *obj EINA_UNUSED, Efl_Ui_T evas_textblock_cursor_free(cur); evas_textblock_cursor_free(cur2); - if (ret && pd->password) + if (ret && efl_text_password_get(obj)) { int i = 0; while (ret[i] != '\0') @@ -3051,7 +2672,7 @@ EOLIAN static Eina_Bool _efl_ui_text_efl_access_text_selection_remove(Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED, int selection_number) { if (selection_number != 0) return EINA_FALSE; - _efl_ui_text_select_none(obj, pd); + efl_text_interactive_all_unselect(obj); return EINA_TRUE; } @@ -3714,8 +3335,6 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd) if (!sd->deferred_decoration_anchor) return; sd->deferred_decoration_anchor = EINA_FALSE; - if (sd->anchors_updated) return; - sd->gen++; start = efl_canvas_text_cursor_create(sd->text_obj); @@ -3933,7 +3552,7 @@ _efl_ui_text_changed_cb(void *data, const Efl_Event *event) sd->text_changed = EINA_TRUE; sd->cursor_update = EINA_TRUE; _update_guide_text(data, sd); - efl_event_callback_call(event->object, EFL_UI_TEXT_EVENT_CHANGED, NULL); + efl_event_callback_call(data, EFL_UI_TEXT_EVENT_CHANGED, NULL); efl_canvas_group_change(data); _decoration_defer(data); } @@ -3956,7 +3575,6 @@ _efl_ui_text_cursor_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) { if (efl_invalidated_get(event->object)) return; EFL_UI_TEXT_DATA_GET(data, sd); - sd->cur_changed = EINA_TRUE; sd->cursor_update = EINA_TRUE; sd->deferred_decoration_cursor = EINA_TRUE; _decoration_defer(data); @@ -3986,35 +3604,35 @@ _text_position_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) _decoration_defer_all(data); } +static void +_efl_ui_text_selection_start_clear_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + if (efl_invalidated_get(event->object)) return; + Eo *obj = data; + EFL_UI_TEXT_DATA_GET(obj, sd); + + if (efl_text_interactive_have_selection_get(data)) + { + if (efl_invalidated_get(event->object)) return; + _edje_signal_emit(sd, "selection,start", "efl.text"); + _selection_defer(obj, sd); + } + else + { + Eo *obj = data; + _edje_signal_emit(sd, "selection,cleared", "efl.text"); + _selection_defer(obj, sd); + } +} + static void _efl_ui_text_selection_changed_cb(void *data, const Efl_Event *event EINA_UNUSED) { if (efl_invalidated_get(event->object)) return; Eo *obj = data; - Efl_Text_Cursor *start, *end; - char *text; EFL_UI_TEXT_DATA_GET(obj, sd); - - efl_text_interactive_selection_cursors_get(obj, &start, &end); - - text = efl_text_cursor_range_text_get(start, end); - if (!text || (text[0] == '\0')) - { - _edje_signal_emit(sd, "selection,cleared", "efl.text"); - _selection_clear(data, 0); - sd->have_selection = EINA_FALSE; - } - else - { - if (!sd->have_selection) - { - _edje_signal_emit(sd, "selection,start", "efl.text"); - } - _edje_signal_emit(sd, "selection,changed", "efl.text"); - sd->have_selection = EINA_TRUE; - _selection_store(EFL_UI_SELECTION_TYPE_PRIMARY, obj); - } - if (text) free(text); + _edje_signal_emit(sd, "selection,changed", "efl.text"); + _selection_store(EFL_UI_SELECTION_TYPE_PRIMARY, obj); _selection_defer(obj, sd); } @@ -4120,22 +3738,3 @@ _efl_ui_text_async_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED) } #include "efl_ui_text_async.eo.c" - -#undef MY_CLASS -#define MY_CLASS EFL_UI_TEXT_EDITABLE_CLASS - - -EOLIAN static Eo * -_efl_ui_text_editable_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED) -{ - // FIXME: should we have to keep this efl_ui_text_xxx classes? - // Then, going to make new theme for these classes? ex) efl/text_editable? - if (!elm_widget_theme_klass_get(obj)) - elm_widget_theme_klass_set(obj, "text"); - obj = efl_constructor(efl_super(obj, MY_CLASS)); - efl_text_interactive_editable_set(obj, EINA_TRUE); - - return obj; -} - -#include "efl_ui_text_editable.eo.c" diff --git a/src/lib/elementary/efl_ui_text.eo b/src/lib/elementary/efl_ui_text.eo index 19c05c42d2..785fe34294 100644 --- a/src/lib/elementary/efl_ui_text.eo +++ b/src/lib/elementary/efl_ui_text.eo @@ -1,97 +1,12 @@ -/* FIXME - Text object must stop using Context_Item_Clicked_Cb! */ -/* Legacy-only function pointer types, for the legacy EO classes (genlist, etc...) */ -type @beta @extern Context_Item_Clicked_Cb: __undefined_type; [[Evas smart callback type]] - -struct @beta Efl.Ui.Validate_Content_Info -{ - [[Validate content information.]] - text: string; [[Validate content text]] - signal: string; [[Validate content signal]] -} - -enum @beta Efl.Ui.Autocapital_Type -{ - [[Autocapitalization Types. - Choose method of auto-capitalization. - ]] - none, [[No auto-capitalization when typing.]] - word, [[Autocapitalize each word typed.]] - sentence, [[Autocapitalize the start of each sentence.]] - allcharacter [[Autocapitalize all letters.]] -} - -enum @beta Efl.Ui.Input_Panel_Language_Type -{ - [[Input panel (virtual keyboard) language modes. - ]] - automatic, [[Automatic]] - alphabet [[Alphabet]] -} - - -enum @beta Efl.Ui.Input_Hints -{ - [[Enumeration that defines the types of Input Hints.]] - none = 0, [[No active hints.]] - auto_complete = 1 << 0, [[Suggest word auto completion.]] - sensitive_data = 1 << 1, [[Typed text should not be stored.]] -} - - -enum @beta Efl.Ui.Input_Panel_Layout -{ - [[Input panel (virtual keyboard) layout types. - Type of input panel (virtual keyboard) to use - this is a hint and may not provide exactly what is desired. - ]] - normal, [[Default layout.]] - number, [[Number layout.]] - email, [[Email layout.]] - url, [[URL layout.]] - phonenumber, [[Phone Number layout.]] - ip, [[IP layout.]] - month, [[Month layout.]] - numberonly, [[Number Only layout.]] - invalid, [[Never use this.]] - hex, [[Hexadecimal layout.]] - terminal, [[Command-line terminal layout including esc, alt, ctrl key, so on (no auto-correct, no auto-capitalization).]] - password, [[Like normal, but no auto-correct, no auto-capitalization etc.]] - datetime, [[Date and time layout.]] - emoticon, [[Emoticon layout.]] - voice [[Voice layout, but if the IME does not support voice layout, then normal layout will be shown.]] -} - -enum @beta Efl.Ui.Input_Panel_Return_Key_Type -{ - [["Return" Key types on the input panel (virtual keyboard). - ]] - default, [[Default.]] - done, [[Done.]] - go, [[Go.]] - join, [[Join.]] - login, [[Login.]] - next, [[Next.]] - search, [[Search string or magnifier icon.]] - send, [[Send.]] - signin [[Sign-in.]] -} -enum @beta Efl.Ui.Icon_Type -{ - [[Icon types.]] - none, [[Icon has no type set.]] - file, [[Icon is of type file.]] - standard [[Icon is of type standard.]] -} - class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickable, - Efl.Access.Text, Efl.Access.Editable.Text, Efl.File, - Efl.Ui.Text_Selectable + Efl.Access.Text, Efl.Access.Editable.Text, Efl.File, Efl.Input_Text composites Efl.Text_Interactive, Efl.Text_Markup { [[A flexible text widget which can be static (as a label) or editable by the user (as a text entry). It provides all sorts of editing facilities like automatic scrollbars, virtual keyboard, clipboard, configurable - context menus, password mode or autocapitalization, for example.]] + context menus or autocapitalization, for example.]] methods { @property scrollable { [[Enable or disable scrolling in the widget. @@ -104,20 +19,6 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl scroll: bool; [[$true to enable scrolling. Default is $false.]] } } - @property input_panel_show_on_demand { - [[The attribute to show the input panel in case of only a user's explicit Mouse Up event. - It doesn't request to show the input panel even though it has focus. - ]] - set { - } - get { - } - values { - ondemand: bool; [[If $true, the input panel will be shown in case of only Mouse up event. - (Focus event will be ignored.) - ]] - } - } @property context_menu_disabled { [[This disables the entry's contextual (longpress) menu.]] set { @@ -144,19 +45,6 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl format: Efl.Ui.Selection_Format; [[Format for copy & paste.]] } } - @property input_panel_language { - [[The language mode of the input panel. - - This API can be used if you want to show the alphabet keyboard mode. - ]] - set { - } - get { - } - values { - lang: Efl.Ui.Input_Panel_Language_Type; [[Language to be set to the input panel.]] - } - } @property selection_handler_disabled { [[This disables the entry's selection handlers.]] set { @@ -167,117 +55,7 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl disabled: bool; [[If $true, the selection handlers are disabled.]] } } - @property input_panel_layout_variation { - [[Set the input panel layout variation of the entry - ]] - set { - } - get { - } - values { - variation: int; [[Layout variation type.]] - } - } - @property autocapital_type { - [[Set the autocapitalization type on the immodule.]] - set { - } - get { - } - values { - autocapital_type: Efl.Ui.Autocapital_Type; [[The type of autocapitalization.]] - } - } - @property password_mode { - [[Sets the entry to password mode. - In password mode entries are implicitly single line and the display of - any text inside them is replaced with asterisks (*). - ]] - set { - } - get { - } - values { - password: bool; [[If true, password mode is enabled.]] - } - } - @property input_panel_return_key_disabled { - [[Set the return key on the input panel to be disabled.]] - set { - } - get { - } - values { - disabled: bool; [[The state to put in in: $true for - disabled, $false for enabled.]] - } - } - @property prediction_allow { - [[Whether the entry should allow predictive text.]] - set { - } - get { - } - values { - prediction: bool; [[Whether the entry should allow predictive text.]] - } - } - @property input_hint { - [[Sets the input hint which allows input methods to fine-tune their behavior.]] - set { - } - get { - } - values { - hints: Efl.Ui.Input_Hints; [[Input hint.]] - } - } - @property input_panel_layout { - [[Set the input panel layout of the entry.]] - set { - } - get { - } - values { - layout: Efl.Ui.Input_Panel_Layout(Efl.Ui.Input_Panel_Layout.invalid); [[Layout type.]] - } - } - @property input_panel_return_key_type { - [[Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel. - - An input panel displays the string or icon associated with this type. - ]] - set { - } - get { - } - values { - return_key_type: Efl.Ui.Input_Panel_Return_Key_Type; [[The type of "return" key on the input panel.]] - } - } - @property input_panel_enabled { - [[Sets the attribute to show the input panel automatically.]] - set { - } - get { - } - values { - enabled: bool; [[If $true, the input panel is appeared when entry is clicked or has a focus.]] - } - } - @property input_panel_return_key_autoenabled { - [[Whether the return key on the input panel is disabled automatically when entry has no text. - - If $enabled is $true, the return key on input panel is disabled when the entry has no text. - The return key on the input panel is automatically enabled when the entry has text. - ]] - set { - } - values { - enabled: bool(false); [[If $true, the return key is automatically disabled when the entry has no text.]] - } - } @property item_factory { [[The factory that provides item in the text e.g. "emoticon/happy" or "href=file://image.jpg" etc. @@ -297,80 +75,15 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl [[Creates and returns a new cursor for the text.]] return: Efl.Text.Cursor @move; [[Text cursor.]] } - input_panel_show { - [[Show the input panel (virtual keyboard) based on the input panel property of entry such as layout, - autocapital types and so on. - - Note that input panel is shown or hidden automatically according to the focus state of entry widget. - This API can be used in the case of manually controlling by using @.input_panel_enabled.set(en, $false). - ]] - } selection_copy { [[This executes a "copy" action on the selected text in the entry.]] } - context_menu_clear { - [[This clears and frees the items in a entry's contextual (longpress) - menu. - - See also @.context_menu_item_add. - ]] - } - input_panel_imdata_set { - [[Set the input panel-specific data to deliver to the input panel. - - This API is used by applications to deliver specific data to the input panel. - The data format MUST be negotiated by both application and the input panel. - The size and format of data are defined by the input panel. - ]] - params { - @in data: const(void_ptr); [[The specific data to be set to the input panel.]] - @in len: int; [[The length of data, in bytes, to send to the input panel.]] - } - } - input_panel_imdata_get @const { - [[Get the specific data of the current input panel.]] - params { - @inout data: void; [[The specific data to be obtained from the input panel.]] - @out len: int; [[The length of data.]] - } - } selection_paste { [[This executes a "paste" action in the entry.]] } - input_panel_hide { - [[Hide the input panel (virtual keyboard). - - Note that input panel is shown or hidden automatically according to the focus state of entry widget. - This API can be used in the case of manually controlling by using @.input_panel_enabled.set(en, $false) - ]] - } - cursor_selection_end { - [[This ends a selection within the entry as though - the user had just released the mouse button while making a selection.]] - } selection_cut { [[This executes a "cut" action on the selected text in the entry.]] } - context_menu_item_add { - [[This adds an item to the entry's contextual menu. - - A longpress on an entry will make the contextual menu show up unless this - has been disabled with @.context_menu_disabled.set. - By default this menu provides a few options like enabling selection mode, - which is useful on embedded devices that need to be explicit about it. - When a selection exists it also shows the copy and cut actions. - - With this function, developers can add other options to this menu to - perform any action they deem necessary. - ]] - params { - @in label: string @optional; [[The item's text label.]] - @in icon_file: string @optional; [[The item's icon file.]] - @in icon_type: Efl.Ui.Icon_Type; [[The item's icon type.]] - @in func: Context_Item_Clicked_Cb @optional; [[The callback to execute when the item is clicked.]] - @in data: const(void_ptr) @optional; [[The data to associate with the item for related functions.]] - } - } } implements { Efl.Object.constructor; @@ -389,6 +102,7 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl Efl.Ui.Focus.Object.on_focus_update; Efl.Ui.Widget.interest_region { get; } Efl.Ui.Widget.disabled {set;} + Efl.Text_Format.password {set;} //Efl.Ui.Widget.widget_sub_object_del; //Elm.Interface_Scrollable.policy { set; } //Elm.Interface_Scrollable.bounce_allow { set; } @@ -423,23 +137,10 @@ class @beta Efl.Ui.Text extends Efl.Ui.Layout_Base implements Efl.Input.Clickabl Efl.Part.part_get; } events { + selection,paste: void; [[Called when selection is pasted.]] + selection,copy: void; [[Called when selection is copied.]] + selection,cut: void; [[Called when selection is cut.]] changed: void; [[Called when entry changes]] - /* can be $NULL, tag nullable once Eolian supports it */ - changed,user: Efl.Ui.Text_Change_Info; - [[The text object has changed due to user interaction]] - validate: Efl.Ui.Validate_Content_Info; [[Called when validating]] context,open: void; [[Called when context menu was opened]] - preedit,changed: void; [[Called when entry preedit changed]] - press: void; [[Called when entry pressed]] - redo,request: void; [[Called when redo is requested]] - undo,request: void; [[Called when undo is requested]] - aborted: void; [[Called when entry is aborted]] - // FIXME: efl_ui_text doesn't support anchor callbacks yet. - //anchor,down: Elm.Entry_Anchor_Info; [[Called on anchor down]] - //anchor,hover,opened: Elm.Entry_Anchor_Hover_Info; [[Called when hover opened]] - //anchor,in: Elm.Entry_Anchor_Info; [[Called on anchor in]] - //anchor,out: Elm.Entry_Anchor_Info; [[Called on anchor out]] - //anchor,up: Elm.Entry_Anchor_Info; [[called on anchor up]] - cursor,changed,manual: void; [[Called on manual cursor change]] } } diff --git a/src/lib/elementary/elc_fileselector_entry.c b/src/lib/elementary/elc_fileselector_entry.c index 13243b5d6d..68c17c1497 100644 --- a/src/lib/elementary/elc_fileselector_entry.c +++ b/src/lib/elementary/elc_fileselector_entry.c @@ -58,9 +58,9 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = } SIG_FWD(CHANGED, ELM_FILESELECTOR_ENTRY_EVENT_CHANGED) SIG_FWD(PRESS, ELM_FILESELECTOR_ENTRY_EVENT_PRESS) -SIG_FWD(SELECTION_PASTE, EFL_UI_EVENT_SELECTION_PASTE) -SIG_FWD(SELECTION_COPY, EFL_UI_EVENT_SELECTION_COPY) -SIG_FWD(SELECTION_CUT, EFL_UI_EVENT_SELECTION_CUT) +SIG_FWD(SELECTION_PASTE, EFL_UI_TEXT_EVENT_SELECTION_PASTE) +SIG_FWD(SELECTION_COPY, EFL_UI_TEXT_EVENT_SELECTION_COPY) +SIG_FWD(SELECTION_CUT, EFL_UI_TEXT_EVENT_SELECTION_CUT) #undef SIG_FWD #define SIG_FWD(name, event) \ @@ -249,9 +249,9 @@ _elm_fileselector_entry_efl_canvas_group_group_add(Eo *obj, Elm_Fileselector_Ent SIG_FWD(CHANGED, ELM_ENTRY_EVENT_CHANGED); SIG_FWD(ACTIVATED, ELM_ENTRY_EVENT_ACTIVATED); SIG_FWD(PRESS, ELM_ENTRY_EVENT_PRESS); - SIG_FWD(SELECTION_PASTE, EFL_UI_EVENT_SELECTION_PASTE); - SIG_FWD(SELECTION_COPY, EFL_UI_EVENT_SELECTION_COPY); - SIG_FWD(SELECTION_CUT, EFL_UI_EVENT_SELECTION_CUT); + SIG_FWD(SELECTION_PASTE, EFL_UI_TEXT_EVENT_SELECTION_PASTE); + SIG_FWD(SELECTION_COPY, EFL_UI_TEXT_EVENT_SELECTION_COPY); + SIG_FWD(SELECTION_CUT, EFL_UI_TEXT_EVENT_SELECTION_CUT); #undef SIG_FWD #define SIG_FWD(name, event) \ evas_object_smart_callback_add(priv->entry, event, _##name##_fwd, obj) diff --git a/src/lib/elementary/elm_entry.c b/src/lib/elementary/elm_entry.c index 737be8141b..f8079ea579 100644 --- a/src/lib/elementary/elm_entry.c +++ b/src/lib/elementary/elm_entry.c @@ -1588,7 +1588,7 @@ _paste_cb(void *data, if (!sd) return; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_PASTE, NULL); + (data, EFL_UI_TEXT_EVENT_SELECTION_PASTE, NULL); sd->selection_asked = EINA_TRUE; @@ -1643,7 +1643,7 @@ _cut_cb(void *data, if (!sd) return; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_CUT, NULL); + (data, EFL_UI_TEXT_EVENT_SELECTION_CUT, NULL); /* Store it */ sd->sel_mode = EINA_FALSE; if (!_elm_config->desktop_entry) @@ -1667,7 +1667,7 @@ _copy_cb(void *data, if (!sd) return; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_COPY, NULL); + (data, EFL_UI_TEXT_EVENT_SELECTION_COPY, NULL); sd->sel_mode = EINA_FALSE; if (!_elm_config->desktop_entry) { @@ -2338,8 +2338,10 @@ _entry_selection_start_signal_cb(void *data, { if (entry != data) elm_entry_select_none(entry); } + + Eina_Bool b_value = EINA_TRUE; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_START, NULL); + (data, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); elm_object_focus_set(data, EINA_TRUE); } @@ -2382,8 +2384,12 @@ _entry_selection_changed_signal_cb(void *data, if (!sd) return; sd->have_selection = EINA_TRUE; + Efl_Text_Range range = {0}; + //FIXME how to get selection range in legacy !? + range.start = 0; + range.end = 0; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_CHANGED, NULL); + (data, EFL_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED, &range); // XXX: still try primary selection even if on wl in case it's // supported // if (!_entry_win_is_wl(data)) @@ -2405,8 +2411,9 @@ _entry_selection_cleared_signal_cb(void *data, if (!sd->have_selection) return; sd->have_selection = EINA_FALSE; + Eina_Bool b_value = sd->have_selection; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_CLEARED, NULL); + (data, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); // XXX: still try primary selection even if on wl in case it's // supported // if (!_entry_win_is_wl(data)) @@ -2447,7 +2454,7 @@ _entry_paste_request_signal_cb(void *data, // supported // if ((type == ELM_SEL_TYPE_PRIMARY) && _entry_win_is_wl(data)) return; efl_event_callback_legacy_call - (data, EFL_UI_EVENT_SELECTION_PASTE, NULL); + (data, EFL_UI_TEXT_EVENT_SELECTION_PASTE, NULL); top = _entry_win_get(data); if (top) @@ -4442,8 +4449,11 @@ _elm_entry_select_none(Eo *obj EINA_UNUSED, Elm_Entry_Data *sd) edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm"); } if (sd->have_selection) - efl_event_callback_legacy_call - (obj, EFL_UI_EVENT_SELECTION_CLEARED, NULL); + { + Eina_Bool b_value = sd->have_selection; + efl_event_callback_legacy_call + (obj, EFL_TEXT_INTERACTIVE_EVENT_HAVE_SELECTION_CHANGED, &b_value); + } sd->have_selection = EINA_FALSE; edje_object_part_text_select_none(sd->entry_edje, "elm.text");