From 4eddbf00ca49a7b00d2d6fa6deafd8e4a5268acc Mon Sep 17 00:00:00 2001 From: moom Date: Fri, 11 Aug 2006 21:48:18 +0000 Subject: [PATCH] * Rewrite the entry widget It is now splitted in 3 files: - e_editable.c that implements a generic single-line editable object that could be used later by other widgets such as the slider or a spinner. - e_entry.c that implements an entry smart object using an editable object. - e_widget_entry.c that embeds an entry smart object in a widget. So far, text insertion and deletion have been implemented. It also supports cursor movement and mouse selection. The text also no longer gets out of the bounds of the entry. Things to come: - Password mode - Copy/Paste - Make it actually themable, for now, the colors/font/style are hardcoded SVN revision: 24575 --- data/themes/default_entry.edc | 28 +- data/themes/images/Makefile.am | 1 - data/themes/images/entry_focus.png | Bin 749 -> 0 bytes src/bin/Makefile.am | 2 + src/bin/e_editable.c | 1296 ++++++++++++++++++++++++++++ src/bin/e_editable.h | 42 + src/bin/e_entry.c | 1182 ++++++++----------------- src/bin/e_entry.h | 50 +- src/bin/e_fileman_smart.c | 5 +- src/bin/e_includes.h | 1 + src/bin/e_int_config_desklock.c | 4 +- src/bin/e_widget_entry.c | 229 +++-- src/bin/e_widget_entry.h | 11 +- 13 files changed, 1834 insertions(+), 1017 deletions(-) delete mode 100644 data/themes/images/entry_focus.png create mode 100644 src/bin/e_editable.c create mode 100644 src/bin/e_editable.h diff --git a/data/themes/default_entry.edc b/data/themes/default_entry.edc index 1bf8c5ef6..0cade83fd 100644 --- a/data/themes/default_entry.edc +++ b/data/themes/default_entry.edc @@ -1,6 +1,5 @@ images { image: "entry.png" COMP; - image: "entry_focus.png" COMP; } group { @@ -16,13 +15,6 @@ group { border: 8 8 8 8; } } - description { - state: "focus" 0.0; - inherit: "default" 0.0; - image { - normal: "entry_focus.png"; - } - } } part { name: "entry_focus"; @@ -30,10 +22,14 @@ group { state: "default" 0.0; visible: 0; color: 255 255 255 0; - image { - normal: "entry_focus.png"; - border: 8 8 8 8; - } + image { + normal: "focus.png"; + border: 7 7 7 7; + middle: 0; + } + fill { + smooth: 0; + } } description { state: "focus" 0.0; @@ -49,12 +45,12 @@ group { state: "default" 0.0; rel1 { relative: 0.0 0.0; - offset: 4 3; + offset: 4 4; to: "entry"; } rel2 { relative: 1.0 1.0; - offset: -5 -4; + offset: -5 -5; to: "entry"; } } @@ -66,7 +62,7 @@ group { signal: "focus_in"; source: ""; action: STATE_SET "focus" 0.0; - transition: LINEAR 0.2; + transition: DECELERATE 0.2; target: "entry_focus"; } program { @@ -74,7 +70,7 @@ group { signal: "focus_out"; source: ""; action: STATE_SET "default" 0.0; - transition: LINEAR 0.2; + transition: ACCELERATE 0.5; target: "entry_focus"; } } diff --git a/data/themes/images/Makefile.am b/data/themes/images/Makefile.am index 728405f45..f1f1fa574 100644 --- a/data/themes/images/Makefile.am +++ b/data/themes/images/Makefile.am @@ -326,7 +326,6 @@ e17_about_sky5.png \ e17_about_sky_overlay.png \ focus.png \ entry.png \ -entry_focus.png \ e17_scrollbar_hdrag_thumb.png \ e17_scrollbar_vdrag_thumb.png \ e17_fileman_bg.png \ diff --git a/data/themes/images/entry_focus.png b/data/themes/images/entry_focus.png deleted file mode 100644 index 5a0ebc24cedca4e8f70efc9ad39329d96d365090..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 749 zcmVsw;000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^RQ2@4MlD_>(XJpcd#dr3q= zRA}Dqnays~Koo^P&s^Ja+%$%)joh`x)raG#sq1TVw^>+PL5cTTfcnnn8ppjo zJU^gPYoWzQ#6xMZ(JLSl6LWOfWzg@j(SFaJ2Tvag!0xwo{8C7@af2YN;|CSQ3lQ;b z)C!0=J|(O+IoR8#v(*N0WKxU6N`oM*GgF(R6xQ*BS+sU>l%A3Viz{55(}XlJ7!z^Y zKg9LJ3DIZT?D}Q=ph9`3L3y@?7gW$v!cmswLXn*$n0SEel~K6_mB~pE@enV-EzRHs z6}(af@j?KU(l&xcsLhEPN%!y=fM|G<8R{&fl@>&Nw06-_Lc9x6%TE+FN44f#C^nBgrgKrPKo7Ly;xqZ|Ma1Y?z6a@ zgD@d{!d>1(Tc`D(Kz?S?Cxu;&H9k8jR=TgebmvW3ezGa&Q#?%!X_AaLnyET%iTq1$ z`T}tunXyrul_n zUue!RW<>9|Zr!7^@tMw6o6c6-{+=v2CW+acUu0ov1>l4De%M`Fe)jV2;}^^0eYPO~ f8!+SbBk=AAt$O#*>$bFT00000NkvXXu0mjfqhC{c diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 56942c2e1..0d589fa01 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -85,6 +85,7 @@ e_dialog.h \ e_about.h \ e_theme_about.h \ e_apps_cache.h \ +e_editable.h \ e_entry.h \ e_fileman.h \ e_fileman_smart.h \ @@ -228,6 +229,7 @@ e_dialog.c \ e_about.c \ e_theme_about.c \ e_apps_cache.c \ +e_editable.c \ e_entry.c \ e_fileman.c \ e_fileman_smart.c \ diff --git a/src/bin/e_editable.c b/src/bin/e_editable.c new file mode 100644 index 000000000..3ba876eb6 --- /dev/null +++ b/src/bin/e_editable.c @@ -0,0 +1,1296 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +#define E_EDITABLE_CURSOR_SHOW_DELAY 1.25 +#define E_EDITABLE_CURSOR_HIDE_DELAY 0.25 +#define E_EDITABLE_CURSOR_MARGIN 5 + +#define E_EDITABLE_BLOCK_SIZE 128 +#define E_EDITABLE_SIZE_TO_ALLOC(length) \ + (((length) + (E_EDITABLE_BLOCK_SIZE - 1)) / E_EDITABLE_BLOCK_SIZE) * E_EDITABLE_BLOCK_SIZE + +typedef struct _E_Editable_Smart_Data E_Editable_Smart_Data; + +struct _E_Editable_Smart_Data +{ + Evas_Object *clip_object; + Evas_Object *event_object; + Evas_Object *text_object; + Evas_Object *cursor_object; + Evas_Object *selection_object; + + Ecore_Timer *cursor_timer; + int cursor_pos; + int cursor_visible; + int selection_pos; + int selection_dragging; + int selection_visible; + int selectable; + + char *text; + int char_length; + int unicode_length; + int allocated_length; + + char *font; + int font_size; + Evas_Text_Style_Type font_style; + int average_char_w; + int average_char_h; +}; + +/* local subsystem functions */ +static int _e_editable_text_insert(Evas_Object *editable, int pos, const char *text); +static int _e_editable_text_delete(Evas_Object *editable, int start, int end); +static void _e_editable_cursor_update(Evas_Object *editable); +static void _e_editable_selection_update(Evas_Object *editable); +static void _e_editable_text_position_update(Evas_Object *editable); +static int _e_editable_cursor_pos_get_from_coords(Evas_Object *editable, Evas_Coord canvas_x, Evas_Coord canvas_y); + +static int _e_editable_cursor_timer_cb(void *data); +static void _e_editable_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_editable_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_editable_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _e_editable_smart_add(Evas_Object *object); +static void _e_editable_smart_del(Evas_Object *object); +static void _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); +static void _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); +static void _e_editable_smart_show(Evas_Object *object); +static void _e_editable_smart_hide(Evas_Object *object); +static void _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a); +static void _e_editable_clip_set(Evas_Object *object, Evas_Object *clip); +static void _e_editable_clip_unset(Evas_Object *object); + +/* local subsystem globals */ +static Evas_Smart *_e_editable_smart = NULL; +static int _e_editable_smart_use = 0; + + +/* externally accessible functions */ + +/** + * Creates a new editable object. An editable object is an evas smart object in + * which the user can type some single-line text, select it and delete it. + * + * @param evas The evas where to add the editable object + * @return Returns the new editable object + */ +EAPI Evas_Object * +e_editable_add(Evas *evas) +{ + if (!_e_editable_smart) + { + _e_editable_smart = evas_smart_new("e_editable", + _e_editable_smart_add, /* add */ + _e_editable_smart_del, /* del */ + NULL, NULL, NULL, NULL, NULL, /* stacking */ + _e_editable_smart_move, /* move */ + _e_editable_smart_resize, /* resize */ + _e_editable_smart_show, /* show */ + _e_editable_smart_hide, /* hide */ + _e_editable_color_set, /* color_set */ + _e_editable_clip_set, /* clip_set */ + _e_editable_clip_unset, /* clip_unset */ + NULL); /* data*/ + _e_editable_smart_use = 0; + } + + _e_editable_smart_use++; + return evas_object_smart_add(evas, _e_editable_smart); +} + +/** + * Sets the text of the editable object + * + * @param editable an editable object + * @param text the text to set + */ +EAPI void +e_editable_text_set(Evas_Object *editable, const char *text) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + free(sd->text); + sd->text = NULL; + sd->char_length = 0; + sd->unicode_length = 0; + sd->allocated_length = -1; + + if (_e_editable_text_insert(editable, 0, text) <= 0) + { + sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char)); + sd->text[0] = '\0'; + sd->char_length = 0; + sd->unicode_length = 0; + sd->allocated_length = E_EDITABLE_BLOCK_SIZE; + } + + sd->cursor_pos = 0; + sd->selection_pos = 0; + _e_editable_cursor_update(editable); +} + +/** + * Gets the entire text of the editable object + * + * @param editable an editable object + * @return Returns the entire text of the editable object + */ +EAPI const char * +e_editable_text_get(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return NULL; + return sd->text; +} + +/** + * Gets a range of the text of the editable object, from position @a start to + * position @a end + * + * @param editable an editable object + * @param start the start position of the text range to get + * @param end the end position of the text range to get + * @return Returns the range of text. The returned string will have to be freed + */ +EAPI char * +e_editable_text_range_get(Evas_Object *editable, int start, int end) +{ + E_Editable_Smart_Data *sd; + char *range; + int start_id, end_id; + int i; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return NULL; + + start = E_CLAMP(start, 0, sd->unicode_length); + end = E_CLAMP(end, 0, sd->unicode_length); + if (end <= start) + return NULL; + + start_id = 0; + end_id = 0; + for (i = 0; i < end; i++) + { + end_id = evas_string_char_next_get(sd->text, end_id, NULL); + if (i < start) + start_id = end_id; + } + + if (end_id <= start_id) + return NULL; + + range = malloc((end_id - start_id + 1) * sizeof(char)); + strncpy(range, &sd->text[start_id], end_id - start_id); + range[end_id - start_id] = '\0'; + + return range; +} + +/** + * Gets the unicode length of the text of the entry. The unicode length is not + * always the length returned by strlen() since a UTF-8 char can take several + * bytes + * + * @param editable an editable object + * @return Returns the unicode length of the text of the entry + */ +EAPI int +e_editable_text_length_get(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + return sd->unicode_length; +} + +/** + * Inserts some text at the given position in the editable object + * + * @param editable the editable object in which the text should be inserted + * @param pos the position where to insert the text + * @param text the text to insert + * @return Returns 1 if the text has been modified, 0 otherwise + */ +EAPI int +e_editable_insert(Evas_Object *editable, int pos, const char *text) +{ + E_Editable_Smart_Data *sd; + int unicode_length; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + + unicode_length = _e_editable_text_insert(editable, pos, text); + if (unicode_length <= 0) + return 0; + + if (sd->cursor_pos >= pos) + e_editable_cursor_pos_set(editable, sd->cursor_pos + unicode_length); + if (sd->selection_pos >= pos) + e_editable_selection_pos_set(editable, sd->selection_pos + unicode_length); + + _e_editable_text_position_update(editable); + return 1; +} + +/** + * Deletes the text of the editable object, between position "start" and + * position "end" + * + * @param editable the editable object in which the text should be deleted + * @param start the position of the first char to delete + * @param end the position of the last char to delete + * @return Returns 1 if the text has been modified, 0 otherwise + */ +EAPI int +e_editable_delete(Evas_Object *editable, int start, int end) +{ + E_Editable_Smart_Data *sd; + int unicode_length; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + + unicode_length = _e_editable_text_delete(editable, start, end); + if (unicode_length <= 0) + return 0; + + if (sd->cursor_pos > end) + e_editable_cursor_pos_set(editable, sd->cursor_pos - unicode_length); + else if (sd->cursor_pos > start) + e_editable_cursor_pos_set(editable, start); + + if (sd->selection_pos > end) + e_editable_selection_pos_set(editable, sd->selection_pos - unicode_length); + else if (sd->selection_pos > start) + e_editable_selection_pos_set(editable, start); + + _e_editable_text_position_update(editable); + return 1; +} + +/** + * Moves the cursor of the editable object to the given position + * + * @param editable an editable object + * @param pos the position where to move the cursor + */ +EAPI void +e_editable_cursor_pos_set(Evas_Object *editable, int pos) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + pos = E_CLAMP(pos, 0, sd->unicode_length); + if ((sd->cursor_pos == pos)) + return; + + sd->cursor_pos = pos; + _e_editable_cursor_update(editable); +} + +/** + * Gets the position of the cursor of the editable object + * + * @param editable an editable object + * @return Returns the position of the cursor of the editable object + */ +EAPI int +e_editable_cursor_pos_get(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + return sd->cursor_pos; +} + +/** + * Moves the cursor to the start of the editable object + * + * @param editable an editable object + */ +EAPI void +e_editable_cursor_move_to_start(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_cursor_pos_set(editable, 0); +} + +/** + * Moves the cursor to the end of the editable object + * + * @param editable an editable object + */ +EAPI void +e_editable_cursor_move_to_end(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_cursor_pos_set(editable, sd->unicode_length); +} + +/** + * Moves the cursor backward by one character offset + * + * @param editable an editable object + */ +EAPI void +e_editable_cursor_move_left(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_cursor_pos_set(editable, sd->cursor_pos - 1); +} + +/** + * Moves the cursor forward by one character offset + * + * @param editable an editable object + */ +EAPI void +e_editable_cursor_move_right(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_cursor_pos_set(editable, sd->cursor_pos + 1); +} + +/** + * Shows the cursor of the editable object + * + * @param editable the editable object whose cursor should be shown + */ +EAPI void +e_editable_cursor_show(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (sd->cursor_visible) + return; + + sd->cursor_visible = 1; + if (evas_object_visible_get(editable)) + { + evas_object_show(sd->cursor_object); + sd->cursor_timer = ecore_timer_add(E_EDITABLE_CURSOR_SHOW_DELAY, + _e_editable_cursor_timer_cb, + editable); + } +} + +/** + * Hides the cursor of the editable object + * + * @param editable the editable object whose cursor should be hidden + */ +EAPI void +e_editable_cursor_hide(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (!sd->cursor_visible) + return; + + sd->cursor_visible = 0; + if (evas_object_visible_get(editable)) + { + evas_object_hide(sd->cursor_object); + ecore_timer_del(sd->cursor_timer); + sd->cursor_timer = NULL; + } +} + +/** + * Moves the selection bound of the editable object to the given position + * + * @param editable an editable object + * @param pos the position where to move the selection bound + */ +EAPI void +e_editable_selection_pos_set(Evas_Object *editable, int pos) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + pos = E_CLAMP(pos, 0, sd->unicode_length); + if ((sd->selection_pos == pos)) + return; + + sd->selection_pos = pos; + _e_editable_selection_update(editable); +} + +/** + * Gets the position of the selection bound of the editable object. If the + * editable object is not selectable, this function returns the position of the + * cursor instead. + * + * @param editable an editable object + * @return Returns the position of the selection bound of the editable object + */ +EAPI int +e_editable_selection_pos_get(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + return sd->selectable ? sd->selection_pos : sd->cursor_pos; +} + +/** + * Moves the selection bound to the start of the editable object + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_move_to_start(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_selection_pos_set(editable, 0); +} + +/** + * Moves the selection bound to the end of the editable object + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_move_to_end(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_selection_pos_set(editable, sd->unicode_length); +} + +/** + * Moves the selection bound backward by one character offset + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_move_left(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_selection_pos_set(editable, sd->selection_pos - 1); +} + +/** + * Moves the selection bound forward by one character offset + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_move_right(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_selection_pos_set(editable, sd->selection_pos + 1); +} + +/** + * Selects all the text of the editable object. The selection bound will be + * moved to the start of the editable object and the cursor will be moved to + * the end + * + * @param editable an editable object + */ +EAPI void +e_editable_select_all(Evas_Object *editable) +{ + if (!editable) + return; + e_editable_selection_move_to_start(editable); + e_editable_cursor_move_to_end(editable); +} + +/** + * Unselects all the text of the editable object. The selection bound will be + * moved to the cursor position + * + * @param editable an editable object + */ +EAPI void +e_editable_unselect_all(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + e_editable_selection_pos_set(editable, sd->cursor_pos); +} + +/** + * Shows the selection of the editable object. The editable object need to be + * selectable (see e_editable_selectable_set()) + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_show(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (sd->selection_visible) + return; + + sd->selection_visible = 1; + if ((sd->selectable) && (evas_object_visible_get(editable)) && + (sd->cursor_pos != sd->selection_pos)) + evas_object_show(sd->selection_object); +} + +/** + * Hides the selection of the editable object + * + * @param editable an editable object + */ +EAPI void +e_editable_selection_hide(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (!sd->selection_visible) + return; + + sd->selection_visible = 0; + evas_object_hide(sd->selection_object); +} + +/** + * Sets whether or not the editable object is selectable. If the editable object + * is not selectable, the selection rectangle won't be shown, and + * e_editable_selection_pos_get() will then return the position of the cursor + * + * @param editable an editable object + * @param selection 1 to make the editable object selectable, 0 otherwise + */ +EAPI void +e_editable_selectable_set(Evas_Object *editable, int selectable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (sd->selectable == selectable) + return; + + sd->selectable = selectable; + + if (sd->selectable) + e_editable_unselect_all(editable); + + if ((sd->selectable) && (sd->selection_visible) && + (evas_object_visible_get(editable)) && + (sd->cursor_pos != sd->selection_pos)) + evas_object_show(sd->selection_object); + else + evas_object_hide(sd->selection_object); +} + +/** + * Gets whether or not the editable object is selectable + * + * @param editable an editable object + * @return Returns 1 if the editable object is selectable, 0 otherwise + */ +EAPI int +e_editable_selectable_get(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + return sd->selectable; +} + +/** + * A utility function to get the average size of a character written inside + * the editable object + * + * @param editable an editable object + * @param w the location where to store the average width of a character + * @param h the location where to store the average height of a character + */ +EAPI void +e_editable_char_size_get(Evas_Object *editable, int *w, int *h) +{ + int tw = 0, th = 0; + Evas *evas; + E_Editable_Smart_Data *sd; + Evas_Object *text_object; + char *text = "Tout est bon dans l'abricot sauf le noyau!" + "Wakey wakey! Eggs and Bakey!"; + + if (w) *w = 0; + if (h) *h = 0; + + if ((!editable) || (!(evas = evas_object_evas_get(editable)))) + return; + if ((!(sd = evas_object_smart_data_get(editable))) || (!sd->font)) + return; + + if ((sd->average_char_w <= 0) || (sd->average_char_h <= 0)) + { + text_object = evas_object_text_add(evas); + evas_object_text_font_set(text_object, sd->font, sd->font_size); + evas_object_text_style_set(text_object, sd->font_style); + evas_object_text_text_set(text_object, text); + evas_object_geometry_get(text_object, NULL, NULL, &tw, &th); + evas_object_del(text_object); + + sd->average_char_w = tw / strlen(text); + sd->average_char_h = th; + } + + if (w) *w = sd->average_char_w; + if (h) *h = sd->average_char_h; +} + +/* Private functions */ + +/* A utility function to insert some text inside the editable object. + * It doesn't update the position of the cursor, nor the selection... + */ +static int +_e_editable_text_insert(Evas_Object *editable, int pos, const char *text) +{ + E_Editable_Smart_Data *sd; + int char_length, unicode_length, prev_length; + int index; + int i; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + if ((!text) || (*text == '\0')) + return 0; + + if (pos < 0) + pos = 0; + else if (pos > sd->unicode_length) + pos = sd->unicode_length; + + char_length = -1; + unicode_length = -1; + for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL)) + { + char_length = i; + unicode_length++; + } + + index = 0; + for (i = 0; i < pos; i++) + index = evas_string_char_next_get(sd->text, index, NULL); + + if ((unicode_length <= 0) || (char_length <= 0)) + if ((unicode_length <= 0) || (char_length <= 0)) + return 0; + + prev_length = sd->char_length; + sd->char_length += char_length; + sd->unicode_length += unicode_length; + + if (sd->char_length > sd->allocated_length) + { + sd->text = realloc(sd->text, + E_EDITABLE_SIZE_TO_ALLOC(sd->char_length) + 1); + sd->allocated_length = E_EDITABLE_SIZE_TO_ALLOC(sd->char_length); + } + + if (prev_length > index) + memmove(&sd->text[index + char_length], &sd->text[index], prev_length - index); + strncpy(&sd->text[index], text, char_length); + sd->text[sd->char_length] = '\0'; + + evas_object_text_text_set(sd->text_object, sd->text); + + return unicode_length; +} + +/* A utility function to delete a range of text from the editable object. + * It doesn't update the position of the cursor, nor the selection... + */ +static int +_e_editable_text_delete(Evas_Object *editable, int start, int end) +{ + E_Editable_Smart_Data *sd; + int start_id, end_id; + int i; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return 0; + + start = E_CLAMP(start, 0, sd->unicode_length); + end = E_CLAMP(end, 0, sd->unicode_length); + if (end <= start) + return 0; + + start_id = 0; + end_id = 0; + for (i = 0; i < end; i++) + { + end_id = evas_string_char_next_get(sd->text, end_id, NULL); + if (i < start) + start_id = end_id; + } + + if (end_id <= start_id) + return 0; + + memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id); + sd->char_length -= (end_id - start_id); + sd->unicode_length -= (end - start); + sd->text[sd->char_length] = '\0'; + + evas_object_text_text_set(sd->text_object, sd->text); + + return end - start; +} + +/* Updates the position of the cursor + * It also updates automatically the text position and the selection + */ +static void +_e_editable_cursor_update(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + Evas_Coord tx, ty; + Evas_Coord cx, cy, cw, ch; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + evas_object_geometry_get(sd->text_object, &tx, &ty, NULL, NULL); + + if ((sd->unicode_length <= 0) || (sd->cursor_pos <= 0)) + { + e_editable_char_size_get(editable, &cw, &ch); + evas_object_move(sd->cursor_object, tx, ty); + evas_object_resize(sd->cursor_object, 1, ch); + } + else + { + if (sd->cursor_pos >= sd->unicode_length) + { + evas_object_text_char_pos_get(sd->text_object, sd->unicode_length - 1, + &cx, &cy, &cw, &ch); + evas_object_move(sd->cursor_object, tx + cx + cw - 1, ty + cy); + evas_object_resize(sd->cursor_object, 1, ch); + } + else + { + evas_object_text_char_pos_get(sd->text_object, sd->cursor_pos, + &cx, &cy, &cw, &ch); + evas_object_move(sd->cursor_object, tx + cx - 1, ty + cy); + evas_object_resize(sd->cursor_object, 1, ch); + } + } + + if (sd->cursor_timer) + { + evas_object_show(sd->cursor_object); + ecore_timer_interval_set(sd->cursor_timer, E_EDITABLE_CURSOR_SHOW_DELAY); + } + + _e_editable_selection_update(editable); + _e_editable_text_position_update(editable); +} + +/* Updates the selection of the editable object */ +static void +_e_editable_selection_update(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + Evas_Coord tx, ty; + Evas_Coord cx, cy, cw, ch; + Evas_Coord sx, sy, sw, sh; + int start_pos, end_pos; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + if ((sd->cursor_pos == sd->selection_pos) || + (!sd->selection_visible) || (!sd->selectable)) + evas_object_hide(sd->selection_object); + else + { + evas_object_geometry_get(sd->text_object, &tx, &ty, NULL, NULL); + + start_pos = (sd->cursor_pos <= sd->selection_pos) ? + sd->cursor_pos : sd->selection_pos; + end_pos = (sd->cursor_pos >= sd->selection_pos) ? + sd->cursor_pos : sd->selection_pos; + + /* Position of the start cursor (note, the start cursor can not be at + * the end of the editable object, and the editable object can not be + * empty, or it would have returned before)*/ + evas_object_text_char_pos_get(sd->text_object, start_pos, + &cx, &cy, &cw, &ch); + sx = tx + cx - 1; + sy = ty + cy; + + /* Position of the end cursor (note, the editable object can not be + * empty, or it would have returned before)*/ + if (end_pos >= sd->unicode_length) + { + evas_object_text_char_pos_get(sd->text_object, sd->unicode_length - 1, + &cx, &cy, &cw, &ch); + sw = (tx + cx + cw - 1) - sx; + sh = ch; + } + else + { + evas_object_text_char_pos_get(sd->text_object, end_pos, + &cx, &cy, &cw, &ch); + sw = (tx + cx - 1) - sx; + sh = ch; + } + + evas_object_move(sd->selection_object, sx, sy); + evas_object_resize(sd->selection_object, sw, sh); + evas_object_show(sd->selection_object); + } +} + +/* Updates the position of the text according to the position of the cursor */ +static void +_e_editable_text_position_update(Evas_Object *editable) +{ + E_Editable_Smart_Data *sd; + Evas_Coord ox, oy, ow; + Evas_Coord tx, ty, tw; + Evas_Coord cx, cy, cw; + Evas_Coord sx, sy; + Evas_Coord offset_x = 0; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return; + + evas_object_geometry_get(editable, &ox, &oy, &ow, NULL); + evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, NULL); + evas_object_geometry_get(sd->cursor_object, &cx, &cy, &cw, NULL); + evas_object_geometry_get(sd->selection_object, &sx, &sy, NULL, NULL); + + if (tw <= ow) + offset_x = ox - tx; + else if (cx < (ox + E_EDITABLE_CURSOR_MARGIN)) + offset_x = ox + E_EDITABLE_CURSOR_MARGIN - cx; + else if ((cx + cw + E_EDITABLE_CURSOR_MARGIN) > (ox + ow)) + offset_x = (ox + ow) - (cx + cw + E_EDITABLE_CURSOR_MARGIN); + + if (tw > ow) + { + if ((tx + offset_x) > ox) + offset_x = ox - tx; + else if ((tx + tw + offset_x) < (ox + ow)) + offset_x = (ox + ow) - (tx + tw); + } + + if (offset_x != 0) + { + evas_object_move(sd->text_object, tx + offset_x, ty); + evas_object_move(sd->cursor_object, cx + offset_x, cy); + evas_object_move(sd->selection_object, sx + offset_x, sy); + } +} + +/* Returns the position where to place the cursor according to the given coords + * Returns -1 on failure + */ +static int +_e_editable_cursor_pos_get_from_coords(Evas_Object *editable, Evas_Coord canvas_x, Evas_Coord canvas_y) +{ + E_Editable_Smart_Data *sd; + Evas_Coord tx, ty, tw, th; + Evas_Coord cx, cw; + int pos; + + if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) + return -1; + + evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, &th); + + if ((canvas_y < ty) || (canvas_x < tx)) + pos = 0; + else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw))) + pos = sd->unicode_length; + else + { + pos = evas_object_text_char_coords_get(sd->text_object, + canvas_x - tx, canvas_y - ty, + &cx, NULL, &cw, NULL); + if (pos >= 0) + { + if ((canvas_x - tx) > (cx + (cw / 2))) + pos++; + if (pos > sd->unicode_length) + pos = sd->unicode_length; + } + else + pos = -1; + } + + return pos; +} + +/* Shows/hides the cursor on regular interval */ +static int +_e_editable_cursor_timer_cb(void *data) +{ + Evas_Object *editable; + E_Editable_Smart_Data *sd; + + if ((!(editable = data)) || (!(sd = evas_object_smart_data_get(editable)))) + return 1; + + if (evas_object_visible_get(sd->cursor_object)) + { + evas_object_hide(sd->cursor_object); + ecore_timer_interval_set(sd->cursor_timer, E_EDITABLE_CURSOR_HIDE_DELAY); + } + else + { + evas_object_show(sd->cursor_object); + ecore_timer_interval_set(sd->cursor_timer, E_EDITABLE_CURSOR_SHOW_DELAY); + } + + return 1; +} + +/* Called when the editable object is pressed by the mouse */ +static void +_e_editable_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Object *editable; + E_Editable_Smart_Data *sd; + Evas_Event_Mouse_Down *event; + Evas_Coord ty, th; + int pos; + + if ((!(editable = obj)) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (!(event = event_info)) + return; + + evas_object_geometry_get(sd->text_object, NULL, &ty, NULL, &th); + if ((event->canvas.y < ty) || (event->canvas.y > (ty + th))) + return; + + pos = _e_editable_cursor_pos_get_from_coords(editable, event->canvas.x, + event->canvas.y); + if (pos >= 0) + { + e_editable_cursor_pos_set(editable, pos); + if (!evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_selection_pos_set(editable, pos); + + sd->selection_dragging = 1; + } +} + +/* Called when the editable object is released by the mouse */ +static void +_e_editable_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + E_Editable_Smart_Data *sd; + + if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + return; + sd->selection_dragging = 0; +} + +/* Called when the mouse moves over the editable object */ +static void +_e_editable_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Object *editable; + E_Editable_Smart_Data *sd; + Evas_Event_Mouse_Move *event; + int pos; + + if ((!(editable = obj)) || (!(sd = evas_object_smart_data_get(editable)))) + return; + if (!(event = event_info)) + return; + + if (sd->selection_dragging) + { + pos = _e_editable_cursor_pos_get_from_coords(editable, + event->cur.canvas.x, + event->cur.canvas.y); + if (pos >= 0) + e_editable_cursor_pos_set(editable, pos); + } +} + +/* Editable object's smart methods */ + +static void +_e_editable_smart_add(Evas_Object *object) +{ + Evas *evas; + E_Editable_Smart_Data *sd; + + if ((!object) || !(evas = evas_object_evas_get(object))) + return; + + sd = malloc(sizeof(E_Editable_Smart_Data)); + if (!sd) + return; + + evas_object_smart_data_set(object, sd); + + sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char)); + sd->text[0] = '\0'; + sd->char_length = 0; + sd->unicode_length = 0; + sd->allocated_length = E_EDITABLE_BLOCK_SIZE; + + /* TODO: themability! */ + sd->font = strdup("Vera"); + sd->font_size = 10; + sd->font_style = EVAS_TEXT_STYLE_PLAIN; + sd->average_char_w = 0; + sd->average_char_h = 0; + + sd->cursor_timer = NULL; + sd->cursor_pos = 0; + sd->cursor_visible = 1; + sd->selection_pos = 0; + sd->selection_dragging = 0; + sd->selection_visible = 1; + sd->selectable = 1; + + sd->clip_object = evas_object_rectangle_add(evas); + evas_object_smart_member_add(sd->clip_object, object); + + sd->event_object = evas_object_rectangle_add(evas); + evas_object_color_set(sd->event_object, 255, 255, 255, 0); + evas_object_clip_set(sd->event_object, sd->clip_object); + evas_object_smart_member_add(sd->event_object, object); + + sd->text_object = evas_object_text_add(evas); + evas_object_text_font_set(sd->text_object, sd->font, sd->font_size); + evas_object_text_style_set(sd->text_object, sd->font_style); + evas_object_color_set(sd->text_object, 0, 0, 0, 255); + evas_object_clip_set(sd->text_object, sd->clip_object); + evas_object_smart_member_add(sd->text_object, object); + + sd->cursor_object = evas_object_rectangle_add(evas); + /* TODO: themability (and use edje for this?) ! */ + evas_object_color_set(sd->cursor_object, 0, 0, 0, 255); + evas_object_clip_set(sd->cursor_object, sd->clip_object); + evas_object_smart_member_add(sd->cursor_object, object); + + sd->selection_object = evas_object_rectangle_add(evas); + /* TODO: themability (stackint too) ! */ + evas_object_color_set(sd->selection_object, 245, 205, 109, 102); + evas_object_clip_set(sd->selection_object, sd->clip_object); + evas_object_smart_member_add(sd->selection_object, object); + + _e_editable_cursor_update(object); + + evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN, + _e_editable_mouse_down_cb, NULL); + evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP, + _e_editable_mouse_up_cb, NULL); + evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_MOVE, + _e_editable_mouse_move_cb, NULL); +} + +/* Deletes the editable */ +static void +_e_editable_smart_del(Evas_Object *object) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + + free(sd->font); + + evas_object_del(sd->clip_object); + evas_object_del(sd->event_object); + evas_object_del(sd->text_object); + evas_object_del(sd->cursor_object); + evas_object_del(sd->selection_object); + if (sd->cursor_timer) + ecore_timer_del(sd->cursor_timer); + + free(sd); + + _e_editable_smart_use--; + if (_e_editable_smart_use <= 0) + { + evas_smart_free(_e_editable_smart); + _e_editable_smart = NULL; + } +} + +/* Moves the editable object */ +static void +_e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y) +{ + E_Editable_Smart_Data *sd; + Evas_Coord prev_x, prev_y; + Evas_Coord ox, oy; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + + evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL); + + evas_object_move(sd->clip_object, x, y); + evas_object_move(sd->event_object, x, y); + + evas_object_geometry_get(sd->text_object, &ox, &oy, NULL, NULL); + evas_object_move(sd->text_object, ox + (x - prev_x), oy + (y - prev_y)); + + evas_object_geometry_get(sd->cursor_object, &ox, &oy, NULL, NULL); + evas_object_move(sd->cursor_object, ox + (x - prev_x), oy + (y - prev_y)); + + evas_object_geometry_get(sd->selection_object, &ox, &oy, NULL, NULL); + evas_object_move(sd->selection_object, ox + (x - prev_x), oy + (y - prev_y)); +} + +/* Resizes the editable object */ +static void +_e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + + evas_object_resize(sd->clip_object, w, h); + evas_object_resize(sd->event_object, w, h); +} + +/* Shows the editable object */ +static void +_e_editable_smart_show(Evas_Object *object) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + + evas_object_show(sd->clip_object); + evas_object_show(sd->event_object); + evas_object_show(sd->text_object); + + if (sd->cursor_visible) + { + evas_object_show(sd->cursor_object); + if (sd->cursor_timer) + ecore_timer_interval_set(sd->cursor_timer, E_EDITABLE_CURSOR_SHOW_DELAY); + else + { + sd->cursor_timer = ecore_timer_add(E_EDITABLE_CURSOR_SHOW_DELAY, + _e_editable_cursor_timer_cb, + object); + } + } + + if ((sd->selectable) && (sd->selection_visible) && + (sd->cursor_pos != sd->selection_pos)) + evas_object_show(sd->selection_object); +} + +/* Hides the editable object */ +static void +_e_editable_smart_hide(Evas_Object *object) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + + evas_object_hide(sd->clip_object); + evas_object_hide(sd->event_object); + evas_object_hide(sd->text_object); + evas_object_hide(sd->cursor_object); + evas_object_hide(sd->selection_object); + + if (sd->cursor_timer) + { + ecore_timer_del(sd->cursor_timer); + sd->cursor_timer = NULL; + } +} + +/* Changes the color of the editable object */ +static void +_e_editable_color_set(Evas_Object *object, int r, int g, int b, int a) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + evas_object_color_set(sd->clip_object, r, g, b, a); +} + +/* Clips the editable object against "clip" */ +static void +_e_editable_clip_set(Evas_Object *object, Evas_Object *clip) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + evas_object_clip_set(sd->clip_object, clip); +} + +/* Unclips the editable object */ +static void +_e_editable_clip_unset(Evas_Object *object) +{ + E_Editable_Smart_Data *sd; + + if ((!object) || (!(sd = evas_object_smart_data_get(object)))) + return; + evas_object_clip_unset(sd->clip_object); +} diff --git a/src/bin/e_editable.h b/src/bin/e_editable.h new file mode 100644 index 000000000..13a490b20 --- /dev/null +++ b/src/bin/e_editable.h @@ -0,0 +1,42 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS +#else +#ifndef E_EDITABLE_H +#define E_EDITABLE_H + +EAPI Evas_Object *e_editable_add (Evas *evas); +EAPI void e_editable_text_set (Evas_Object *editable, const char *text); +EAPI const char *e_editable_text_get (Evas_Object *editable); +EAPI char *e_editable_text_range_get (Evas_Object *editable, int start, int end); +EAPI int e_editable_text_length_get (Evas_Object *editable); +EAPI int e_editable_insert (Evas_Object *editable, int pos, const char *text); +EAPI int e_editable_delete (Evas_Object *editable, int start, int end); + +EAPI void e_editable_cursor_pos_set (Evas_Object *editable, int pos); +EAPI int e_editable_cursor_pos_get (Evas_Object *editable); +EAPI void e_editable_cursor_move_to_start (Evas_Object *editable); +EAPI void e_editable_cursor_move_to_end (Evas_Object *editable); +EAPI void e_editable_cursor_move_left (Evas_Object *editable); +EAPI void e_editable_cursor_move_right (Evas_Object *editable); +EAPI void e_editable_cursor_show (Evas_Object *editable); +EAPI void e_editable_cursor_hide (Evas_Object *editable); + +EAPI void e_editable_selection_pos_set (Evas_Object *editable, int pos); +EAPI int e_editable_selection_pos_get (Evas_Object *editable); +EAPI void e_editable_selection_move_to_start (Evas_Object *editable); +EAPI void e_editable_selection_move_to_end (Evas_Object *editable); +EAPI void e_editable_selection_move_left (Evas_Object *editable); +EAPI void e_editable_selection_move_right (Evas_Object *editable); +EAPI void e_editable_select_all (Evas_Object *editable); +EAPI void e_editable_unselect_all (Evas_Object *editable); +EAPI void e_editable_selection_show (Evas_Object *editable); +EAPI void e_editable_selection_hide (Evas_Object *editable); +EAPI void e_editable_selectable_set (Evas_Object *editable, int selectable); +EAPI int e_editable_selectable_get (Evas_Object *editable); + +EAPI void e_editable_char_size_get (Evas_Object *editable, int *w, int *h); + +#endif +#endif diff --git a/src/bin/e_entry.c b/src/bin/e_entry.c index fb80270fa..5ced459d1 100644 --- a/src/bin/e_entry.c +++ b/src/bin/e_entry.c @@ -3,956 +3,474 @@ */ #include "e.h" -/* - * TODO: - * - implement missing _e_entry_smart_*, very easy - * - free / delete properly - * - implement focus and interact with theme - */ - -typedef struct _E_Editable_Text_Smart_Data E_Editable_Text_Smart_Data; -typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data; - -struct _E_Editable_Text_Smart_Data -{ - Evas_Object *clip; - Evas_Object *text_object; - Evas_Object *cursor_object; - Evas_Object *edje_object; - Ecore_Timer *cursor_timer; - - Evas_Bool cursor_at_the_end; - Evas_Bool show_cursor; -}; +typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data; struct _E_Entry_Smart_Data { Evas_Object *entry_object; - Evas_Object *edje_object; + Evas_Object *editable_object; - Evas_Coord minw, minh; - - void (*change_func) (void *data, Evas_Object *entry, char *key); - void *change_data; + int enabled; + int focused; + float valign; + int min_width; + int height; }; -static Evas_Bool _e_editable_text_is_empty(Evas_Object *object); -static void _e_editable_text_cursor_position_update(Evas_Object *object); -static void _e_editable_text_cursor_visibility_update(Evas_Object *object); -static int _e_editable_text_cursor_timer_cb(void *data); -static void _e_editable_text_size_update(Evas_Object *object); +/* local subsystem functions */ +static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); -static void _e_editable_text_smart_add(Evas_Object *object); -static void _e_editable_text_smart_del(Evas_Object *object); -static void _e_editable_text_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); -static void _e_editable_text_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); -static void _e_editable_text_smart_show(Evas_Object *object); -static void _e_editable_text_smart_hide(Evas_Object *object); +static void _e_entry_smart_add(Evas_Object *object); +static void _e_entry_smart_del(Evas_Object *object); +static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); +static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); +static void _e_entry_smart_show(Evas_Object *object); +static void _e_entry_smart_hide(Evas_Object *object); +static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a); +static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip); +static void _e_entry_clip_unset(Evas_Object *object); -static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event); +/* local subsystem globals */ +static Evas_Smart *_e_entry_smart = NULL; +static int _e_entry_smart_use = 0; -static void _e_entry_smart_add(Evas_Object *object); -static void _e_entry_smart_del(Evas_Object *object); -static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); -static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); -static void _e_entry_smart_show(Evas_Object *object); -static void _e_entry_smart_hide(Evas_Object *object); -static Evas_Smart *e_editable_text_smart = NULL; -static Evas_Textblock_Style *e_editable_text_style = NULL; -static int e_editable_text_style_use_count = 0; - -static Evas_Smart *e_entry_smart = NULL; - -EAPI Evas_Object * -e_editable_text_add(Evas *evas) -{ - if (!e_editable_text_smart) - { - e_editable_text_smart = evas_smart_new("e_editable_entry", - _e_editable_text_smart_add, /* add */ - _e_editable_text_smart_del, /* del */ - NULL, NULL, NULL, NULL, NULL, - _e_editable_text_smart_move, /* move */ - _e_editable_text_smart_resize, /* resize */ - _e_editable_text_smart_show, /* show */ - _e_editable_text_smart_hide, /* hide */ - NULL, /* color_set */ - NULL, /* clip_set */ - NULL, /* clip_unset */ - NULL); /* data*/ - } - return evas_object_smart_add(evas, e_editable_text_smart); -} - -EAPI const char* -e_editable_text_text_get(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return ""; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - return evas_textblock_cursor_node_text_get(cursor); -} +/* externally accessible functions */ /** - * @brief Sets the text of the object - * @param object an editable text object - * @param text the text to set + * Creates a new entry object. An entry is a field where the user can type + * single-line text. + * Use the "changed" smart callback to know when the content of the entry is + * changed + * + * @param evas the evas where the entry object should be added + * @return Returns the new entry object */ -EAPI void -e_editable_text_text_set(Evas_Object *object, const char *text) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_textblock_text_markup_set(sd->text_object, text); - sd->cursor_at_the_end = 1; - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Inserts text at the cursor position of the object - * @param object an editable text object - * @param text the text to insert - */ -EAPI void -e_editable_text_insert(Evas_Object *object, const char *text) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - if ((!text) || ((strlen(text) <= 1) && (text[0] < 0x20))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - - if (sd->cursor_at_the_end) - evas_textblock_cursor_text_append(cursor, text); - else - evas_textblock_cursor_text_prepend(cursor, text); - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Deletes the char placed before the cursor - * @param object an editable text object - */ -EAPI void -e_editable_text_delete_char_before(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || - (!(sd = evas_object_smart_data_get(object))) || - (_e_editable_text_is_empty(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - - if ((sd->cursor_at_the_end) || (evas_textblock_cursor_char_prev(cursor))) - evas_textblock_cursor_char_delete(cursor); - - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Deletes the char placed after the cursor - * @param object an editable text object - */ -EAPI void -e_editable_text_delete_char_after(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || - (!(sd = evas_object_smart_data_get(object))) || - (_e_editable_text_is_empty(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - - if (!sd->cursor_at_the_end) - { - if (!evas_textblock_cursor_char_next(cursor)) - sd->cursor_at_the_end = 1; - else - evas_textblock_cursor_char_prev(cursor); - evas_textblock_cursor_char_delete(cursor); - } - - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Moves the cursor of the editable text object at the start of the text - * @param object an editable text object - */ -EAPI void -e_editable_text_cursor_move_at_start(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || - (!(sd = evas_object_smart_data_get(object))) || - (_e_editable_text_is_empty(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - sd->cursor_at_the_end = 0; - evas_textblock_cursor_char_first(cursor); - - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Moves the cursor of the editable text object at the end of the text - * @param object an editable text object - */ -EAPI void -e_editable_text_cursor_move_at_end(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || - (!(sd = evas_object_smart_data_get(object))) || - (_e_editable_text_is_empty(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - sd->cursor_at_the_end = 1; - evas_textblock_cursor_char_last(cursor); - - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Moves the cursor of the editable text object to the left - * @param object an editable text object - */ -EAPI void -e_editable_text_cursor_move_left(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - if (sd->cursor_at_the_end) - sd->cursor_at_the_end = 0; - else - evas_textblock_cursor_char_prev(cursor); - - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Moves the cursor of the editable text object to the right - * @param object an editable text object - */ -EAPI void -e_editable_text_cursor_move_right(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - if (!evas_textblock_cursor_char_next(cursor)) - sd->cursor_at_the_end = 1; - - _e_editable_text_size_update(object); - _e_editable_text_cursor_position_update(object); -} - -/** - * @brief Shows the cursor of the editable text object - * @param object the editable text object - */ -EAPI void -e_editable_text_cursor_show(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - sd->show_cursor = 1; - _e_editable_text_cursor_visibility_update(object); -} - -/** - * @brief Hides the cursor of the editable text object - * @param object the editable text object - */ -EAPI void -e_editable_text_cursor_hide(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - sd->show_cursor = 0; - _e_editable_text_cursor_visibility_update(object); -} - -EAPI void -e_editable_text_min_size_get(Evas_Object *object, Evas_Coord *mw, Evas_Coord *mh) -{ - -} - EAPI Evas_Object * e_entry_add(Evas *evas) { - if(!e_entry_smart) - e_entry_smart = evas_smart_new("e_entry", + if (!_e_entry_smart) + { + _e_entry_smart = evas_smart_new("e_entry", _e_entry_smart_add, /* add */ _e_entry_smart_del, /* del */ - NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, /* stacking */ _e_entry_smart_move, /* move */ _e_entry_smart_resize, /* resize */ _e_entry_smart_show, /* show */ _e_entry_smart_hide, /* hide */ - NULL, /* color_set */ - NULL, /* clip_set */ - NULL, /* clip_unset */ - NULL); /* data*/ - return evas_object_smart_add(evas, e_entry_smart); -} - -EAPI void -e_entry_change_handler_set(Evas_Object *object, void (*func)(void *data, Evas_Object *entry, char *key), void *data) -{ - E_Entry_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - sd->change_func = func; - sd->change_data = data; + _e_entry_color_set, /* color_set */ + _e_entry_clip_set, /* clip_set */ + _e_entry_clip_unset, /* clip_unset */ + NULL); /* data*/ + _e_entry_smart_use = 0; + } + + _e_entry_smart_use++; + return evas_object_smart_add(evas, _e_entry_smart); } +/** + * Sets the text of the entry object + * + * @param entry an entry object + * @param text the text to set + */ EAPI void e_entry_text_set(Evas_Object *entry, const char *text) { E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - - e_editable_text_text_set(sd->entry_object, text); + + e_editable_text_set(sd->editable_object, text); + evas_object_smart_callback_call(entry, "changed", NULL); } -EAPI const char* +/** + * Gets the text of the entry object + * + * @param entry an entry object + * @return Returns the text of the entry object + */ +EAPI const char * e_entry_text_get(Evas_Object *entry) { E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return ""; - - return e_editable_text_text_get(sd->entry_object); + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) + return NULL; + return e_editable_text_get(sd->editable_object); } +/** + * Clears the entry object + * + * @param entry an entry object + */ EAPI void -e_entry_text_insert(Evas_Object *entry, const char *text) +e_entry_clear(Evas_Object *entry) +{ + e_entry_text_set(entry, ""); +} + +/** + * Gets the minimum size of the entry object + * + * @param entry an entry object + * @param minw the location where to store the minimun width of the entry + * @param minh the location where to store the minimun height of the entry + */ +EAPI void +e_entry_min_size_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh) { E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - - e_editable_text_insert(sd->entry_object, text); -} - -EAPI void -e_entry_delete_char_before(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_delete_char_before(sd->entry_object); -} - -EAPI void -e_entry_delete_char_after(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_delete_char_after(sd->entry_object); -} - -EAPI void -e_entry_cursor_move_at_start(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_move_at_start(sd->entry_object); -} - -EAPI void -e_entry_cursor_move_at_end(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_move_at_end(sd->entry_object); -} - -EAPI void -e_entry_cursor_move_left(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_move_left(sd->entry_object); -} - -EAPI void -e_entry_cursor_move_right(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_move_right(sd->entry_object); -} - -EAPI void -e_entry_cursor_show(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_show(sd->entry_object); -} - -EAPI void -e_entry_cursor_hide(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - - e_editable_text_cursor_hide(sd->entry_object); + + if (minw) *minw = sd->min_width; + if (minh) *minh = sd->height; } +/** + * Focuses the entry object. It will receives keyboard events and the user could + * then type some text (the entry should also be enabled. The cursor and the + * selection will be shown + * + * @param entry the entry to focus + */ EAPI void e_entry_focus(Evas_Object *entry) { E_Entry_Smart_Data *sd; - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; + if (sd->focused) + return; - edje_object_signal_emit(sd->edje_object, "focus_in", ""); + evas_object_focus_set(entry, 1); + edje_object_signal_emit(sd->entry_object, "focus_in", ""); + if (sd->enabled) + e_editable_cursor_show(sd->editable_object); + e_editable_selection_show(sd->editable_object); + e_editable_cursor_move_to_end(sd->editable_object); + e_editable_selection_move_to_end(sd->editable_object); + sd->focused = 1; } +/** + * Unfocuses the entry object. It will no longer receives keyboard events so + * the user could no longer type some text. The cursor and the selection will + * be hidden + * + * @param entry the entry object to unfocus + */ EAPI void e_entry_unfocus(Evas_Object *entry) { E_Entry_Smart_Data *sd; - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - - edje_object_signal_emit(sd->edje_object, "focus_out", ""); -} - -EAPI void -e_entry_min_size_get(Evas_Object *entry, Evas_Coord *mw, Evas_Coord *mh) -{ - E_Entry_Smart_Data *sd; - - if ((!entry) || !(sd = evas_object_smart_data_get(entry))) - return; - if (mw) *mw = sd->minw; - if (mh) *mh = sd->minh; -} - -/************************** - * - * Private functions - * - **************************/ - -/* Returns 1 if the text of the editable object is empty */ -static Evas_Bool -_e_editable_text_is_empty(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return 1; - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - return (evas_textblock_cursor_node_text_length_get(cursor) <= 0); -} - -/* Updates the size of the text object: to be called when the text of the object is changed */ -static void -_e_editable_text_size_update(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - int w, h; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_textblock_size_native_get(sd->text_object, &w, &h); - evas_object_resize(sd->text_object, w, h); - evas_object_resize(object, w, h); -} - -/* Updates the cursor position: to be called when the cursor or the object are moved */ -static void -_e_editable_text_cursor_position_update(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - Evas_Coord tx, ty, tw, th, cx, cy, cw, ch, ox, oy, ow, oh; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, &th); - evas_object_geometry_get(object, &ox, &oy, &ow, &oh); - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - - if (_e_editable_text_is_empty(object)) - { - evas_object_move(sd->cursor_object, tx, ty); - evas_object_resize(sd->cursor_object, 1, th); - return; - } - else if (sd->cursor_at_the_end) - { - evas_textblock_cursor_char_last(cursor); - evas_textblock_cursor_char_geometry_get(cursor, &cx, &cy, &cw, &ch); - cx += tx + cw; - } - else - { - evas_textblock_cursor_char_geometry_get(cursor, &cx, &cy, &cw, &ch); - cx += tx; - } - - /* TODO: fix */ - if ((cx < ox + 20) && (cx - tx > 20)) - { - evas_object_move(sd->text_object, tx + ox + 20 - cx, ty); - cx = ox + 20; - } - else if (cx < ox) - { - evas_object_move(sd->text_object, tx + ox - cx, ty); - cx = ox; - } - else if ((cx > ox + ow - 20) && (tw - (cx - tx) > 20)) - { - evas_object_move(sd->text_object, tx - cx + ox + ow - 20, ty); - cx = ox + ow - 20; - } - else if (cx > ox + ow) - { - evas_object_move(sd->text_object, tx - cx + ox + ow, ty); - cx = ox + ow; - } - - evas_object_move(sd->cursor_object, cx, ty + cy); - evas_object_resize(sd->cursor_object, 1, ch); -} - -/* Updates the visibility state of the cursor */ -static void -_e_editable_text_cursor_visibility_update(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) + if (!sd->focused) return; - - if (!sd->show_cursor) - { - if (sd->cursor_timer) - { - ecore_timer_del(sd->cursor_timer); - sd->cursor_timer = NULL; - } - evas_object_hide(sd->cursor_object); - } - else - { - if (!sd->cursor_timer) - { - sd->cursor_timer = ecore_timer_add(0.75, _e_editable_text_cursor_timer_cb, object); - evas_object_show(sd->cursor_object); - } - } + + evas_object_focus_set(entry, 0); + edje_object_signal_emit(sd->entry_object, "focus_out", ""); + e_editable_cursor_hide(sd->editable_object); + e_editable_selection_hide(sd->editable_object); + sd->focused = 0; } -/* Make the cursor blink */ -// FIXME: cursor should not be a rect - shoudl be an edje. timers not needed then -static int -_e_editable_text_cursor_timer_cb(void *data) -{ - Evas_Object *object; - E_Editable_Text_Smart_Data *sd; - - object = data; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return 1; - - if (evas_object_visible_get(sd->cursor_object)) - { - evas_object_hide(sd->cursor_object); - ecore_timer_interval_set(sd->cursor_timer, 0.25); - } - else - { - evas_object_show(sd->cursor_object); - ecore_timer_interval_set(sd->cursor_timer, 0.75); - } - - return 1; -} - -/* Called when the object is created */ -static void -_e_editable_text_smart_add(Evas_Object *object) -{ - Evas *evas; - E_Editable_Text_Smart_Data *sd; - Evas_Textblock_Cursor *cursor; - - if ((!object) || !(evas = evas_object_evas_get(object))) - return; - - if (!e_editable_text_style) - { - e_editable_text_style = evas_textblock_style_new(); - evas_textblock_style_set(e_editable_text_style, "DEFAULT='font=Vera font_size=10 align=left color=#000000 wrap=word'"); - e_editable_text_style_use_count = 0; - } - - sd = malloc(sizeof(E_Editable_Text_Smart_Data)); - if (!sd) return; - sd->show_cursor = 0; - sd->cursor_at_the_end = 1; - sd->cursor_timer = NULL; - - sd->text_object = evas_object_textblock_add(evas); - evas_object_textblock_style_set(sd->text_object, e_editable_text_style); - e_editable_text_style_use_count++; - evas_object_smart_member_add(sd->text_object, object); - - // FIXME: cursor should not be a rect - shoudl be an edje. - sd->clip = evas_object_rectangle_add(evas); - evas_object_clip_set(sd->text_object, sd->clip); - evas_object_smart_member_add(sd->clip, object); - - sd->cursor_object = evas_object_rectangle_add(evas); - evas_object_color_set(sd->cursor_object, 0, 0, 0, 255); - evas_object_smart_member_add(sd->cursor_object, object); - - evas_object_smart_data_set(object, sd); - - cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(sd->text_object); - evas_textblock_cursor_node_first(cursor); - - evas_font_path_append (evas, PACKAGE_DATA_DIR"/data/fonts"); -} - -/* Called when the object is deleted */ -static void -_e_editable_text_smart_del(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - if (sd->cursor_timer) - ecore_timer_del(sd->cursor_timer); - evas_object_del(sd->text_object); - - evas_object_del(sd->clip); - evas_object_del(sd->cursor_object); - free(sd); - - e_editable_text_style_use_count--; - if ((e_editable_text_style_use_count <= 0) && (e_editable_text_style)) - { - evas_textblock_style_free(e_editable_text_style); - e_editable_text_style = NULL; - } -} - -/* Called when the object is moved */ -static void -_e_editable_text_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_move(sd->clip, x, y); - evas_object_move(sd->text_object, x, y); - _e_editable_text_cursor_position_update(object); -} - -/* Called when the object is resized */ -static void -_e_editable_text_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_resize(sd->clip, w, h); -} - -/* Called when the object is shown */ -static void -_e_editable_text_smart_show(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_show(sd->text_object); - evas_object_show(sd->clip); - _e_editable_text_cursor_visibility_update(object); -} - -/* Called when the object is hidden */ -static void -_e_editable_text_smart_hide(Evas_Object *object) -{ - E_Editable_Text_Smart_Data *sd; - - if ((!object) || !(sd = evas_object_smart_data_get(object))) - return; - - evas_object_hide(sd->cursor_object); - evas_object_hide(sd->text_object); - evas_object_hide(sd->clip); -} - -/* Called when the user presses a key */ -static void -_e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event) +/** + * Enables the entry object: the user will be able to type text + * + * @param entry the entry object to enable + */ +EAPI void +e_entry_enable(Evas_Object *entry) { E_Entry_Smart_Data *sd; - Evas_Event_Key_Down *key_event = event; - - if ((!obj) || !(sd = evas_object_smart_data_get(obj))) + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - - obj = sd->entry_object; - - if ((!strcmp(key_event->keyname, "BackSpace")) || - ((key_event->string) && (strlen(key_event->string) == 1) && - (key_event->string[0] == 0x8))) - { - e_editable_text_delete_char_before(obj); - if (sd->change_func) - sd->change_func(sd->change_data, obj, ""); - } - else if ((!strcmp(key_event->keyname, "Delete")) || - ((key_event->string) && (strlen(key_event->string) == 1) && - (key_event->string[0] == 0x4))) - { - e_editable_text_delete_char_after(obj); - if (sd->change_func) - sd->change_func(sd->change_data, obj, ""); - } - else if (!strcmp(key_event->keyname, "Left")) - e_editable_text_cursor_move_left(obj); - else if (!strcmp(key_event->keyname, "Right")) - e_editable_text_cursor_move_right(obj); - else if ((!strcmp(key_event->keyname, "Home")) || - ((key_event->string) && (strlen(key_event->string) == 1) && - (key_event->string[0] == 0x1))) - e_editable_text_cursor_move_at_start(obj); - else if ((!strcmp(key_event->keyname, "End")) || - ((key_event->string) && (strlen(key_event->string) == 1) && - (key_event->string[0] == 0x5))) - e_editable_text_cursor_move_at_end(obj); - else - { - e_editable_text_insert(obj, key_event->string); - if ((key_event->string) && (strcmp(key_event->keyname, "Escape"))) - { - if (*(key_event->string) >= 0x20) - { - if (sd->change_func) - sd->change_func(sd->change_data, obj, - (char *)key_event->string); - } - } - } + if (sd->enabled) + return; + + edje_object_signal_emit(entry, "enabled", ""); + if (sd->focused) + e_editable_cursor_show(sd->editable_object); + sd->enabled = 1; + } -/* Called when the entry is focused */ -/* we need to make this work, move then to e_entry_...? fuck it, am too sleepy */ -static void -_e_editable_text_focus_cb(Evas_Object *object) + +/** + * Disables the entry object: the user won't be able to type anymore. Selection + * will still be possible (to copy the text) + * + * @param entry the entry object to disable + */ +EAPI void +e_entry_disable(Evas_Object *entry) { - if (!object) + E_Entry_Smart_Data *sd; + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - - e_editable_text_cursor_show(object); + if (!sd->enabled) + return; + + edje_object_signal_emit(entry, "disabled", ""); + e_editable_cursor_hide(sd->editable_object); + sd->enabled = 0; } -/* Called when the entry is unfocused */ -/* we need to make this work */ + +/* Private functions */ + +/* Called when a key has been pressed by the user */ static void -_e_editable_text_unfocus_cb(Evas_Object *object) +_e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) { - if (!object) + E_Entry_Smart_Data *sd; + Evas_Object *editable; + Evas_Event_Key_Down *event; + int cursor_pos, selection_pos; + int start_pos, end_pos; + int selecting; + int changed = 0; + + if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + return; + if (!(event = event_info) || !(event->keyname)) return; - //e_editable_text_object_cursor_hide(object); - //e_editable_text_object_cursor_move_at_start(object); + editable = sd->editable_object; + cursor_pos = e_editable_cursor_pos_get(editable); + selection_pos = e_editable_selection_pos_get(editable); + start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; + end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; + selecting = (start_pos != end_pos); + + /* TODO: CTRL + A, X, C, V */ + + if (!sd->enabled) + return; + + /* Move the cursor/selection to the left */ + if (strcmp(event->key, "Left") == 0) + { + if (evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_cursor_move_left(editable); + else if (selecting) + { + if (cursor_pos < selection_pos) + e_editable_selection_pos_set(editable, cursor_pos); + else + e_editable_cursor_pos_set(editable, selection_pos); + } + else + { + e_editable_cursor_move_left(editable); + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + } + /* Move the cursor/selection to the right */ + else if (strcmp(event->key, "Right") == 0) + { + if (evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_cursor_move_right(editable); + else if (selecting) + { + if (cursor_pos > selection_pos) + e_editable_selection_pos_set(editable, cursor_pos); + else + e_editable_cursor_pos_set(editable, selection_pos); + } + else + { + e_editable_cursor_move_right(editable); + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + } + /* Move the cursor/selection to the start of the entry */ + else if ((strcmp(event->keyname, "Home") == 0) || + ((event->string) && (strlen(event->string) == 1) && + (event->string[0] == 0x1))) + { + e_editable_cursor_move_to_start(editable); + if (!evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Move the cursor/selection to the end of the entry */ + else if ((strcmp(event->keyname, "End") == 0) || + ((event->string) && (strlen(event->string) == 1) && + (event->string[0] == 0x5))) + { + e_editable_cursor_move_to_end(editable); + if (!evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Remove the previous character */ + else if ((strcmp(event->keyname, "BackSpace") == 0) || + ((event->string) && (strlen(event->string) == 1) && + (event->string[0] == 0x8))) + { + if (selecting) + changed = e_editable_delete(editable, start_pos, end_pos); + else + changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos); + } + /* Remove the next character */ + else if ((!strcmp(event->keyname, "Delete")) || + ((event->string) && (strlen(event->string) == 1) && + (event->string[0] == 0x4))) + { + if (selecting) + changed = e_editable_delete(editable, start_pos, end_pos); + else + changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1); + } + /* Otherwise, we insert the corresponding character */ + else if ((event->string) && + ((strlen(event->string) != 1) || (event->string[0] >= 0x20))) + { + if (selecting) + changed = e_editable_delete(editable, start_pos, end_pos); + changed |= e_editable_insert(editable, start_pos, event->string); + } + + if (changed) + evas_object_smart_callback_call(obj, "changed", NULL); } -static void -_e_entry_smart_add(Evas_Object *object) +/* Editable object's smart methods */ + +static void _e_entry_smart_add(Evas_Object *object) { Evas *evas; E_Entry_Smart_Data *sd; - Evas_Coord w = 0, h = 0; + Evas_Object *o; + int cw, ch; if ((!object) || !(evas = evas_object_evas_get(object))) return; sd = malloc(sizeof(E_Entry_Smart_Data)); - if (!sd) return; - - sd->change_func = NULL; - sd->change_data = NULL; + if (!sd) + return; evas_object_smart_data_set(object, sd); - - sd->edje_object = edje_object_add(evas); - e_theme_edje_object_set(sd->edje_object, "base/theme/widgets", - "widgets/entry"); - evas_object_smart_member_add(sd->edje_object, object); - - sd->entry_object = e_editable_text_add(evas); - e_editable_text_text_set(sd->entry_object, " "); - evas_object_geometry_get(sd->entry_object, NULL, NULL, &w, &h); - e_editable_text_text_set(sd->entry_object, NULL); - edje_extern_object_min_size_set(sd->entry_object, w, h); - edje_object_part_swallow(sd->edje_object, "text_area", sd->entry_object); - edje_object_size_min_calc(sd->edje_object, &w, &h); - sd->minw = w; - sd->minh = h; - evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN, _e_entry_key_down_cb, NULL); + sd->enabled = 1; + sd->focused = 0; + sd->valign = 0.5; + + o = edje_object_add(evas); + sd->entry_object = o; + e_theme_edje_object_set(o, "base/theme/widgets", "widgets/entry"); + evas_object_smart_member_add(o, object); + + o = e_editable_add(evas); + sd->editable_object = o; + e_editable_cursor_hide(o); + e_editable_char_size_get(o, &cw, &ch); + edje_extern_object_min_size_set(o, cw, ch); + edje_object_part_swallow(sd->entry_object, "text_area", o); + edje_object_size_min_calc(sd->entry_object, &sd->min_width, &sd->height); + evas_object_show(o); + + evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN, + _e_entry_key_down_cb, NULL); } -static void -_e_entry_smart_del(Evas_Object *object) +static void _e_entry_smart_del(Evas_Object *object) { E_Entry_Smart_Data *sd; - + if ((!object) || !(sd = evas_object_smart_data_get(object))) return; - + + evas_object_del(sd->editable_object); evas_object_del(sd->entry_object); - evas_object_del(sd->edje_object); - E_FREE(sd); } -static void -_e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y) +static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y) { E_Entry_Smart_Data *sd; - + Evas_Coord prev_x, prev_y; + Evas_Coord ox, oy; + if ((!object) || !(sd = evas_object_smart_data_get(object))) return; - - evas_object_move(sd->edje_object, x, y); - e_entry_cursor_move_at_start(object); + + evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL); + evas_object_geometry_get(sd->entry_object, &ox, &oy, NULL, NULL); + evas_object_move(sd->entry_object, ox + (x - prev_x), oy + (y - prev_y)); } -static void -_e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h) +static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h) { E_Entry_Smart_Data *sd; Evas_Coord x, y; - + if ((!object) || !(sd = evas_object_smart_data_get(object))) return; - + evas_object_geometry_get(object, &x, &y, NULL, NULL); - evas_object_move(sd->edje_object, x, y + ((h - sd->minh) / 2)); - evas_object_resize(sd->edje_object, w, sd->minh); + evas_object_move(sd->entry_object, x, y + ((h - sd->height) * sd->valign)); + evas_object_resize(sd->entry_object, w, sd->height); } -static void -_e_entry_smart_show(Evas_Object *object) +static void _e_entry_smart_show(Evas_Object *object) { E_Entry_Smart_Data *sd; - + if ((!object) || !(sd = evas_object_smart_data_get(object))) return; - - evas_object_show(sd->edje_object); + evas_object_show(sd->entry_object); } -static void -_e_entry_smart_hide(Evas_Object *object) +static void _e_entry_smart_hide(Evas_Object *object) { E_Entry_Smart_Data *sd; - + if ((!object) || !(sd = evas_object_smart_data_get(object))) return; - - evas_object_hide(sd->edje_object); + evas_object_hide(sd->entry_object); +} + +static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a) +{ + E_Entry_Smart_Data *sd; + + if ((!object) || !(sd = evas_object_smart_data_get(object))) + return; + evas_object_color_set(sd->entry_object, r, g, b, a); +} + +static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip) +{ + E_Entry_Smart_Data *sd; + + if ((!object) || !(sd = evas_object_smart_data_get(object))) + return; + evas_object_clip_set(sd->entry_object, clip); +} + +static void _e_entry_clip_unset(Evas_Object *object) +{ + E_Entry_Smart_Data *sd; + + if ((!object) || !(sd = evas_object_smart_data_get(object))) + return; + evas_object_clip_unset(sd->entry_object); } diff --git a/src/bin/e_entry.h b/src/bin/e_entry.h index 6fc7a9225..92f275512 100644 --- a/src/bin/e_entry.h +++ b/src/bin/e_entry.h @@ -2,52 +2,20 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #ifdef E_TYPEDEFS - -typedef struct _E_Event_Entry_Change E_Event_Entry_Change; - #else #ifndef E_ENTRY_H #define E_ENTRY_H -struct _E_Event_Entry_Change -{ - Evas_Object *object; - char *keyname; - char *key; - char *string; -}; +EAPI Evas_Object *e_entry_add (Evas *evas); +EAPI void e_entry_text_set (Evas_Object *entry, const char *text); +EAPI const char *e_entry_text_get (Evas_Object *entry); +EAPI void e_entry_clear (Evas_Object *entry); -EAPI Evas_Object *e_editable_text_add(Evas *evas); -EAPI void e_editable_text_text_set(Evas_Object *object, const char *text); -EAPI const char *e_entry_text_get(Evas_Object *object); -EAPI void e_editable_text_insert(Evas_Object *object, const char *text); -EAPI void e_editable_text_delete_char_before(Evas_Object *object); -EAPI void e_editable_text_delete_char_after(Evas_Object *object); -EAPI void e_editable_text_cursor_move_at_start(Evas_Object *object); -EAPI void e_editable_text_cursor_move_at_end(Evas_Object *object); -EAPI void e_editable_text_cursor_move_left(Evas_Object *object); -EAPI void e_editable_text_cursor_move_right(Evas_Object *object); -EAPI void e_editable_text_cursor_show(Evas_Object *object); -EAPI void e_editable_text_cursor_hide(Evas_Object *object); - -EAPI int e_entry_init(void); -EAPI int e_entry_shutdown(void); -EAPI Evas_Object *e_entry_add(Evas *evas); -EAPI void e_entry_text_set (Evas_Object *entry, const char *text); -EAPI const char *e_editable_text_text_get(Evas_Object *object); -EAPI void e_entry_text_insert (Evas_Object *entry, const char *text); -EAPI void e_entry_delete_char_before(Evas_Object *object); -EAPI void e_entry_delete_char_after(Evas_Object *object); -EAPI void e_entry_cursor_move_at_start(Evas_Object *object); -EAPI void e_entry_cursor_move_at_end(Evas_Object *object); -EAPI void e_entry_cursor_move_left(Evas_Object *object); -EAPI void e_entry_cursor_move_right(Evas_Object *object); -EAPI void e_entry_cursor_show(Evas_Object *object); -EAPI void e_entry_cursor_hide(Evas_Object *object); -EAPI void e_entry_change_handler_set(Evas_Object *object, void (*func)(void *data, Evas_Object *entry, char *key), void *data); -EAPI void e_entry_focus(Evas_Object *object); -EAPI void e_entry_unfocus(Evas_Object *object); -EAPI void e_entry_min_size_get(Evas_Object *object, Evas_Coord *mw, Evas_Coord *mh); +EAPI void e_entry_min_size_get (Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh); +EAPI void e_entry_focus (Evas_Object *entry); +EAPI void e_entry_unfocus (Evas_Object *entry); +EAPI void e_entry_enable (Evas_Object *entry); +EAPI void e_entry_disable (Evas_Object *entry); #endif #endif diff --git a/src/bin/e_fileman_smart.c b/src/bin/e_fileman_smart.c index b0e5c2c27..bf024c9ab 100644 --- a/src/bin/e_fileman_smart.c +++ b/src/bin/e_fileman_smart.c @@ -970,9 +970,7 @@ _e_fm_file_rename_start(E_Fm_Icon *icon) { icon->sd->state = E_FILEMAN_STATE_RENAME; icon->sd->entry_obj = e_entry_add(icon->sd->evas); - evas_object_focus_set(icon->sd->entry_obj, 1); - evas_object_show(icon->sd->entry_obj); - e_entry_cursor_show(icon->sd->entry_obj); + e_entry_focus(icon->sd->entry_obj); e_fm_icon_edit_entry_set(icon->icon_obj, icon->sd->entry_obj); e_fm_icon_title_set(icon->icon_obj, ""); @@ -980,7 +978,6 @@ _e_fm_file_rename_start(E_Fm_Icon *icon) // e_fm_mouse_up_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, // _e_fm_win_mouse_up_cb, icon); //e_grabinput_get(icon->sd->win->evas_win, 1, icon->sd->win->evas_win); - e_entry_cursor_move_at_start(icon->sd->entry_obj); e_entry_text_set(icon->sd->entry_obj, icon->file->name); // e_fm_grab_time = ecore_time_get(); diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index c7e6afbf7..8d105e1f0 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -17,6 +17,7 @@ #include "e_menu.h" #include "e_icon.h" #include "e_box.h" +#include "e_editable.h" #include "e_entry.h" #include "e_init.h" #include "e_int_menus.h" diff --git a/src/bin/e_int_config_desklock.c b/src/bin/e_int_config_desklock.c index c9730232e..5f4d08157 100644 --- a/src/bin/e_int_config_desklock.c +++ b/src/bin/e_int_config_desklock.c @@ -237,7 +237,7 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf if (cfdata->auth_method == 0) e_widget_disabled_set(ob, 1); #endif _e_desklock_passwd_cb_change(cfdata, ob); - e_widget_entry_on_change_callback_set(ob, _e_desklock_passwd_cb_change, cfdata); + e_widget_on_change_hook_set(ob, _e_desklock_passwd_cb_change, cfdata); e_widget_min_size_set(ob, 200, 25); e_widget_framelist_object_append(of, ob); @@ -424,7 +424,7 @@ _advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data #endif _e_desklock_passwd_cb_change(cfdata, ob); - e_widget_entry_on_change_callback_set(ob, _e_desklock_passwd_cb_change, cfdata); + e_widget_on_change_hook_set(ob, _e_desklock_passwd_cb_change, cfdata); e_widget_min_size_set(ob, 200, 25); e_widget_framelist_object_append(of, ob); diff --git a/src/bin/e_widget_entry.c b/src/bin/e_widget_entry.c index eb90846c3..f7f3733ae 100644 --- a/src/bin/e_widget_entry.c +++ b/src/bin/e_widget_entry.c @@ -2,34 +2,112 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" - typedef struct _E_Widget_Data E_Widget_Data; struct _E_Widget_Data { Evas_Object *o_entry; - Evas_Object *obj; - char **valptr; - void (*on_change_func) (void *data, Evas_Object *obj); - void *on_change_data; + char **text_location; }; +/* local subsystem functions */ static void _e_wid_del_hook(Evas_Object *obj); static void _e_wid_focus_hook(Evas_Object *obj); static void _e_wid_disable_hook(Evas_Object *obj); -static void _e_wid_on_change_hook(void *data, Evas_Object *obj); -//static void _e_wid_signal_cb1(void *data, Evas_Object *obj, const char *emission, const char *source); static void _e_wid_focus_steal(void *data, Evas *e, Evas_Object *obj, void *event_info); -static void _e_wid_text_change(void *data, Evas_Object *entry, char *key); - -/* local subsystem functions */ +static void _e_wid_changed_cb(void *data, Evas_Object *obj, void *event_info); +/* externally accessible functions */ + +/** + * Creates a new entry widget + * + * @param evas the evas where to add the new entry widget + * @param text_location the location where to store the text of the entry. + * The current value will be used to initialize the entry + * @return Returns the new entry widget + */ +EAPI Evas_Object * +e_widget_entry_add(Evas *evas, char **text_location) +{ + Evas_Object *obj, *o; + E_Widget_Data *wd; + Evas_Coord minw, minh; + + obj = e_widget_add(evas); + + e_widget_del_hook_set(obj, _e_wid_del_hook); + e_widget_focus_hook_set(obj, _e_wid_focus_hook); + e_widget_disable_hook_set(obj, _e_wid_disable_hook); + + wd = calloc(1, sizeof(E_Widget_Data)); + e_widget_data_set(obj, wd); + wd->text_location = text_location; + + o = e_entry_add(evas); + wd->o_entry = o; + evas_object_show(o); + e_widget_sub_object_add(obj, o); + e_widget_resize_object_set(obj, o); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_focus_steal, obj); + + if ((text_location) && (*text_location)) + e_entry_text_set(o, *text_location); + + e_entry_min_size_get(o, &minw, &minh); + e_widget_min_size_set(obj, minw, minh); + + evas_object_smart_callback_add(o, "changed", _e_wid_changed_cb, obj); + + return obj; +} + +/** + * Sets the text of the entry widget + * + * @param entry an entry widget + * @param text the text to set + */ +EAPI void +e_widget_entry_text_set(Evas_Object *entry, const char *text) +{ + E_Widget_Data *wd; + + if (!(entry) || (!(wd = e_widget_data_get(entry)))) + return; + e_entry_text_set(wd->o_entry, text); +} + +/** + * Gets the text of the entry widget + * + * @param entry an entry widget + * @return Returns the text of the entry widget + */ +EAPI const char * +e_widget_entry_text_get(Evas_Object *entry) +{ + E_Widget_Data *wd; + + if (!(entry) || (!(wd = e_widget_data_get(entry)))) + return NULL; + return e_entry_text_get(wd->o_entry); +} + +/* TODO, TODOC */ +EAPI void +e_widget_entry_password_set(Evas_Object *obj, int password) +{ +} + +/* Private functions */ static void _e_wid_del_hook(Evas_Object *obj) { E_Widget_Data *wd; - - wd = e_widget_data_get(obj); + + if (!(obj) || (!(wd = e_widget_data_get(obj)))) + return; free(wd); } @@ -37,33 +115,28 @@ static void _e_wid_focus_hook(Evas_Object *obj) { E_Widget_Data *wd; + + if (!(obj) || (!(wd = e_widget_data_get(obj)))) + return; - wd = e_widget_data_get(obj); if (e_widget_focus_get(obj)) - { - e_entry_focus(wd->o_entry); - evas_object_focus_set(wd->o_entry, 1); - e_entry_cursor_move_at_end(wd->o_entry); - e_entry_cursor_show(wd->o_entry); - } + e_entry_focus(wd->o_entry); else - { - e_entry_unfocus(wd->o_entry); - evas_object_focus_set(wd->o_entry, 0); - e_entry_cursor_hide(wd->o_entry); - } + e_entry_unfocus(wd->o_entry); } static void _e_wid_disable_hook(Evas_Object *obj) { E_Widget_Data *wd; + + if (!(obj) || (!(wd = e_widget_data_get(obj)))) + return; - wd = e_widget_data_get(obj); if (e_widget_disabled_get(obj)) - edje_object_signal_emit(wd->o_entry, "disabled", ""); + e_entry_disable(wd->o_entry); else - edje_object_signal_emit(wd->o_entry, "enabled", ""); + e_entry_enable(wd->o_entry); } static void @@ -73,97 +146,21 @@ _e_wid_focus_steal(void *data, Evas *e, Evas_Object *obj, void *event_info) } static void -_e_wid_on_change_hook(void *data, Evas_Object *obj) -{ - E_Widget_Data *wd; - - wd = e_widget_data_get(obj); - if(wd->on_change_func) - wd->on_change_func(wd->on_change_data, obj); -} - -static void -_e_wid_text_change(void *data, Evas_Object *entry, char *key) +_e_wid_changed_cb(void *data, Evas_Object *obj, void *event_info) { + Evas_Object *entry; E_Widget_Data *wd; const char *text; + + if (!(entry = data) || (!(wd = e_widget_data_get(entry)))) + return; - wd = data; - E_FREE(*(wd->valptr)); - text = e_entry_text_get(wd->o_entry); - if (!text) - *(wd->valptr) = strdup(""); - else - *(wd->valptr) = strdup(text); - e_widget_change(wd->obj); -} - -/* externally accessible functions */ -EAPI Evas_Object * -e_widget_entry_add(Evas *evas, char **val) -{ - Evas_Object *obj, *o; - E_Widget_Data *wd; - Evas_Coord mw, mh; - - obj = e_widget_add(evas); - - e_widget_on_change_hook_set(obj, _e_wid_on_change_hook, NULL); - e_widget_del_hook_set(obj, _e_wid_del_hook); - e_widget_focus_hook_set(obj, _e_wid_focus_hook); - e_widget_disable_hook_set(obj, _e_wid_disable_hook); - wd = calloc(1, sizeof(E_Widget_Data)); - wd->valptr = val; - wd->obj = obj; - wd->on_change_func = NULL; - wd->on_change_data = NULL; - e_widget_data_set(obj, wd); - - o = e_entry_add(evas); - wd->o_entry = o; - evas_object_show(o); - e_entry_min_size_get(o, &mw, &mh); - e_widget_min_size_set(obj, mw, mh); - - if (*(wd->valptr)) - e_entry_text_set(wd->o_entry, *(wd->valptr)); - - e_widget_sub_object_add(obj, o); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_focus_steal, obj); - e_widget_resize_object_set(obj, o); - - e_entry_change_handler_set(wd->o_entry, _e_wid_text_change, wd); - - return obj; -} - -void -e_widget_entry_text_set(Evas_Object *entry, const char *text) -{ - E_Widget_Data *wd; - - wd = e_widget_data_get(entry); - e_entry_text_set(wd->o_entry, text); - E_FREE(*(wd->valptr)); - *(wd->valptr) = strdup(text); -} - -EAPI void -e_widget_entry_on_change_callback_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data) -{ - E_Widget_Data *wd; - - wd = e_widget_data_get(obj); - wd->on_change_func = func; - wd->on_change_data = data; -} - -EAPI void -e_widget_entry_password_set(Evas_Object *obj, int pw) -{ - E_Widget_Data *wd; - - wd = e_widget_data_get(obj); -// FIXME: need password mode for entry. -// e_entry_password_set(wd->o_entry, pw); + if (wd->text_location) + { + text = e_widget_entry_text_get(entry); + free(*wd->text_location); + *wd->text_location = text ? strdup(text) : NULL; + } + + e_widget_change(data); } diff --git a/src/bin/e_widget_entry.h b/src/bin/e_widget_entry.h index 8fa78eb73..ca5630012 100644 --- a/src/bin/e_widget_entry.h +++ b/src/bin/e_widget_entry.h @@ -6,10 +6,11 @@ #ifndef E_WIDGET_ENTRY_H #define E_WIDGET_ENTRY_H -EAPI Evas_Object *e_widget_entry_add(Evas *evas, char **val); -EAPI void e_widget_entry_text_set(Evas_Object *entry, const char *text); -EAPI void e_widget_entry_text_insert (Evas_Object *entry, const char *text); -EAPI void e_widget_entry_on_change_callback_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data); -EAPI void e_widget_entry_password_set(Evas_Object *obj, int pw); +EAPI Evas_Object *e_widget_entry_add (Evas *evas, char **text_location); +EAPI void e_widget_entry_text_set (Evas_Object *entry, const char *text); +EAPI const char *e_widget_entry_text_get (Evas_Object *entry); +EAPI void e_widget_entry_clear (Evas_Object *entry); +EAPI void e_widget_entry_password_set (Evas_Object *entry, int password); + #endif #endif