3 #define E_EDITABLE_CURSOR_MARGIN 5
5 #define E_EDITABLE_BLOCK_SIZE 128
6 #define E_EDITABLE_SIZE_TO_ALLOC(length) \
7 (((length) + (E_EDITABLE_BLOCK_SIZE - 1)) / E_EDITABLE_BLOCK_SIZE) * E_EDITABLE_BLOCK_SIZE
9 typedef struct _E_Editable_Smart_Data E_Editable_Smart_Data;
11 struct _E_Editable_Smart_Data
13 Evas_Object *clip_object;
14 Evas_Object *event_object;
15 Evas_Object *text_object;
16 Evas_Object *cursor_object;
17 Evas_Object *selection_object;
22 int selection_visible;
36 /* local subsystem functions */
37 static int _e_editable_text_insert(Evas_Object *editable, int pos, const char *text);
38 static int _e_editable_text_delete(Evas_Object *editable, int start, int end);
39 static void _e_editable_cursor_update(Evas_Object *editable);
40 static void _e_editable_selection_update(Evas_Object *editable);
41 static void _e_editable_text_update(Evas_Object *editable);
42 static void _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w);
43 static int _e_editable_char_geometry_get_from_pos(Evas_Object *editable, int utf_pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch);
45 static void _e_editable_smart_add(Evas_Object *object);
46 static void _e_editable_smart_del(Evas_Object *object);
47 static void _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
48 static void _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
49 static void _e_editable_smart_show(Evas_Object *object);
50 static void _e_editable_smart_hide(Evas_Object *object);
51 static void _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a);
52 static void _e_editable_clip_set(Evas_Object *object, Evas_Object *clip);
53 static void _e_editable_clip_unset(Evas_Object *object);
55 /* local subsystem globals */
56 static Evas_Smart *_e_editable_smart = NULL;
57 static int _e_editable_smart_use = 0;
59 /* externally accessible functions */
62 * Creates a new editable object. An editable object is an evas smart object in
63 * which the user can type some single-line text, select it and delete it.
65 * @param evas The evas where to add the editable object
66 * @return Returns the new editable object
69 e_editable_add(Evas *evas)
71 if (!_e_editable_smart)
73 static const Evas_Smart_Class sc =
76 EVAS_SMART_CLASS_VERSION,
77 _e_editable_smart_add,
78 _e_editable_smart_del,
79 _e_editable_smart_move,
80 _e_editable_smart_resize,
81 _e_editable_smart_show,
82 _e_editable_smart_hide,
83 _e_editable_color_set,
85 _e_editable_clip_unset,
94 _e_editable_smart = evas_smart_class_new(&sc);
95 _e_editable_smart_use = 0;
98 return evas_object_smart_add(evas, _e_editable_smart);
102 * Sets the theme group to be used by the editable object.
103 * This function has to be called, or the cursor and the selection won't be
106 * @param editable an editable object
107 * @param category the theme category to use for the editable object
108 * @param group the theme group to use for the editable object
111 e_editable_theme_set(Evas_Object *editable, const char *category, const char *group)
113 E_Editable_Smart_Data *sd;
117 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
119 if ((!category) || (!group)) return;
120 obj_group = alloca(strlen(group) + strlen("/selection") + 1);
122 /* Gets the theme for the text object */
123 sprintf(obj_group, "%s/text", group);
124 e_theme_edje_object_set(sd->text_object, category, obj_group);
125 sd->average_char_w = -1;
126 sd->average_char_h = -1;
128 /* Gets the theme for the cursor */
129 sprintf(obj_group, "%s/cursor", group);
130 e_theme_edje_object_set(sd->cursor_object, category, obj_group);
132 edje_object_size_min_get(sd->cursor_object, &sd->cursor_width, NULL);
133 if (sd->cursor_width < 1) sd->cursor_width = 1;
135 /* Gets the theme for the selection */
136 sprintf(obj_group, "%s/selection", group);
137 e_theme_edje_object_set(sd->selection_object, category, obj_group);
139 data = edje_object_data_get(sd->selection_object, "on_foreground");
140 if ((data) && (strcmp(data, "1") == 0))
142 sd->selection_on_fg = 1;
143 evas_object_stack_above(sd->selection_object, sd->text_object);
147 sd->selection_on_fg = 0;
148 evas_object_stack_below(sd->selection_object, sd->text_object);
151 _e_editable_text_update(editable);
152 _e_editable_cursor_update(editable);
156 * Sets whether or not the editable object is in password mode. In password
157 * mode, the editable object displays '*' instead of the characters
159 * @param editable an editable object
160 * @param password_mode 1 to turn on the password mode of the editable object,
164 e_editable_password_set(Evas_Object *editable, int password_mode)
166 E_Editable_Smart_Data *sd;
168 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
170 if (sd->password_mode == password_mode) return;
172 sd->password_mode = password_mode;
173 _e_editable_text_update(editable);
174 _e_editable_cursor_update(editable);
178 * Gets whether or not the editable is in password mode
180 * @param editable an editable object
181 * @return Returns 1 if the editable object is in the password mode, 0 otherwise
184 e_editable_password_get(Evas_Object *editable)
186 E_Editable_Smart_Data *sd;
188 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
190 return sd->password_mode;
194 * Sets the text of the editable object
196 * @param editable an editable object
197 * @param text the text to set
200 e_editable_text_set(Evas_Object *editable, const char *text)
202 E_Editable_Smart_Data *sd;
204 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
207 if (sd->password_mode) memset(sd->text, 0, sd->char_length);
211 sd->unicode_length = 0;
212 sd->allocated_length = -1;
214 if (_e_editable_text_insert(editable, 0, text) <= 0)
216 sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
219 sd->unicode_length = 0;
220 sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
221 _e_editable_text_update(editable);
224 sd->cursor_pos = sd->unicode_length;
225 sd->selection_pos = sd->unicode_length;
226 _e_editable_cursor_update(editable);
230 * Gets the entire text of the editable object
232 * @param editable an editable object
233 * @return Returns the entire text of the editable object
236 e_editable_text_get(Evas_Object *editable)
238 E_Editable_Smart_Data *sd;
240 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
246 * Gets a range of the text of the editable object, from position @a start to
249 * @param editable an editable object
250 * @param start the start position of the text range to get
251 * @param end the end position of the text range to get
252 * @return Returns the range of text. The returned string will have to be freed
255 e_editable_text_range_get(Evas_Object *editable, int start, int end)
257 E_Editable_Smart_Data *sd;
259 int start_id = 0, end_id = 0, i;
261 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
264 start = E_CLAMP(start, 0, sd->unicode_length);
265 end = E_CLAMP(end, 0, sd->unicode_length);
266 if (end <= start) return NULL;
268 for (i = 0; i < end; i++)
270 end_id = evas_string_char_next_get(sd->text, end_id, NULL);
271 if (i < start) start_id = end_id;
274 if (end_id <= start_id) return NULL;
276 range = malloc((end_id - start_id + 1) * sizeof(char));
277 strncpy(range, &sd->text[start_id], end_id - start_id);
278 range[end_id - start_id] = '\0';
284 * Gets the unicode length of the text of the editable object. The unicode
285 * length is not always the length returned by strlen() since a UTF-8 char can
288 * @param editable an editable object
289 * @return Returns the unicode length of the text of the editable object
292 e_editable_text_length_get(Evas_Object *editable)
294 E_Editable_Smart_Data *sd;
296 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
298 return sd->unicode_length;
302 * Inserts some text at the given position in the editable object
304 * @param editable the editable object in which the text should be inserted
305 * @param pos the position where to insert the text
306 * @param text the text to insert
307 * @return Returns 1 if the text has been modified, 0 otherwise
310 e_editable_insert(Evas_Object *editable, int pos, const char *text)
312 E_Editable_Smart_Data *sd;
315 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
318 unicode_length = _e_editable_text_insert(editable, pos, text);
319 if (unicode_length <= 0) return 0;
321 if (sd->cursor_pos >= pos)
322 e_editable_cursor_pos_set(editable, sd->cursor_pos + unicode_length);
323 if (sd->selection_pos >= pos)
324 e_editable_selection_pos_set(editable, sd->selection_pos + unicode_length);
326 _e_editable_text_position_update(editable, -1);
331 * Deletes the text of the editable object, between position "start" and
334 * @param editable the editable object in which the text should be deleted
335 * @param start the position of the first char to delete
336 * @param end the position of the last char to delete
337 * @return Returns 1 if the text has been modified, 0 otherwise
340 e_editable_delete(Evas_Object *editable, int start, int end)
342 E_Editable_Smart_Data *sd;
345 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
348 unicode_length = _e_editable_text_delete(editable, start, end);
349 if (unicode_length <= 0) return 0;
351 if (sd->cursor_pos > end)
352 e_editable_cursor_pos_set(editable, sd->cursor_pos - unicode_length);
353 else if (sd->cursor_pos > start)
354 e_editable_cursor_pos_set(editable, start);
356 if (sd->selection_pos > end)
357 e_editable_selection_pos_set(editable, sd->selection_pos - unicode_length);
358 else if (sd->selection_pos > start)
359 e_editable_selection_pos_set(editable, start);
361 _e_editable_text_position_update(editable, -1);
366 * Moves the cursor of the editable object to the given position
368 * @param editable an editable object
369 * @param pos the position where to move the cursor
372 e_editable_cursor_pos_set(Evas_Object *editable, int pos)
374 E_Editable_Smart_Data *sd;
376 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
379 pos = E_CLAMP(pos, 0, sd->unicode_length);
380 if ((sd->cursor_pos == pos)) return;
382 sd->cursor_pos = pos;
383 _e_editable_cursor_update(editable);
387 * Gets the position of the cursor of the editable object
389 * @param editable an editable object
390 * @return Returns the position of the cursor of the editable object
393 e_editable_cursor_pos_get(Evas_Object *editable)
395 E_Editable_Smart_Data *sd;
397 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
399 return sd->cursor_pos;
403 * Moves the cursor to the start of the editable object
405 * @param editable an editable object
408 e_editable_cursor_move_to_start(Evas_Object *editable)
412 e_editable_cursor_pos_set(editable, 0);
416 * Moves the cursor to the end of the editable object
418 * @param editable an editable object
421 e_editable_cursor_move_to_end(Evas_Object *editable)
423 E_Editable_Smart_Data *sd;
425 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
427 e_editable_cursor_pos_set(editable, sd->unicode_length);
431 * Moves the cursor backward by one character offset
433 * @param editable an editable object
436 e_editable_cursor_move_left(Evas_Object *editable)
438 E_Editable_Smart_Data *sd;
440 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
442 e_editable_cursor_pos_set(editable, sd->cursor_pos - 1);
446 * Moves the cursor forward by one character offset
448 * @param editable an editable object
451 e_editable_cursor_move_right(Evas_Object *editable)
453 E_Editable_Smart_Data *sd;
455 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
457 e_editable_cursor_pos_set(editable, sd->cursor_pos + 1);
461 * Shows the cursor of the editable object
463 * @param editable the editable object whose cursor should be shown
466 e_editable_cursor_show(Evas_Object *editable)
468 E_Editable_Smart_Data *sd;
470 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
472 if (sd->cursor_visible) return;
474 sd->cursor_visible = 1;
475 if (evas_object_visible_get(editable))
477 evas_object_show(sd->cursor_object);
478 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
483 * Hides the cursor of the editable object
485 * @param editable the editable object whose cursor should be hidden
488 e_editable_cursor_hide(Evas_Object *editable)
490 E_Editable_Smart_Data *sd;
492 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
494 if (!sd->cursor_visible) return;
496 sd->cursor_visible = 0;
497 evas_object_hide(sd->cursor_object);
501 * Moves the selection bound of the editable object to the given position
503 * @param editable an editable object
504 * @param pos the position where to move the selection bound
507 e_editable_selection_pos_set(Evas_Object *editable, int pos)
509 E_Editable_Smart_Data *sd;
511 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
514 pos = E_CLAMP(pos, 0, sd->unicode_length);
515 if (sd->selection_pos == pos) return;
517 sd->selection_pos = pos;
518 _e_editable_selection_update(editable);
522 * Gets the position of the selection bound of the editable object
524 * @param editable an editable object
525 * @return Returns the position of the selection bound of the editable object
528 e_editable_selection_pos_get(Evas_Object *editable)
530 E_Editable_Smart_Data *sd;
532 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
534 return sd->selection_pos;
538 * Moves the selection bound to the start of the editable object
540 * @param editable an editable object
543 e_editable_selection_move_to_start(Evas_Object *editable)
547 e_editable_selection_pos_set(editable, 0);
551 * Moves the selection bound to the end of the editable object
553 * @param editable an editable object
556 e_editable_selection_move_to_end(Evas_Object *editable)
558 E_Editable_Smart_Data *sd;
560 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
562 e_editable_selection_pos_set(editable, sd->unicode_length);
566 * Moves the selection bound backward by one character offset
568 * @param editable an editable object
571 e_editable_selection_move_left(Evas_Object *editable)
573 E_Editable_Smart_Data *sd;
575 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
577 e_editable_selection_pos_set(editable, sd->selection_pos - 1);
581 * Moves the selection bound forward by one character offset
583 * @param editable an editable object
586 e_editable_selection_move_right(Evas_Object *editable)
588 E_Editable_Smart_Data *sd;
590 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
592 e_editable_selection_pos_set(editable, sd->selection_pos + 1);
596 * Selects all the text of the editable object. The selection bound will be
597 * moved to the start of the editable object and the cursor will be moved to
600 * @param editable an editable object
603 e_editable_select_all(Evas_Object *editable)
605 if (!editable) return;
606 e_editable_selection_move_to_start(editable);
607 e_editable_cursor_move_to_end(editable);
611 * Unselects all the text of the editable object. The selection bound will be
612 * moved to the cursor position
614 * @param editable an editable object
617 e_editable_unselect_all(Evas_Object *editable)
619 E_Editable_Smart_Data *sd;
621 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
623 e_editable_selection_pos_set(editable, sd->cursor_pos);
627 * Selects the word at the provided character index
630 e_editable_select_word(Evas_Object *editable, int index)
632 E_Editable_Smart_Data *sd;
633 int spos = 0, epos = -1, i = 0, pos = 0;
635 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
637 if ((index < 0) || (index >= sd->unicode_length)) return;
639 while (i < sd->char_length)
641 if (sd->text[i] == ' ')
643 if (pos < index) spos = pos + 1;
644 else if (pos > index)
650 i = evas_string_char_next_get(sd->text, i, NULL);
653 if (epos == -1) epos = pos;
654 e_editable_selection_pos_set(editable, spos);
655 e_editable_cursor_pos_set(editable, epos);
659 * Shows the selection of the editable object
661 * @param editable an editable object
664 e_editable_selection_show(Evas_Object *editable)
666 E_Editable_Smart_Data *sd;
668 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
670 if (sd->selection_visible) return;
671 sd->selection_visible = 1;
672 if ((evas_object_visible_get(editable)) &&
673 (sd->cursor_pos != sd->selection_pos))
674 evas_object_show(sd->selection_object);
678 * Hides the selection of the editable object
680 * @param editable an editable object
683 e_editable_selection_hide(Evas_Object *editable)
685 E_Editable_Smart_Data *sd;
687 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
689 if (!sd->selection_visible) return;
690 sd->selection_visible = 0;
691 evas_object_hide(sd->selection_object);
695 * Gets the cursor position at the coords ( @a x, @a y ). It's used to know
696 * where to place the cursor or the selection bound on mouse evevents.
698 * @param editable an editable object
699 * @param x the x coord, relative to the editable object
700 * @param y the y coord, relative to the editable object
701 * @return Returns the position where to place the cursor according to the
705 e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y)
707 E_Editable_Smart_Data *sd;
708 const Evas_Object *text_obj;
710 Evas_Coord tx, ty, tw, th;
712 Evas_Coord canvas_x, canvas_y;
713 int index, pos, i, j;
716 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
718 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
721 evas_object_geometry_get(editable, &ox, &oy, NULL, NULL);
722 evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th);
726 if ((canvas_y < ty) || (canvas_x < tx))
728 else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw)))
729 pos = sd->unicode_length;
732 index = evas_object_text_char_coords_get(text_obj,
733 canvas_x - tx, canvas_y - ty,
734 &cx, NULL, &cw, NULL);
735 text = evas_object_text_text_get(text_obj);
736 if ((index >= 0) && (text))
738 if ((canvas_x - tx) > (cx + (cw / 2))) index++;
743 while ((i < index) && (j != i))
747 i = evas_string_char_next_get(text, i, NULL);
749 if (pos > sd->unicode_length) pos = sd->unicode_length;
757 * A utility function to get the average size of a character written inside
758 * the editable object
760 * @param editable an editable object
761 * @param w the location where to store the average width of a character
762 * @param h the location where to store the average height of a character
765 e_editable_char_size_get(Evas_Object *editable, int *w, int *h)
769 const Evas_Object *text_obj;
771 E_Editable_Smart_Data *sd;
772 char *text = "Tout est bon dans l'abricot sauf le noyau!"
773 "Wakey wakey! Eggs and Bakey!";
774 const char *font, *font_source;
775 Evas_Text_Style_Type style;
780 if ((!editable) || (!(evas = evas_object_evas_get(editable))))
782 if (!(sd = evas_object_smart_data_get(editable))) return;
783 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
786 if ((sd->average_char_w <= 0) || (sd->average_char_h <= 0))
788 font_source = evas_object_text_font_source_get(text_obj);
789 evas_object_text_font_get(text_obj, &font, &font_size);
790 style = evas_object_text_style_get(text_obj);
792 obj = evas_object_text_add(evas);
793 evas_object_scale_set(obj, edje_scale_get());
794 evas_object_text_font_source_set(obj, font_source);
795 evas_object_text_font_set(obj, font, font_size);
796 evas_object_text_style_set(obj, style);
797 evas_object_text_text_set(obj, text);
798 evas_object_geometry_get(obj, NULL, NULL, &tw, &th);
799 evas_object_del(obj);
800 sd->average_char_w = (tw / strlen(text));
801 sd->average_char_h = th;
803 if (w) *w = sd->average_char_w;
804 if (h) *h = sd->average_char_h;
808 e_editable_enable(Evas_Object *editable)
810 E_Editable_Smart_Data *sd;
812 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
815 edje_object_signal_emit(sd->text_object, "e,state,enabled", "e");
819 e_editable_disable(Evas_Object *editable)
821 E_Editable_Smart_Data *sd;
823 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
826 edje_object_signal_emit(sd->text_object, "e,state,disabled", "e");
828 /* Private functions */
830 /* A utility function to insert some text inside the editable object.
831 * It doesn't update the position of the cursor, nor the selection... */
833 _e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
835 E_Editable_Smart_Data *sd;
836 int char_length = -1, unicode_length = -1;
837 int prev_char_length, new_char_length, new_unicode_length;
838 int index = 0, i = 0;
840 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
842 if ((!text) || (*text == '\0')) return 0;
844 if (pos < 0) pos = 0;
845 else if (pos > sd->unicode_length)
846 pos = sd->unicode_length;
848 for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL))
854 for (i = 0; i < pos; i++)
855 index = evas_string_char_next_get(sd->text, index, NULL);
857 if ((unicode_length <= 0) || (char_length <= 0)) return 0;
859 prev_char_length = sd->char_length;
860 new_char_length = sd->char_length + char_length;
861 new_unicode_length = sd->unicode_length + unicode_length;
863 if (new_char_length > sd->allocated_length)
865 int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length);
866 char *old = sd->text;
868 if (sd->password_mode)
870 /* security -- copy contents into new buffer, and overwrite old contents */
871 sd->text = malloc(new_allocated_length + 1);
879 memcpy(sd->text, old, prev_char_length + 1);
880 memset(old, 0, prev_char_length);
886 sd->text = realloc(sd->text, new_allocated_length + 1);
893 sd->allocated_length = new_allocated_length;
895 sd->unicode_length = new_unicode_length;
896 sd->char_length = new_char_length;
898 if (prev_char_length > index)
899 memmove(&sd->text[index + char_length], &sd->text[index], prev_char_length - index);
900 strncpy(&sd->text[index], text, char_length);
901 sd->text[sd->char_length] = '\0';
903 _e_editable_text_update(editable);
904 return unicode_length;
907 /* A utility function to delete a range of text from the editable object.
908 * It doesn't update the position of the cursor, nor the selection... */
910 _e_editable_text_delete(Evas_Object *editable, int start, int end)
912 E_Editable_Smart_Data *sd;
913 int start_id = 0, end_id = 0, i = 0;
915 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
918 start = E_CLAMP(start, 0, sd->unicode_length);
919 end = E_CLAMP(end, 0, sd->unicode_length);
920 if (end <= start) return 0;
922 for (i = 0; i < end; i++)
924 end_id = evas_string_char_next_get(sd->text, end_id, NULL);
925 if (i < start) start_id = end_id;
928 if (end_id <= start_id) return 0;
930 memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id);
931 sd->char_length -= (end_id - start_id);
932 sd->unicode_length -= (end - start);
933 sd->text[sd->char_length] = '\0';
935 _e_editable_text_update(editable);
937 return (end - start);
940 /* Updates the position of the cursor
941 * It also updates automatically the text position and the selection */
943 _e_editable_cursor_update(Evas_Object *editable)
945 E_Editable_Smart_Data *sd;
946 const Evas_Object *text_obj;
948 Evas_Coord cx, cy, ch;
950 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
952 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
955 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
956 _e_editable_char_geometry_get_from_pos(editable, sd->cursor_pos,
957 &cx, &cy, NULL, &ch);
959 evas_object_move(sd->cursor_object, tx + cx, ty + cy);
960 evas_object_resize(sd->cursor_object, sd->cursor_width, ch);
962 if (sd->cursor_visible && evas_object_visible_get(editable))
964 evas_object_show(sd->cursor_object);
965 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
968 _e_editable_selection_update(editable);
969 _e_editable_text_position_update(editable, -1);
972 /* Updates the selection of the editable object */
974 _e_editable_selection_update(Evas_Object *editable)
976 E_Editable_Smart_Data *sd;
977 const Evas_Object *text_obj;
980 Evas_Coord sx, sy, sw, sh;
981 int start_pos, end_pos;
983 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
985 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
988 if ((sd->cursor_pos == sd->selection_pos) || (!sd->selection_visible))
989 evas_object_hide(sd->selection_object);
992 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
993 start_pos = (sd->cursor_pos <= sd->selection_pos) ?
994 sd->cursor_pos : sd->selection_pos;
995 end_pos = (sd->cursor_pos >= sd->selection_pos) ?
996 sd->cursor_pos : sd->selection_pos;
998 _e_editable_char_geometry_get_from_pos(editable, start_pos,
999 &cx, &cy, NULL, NULL);
1003 _e_editable_char_geometry_get_from_pos(editable, end_pos,
1004 &cx, NULL, NULL, &sh);
1007 evas_object_move(sd->selection_object, sx, sy);
1008 evas_object_resize(sd->selection_object, sw, sh);
1009 evas_object_show(sd->selection_object);
1013 /* Updates the text of the text object of the editable object
1014 * (it fills it with '*' if the editable is in password mode)
1015 * It does not update the position of the text */
1017 _e_editable_text_update(Evas_Object *editable)
1019 E_Editable_Smart_Data *sd;
1020 Evas_Coord minw, minh;
1022 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1025 if (sd->password_mode)
1029 text = malloc((sd->unicode_length + 1) * sizeof(char));
1030 memset(text, '*', sd->unicode_length * sizeof(char));
1031 text[sd->unicode_length] = '\0';
1032 edje_object_part_text_set(sd->text_object, "e.text.text", text);
1036 edje_object_part_text_set(sd->text_object, "e.text.text", sd->text);
1038 edje_object_size_min_calc(sd->text_object, &minw, &minh);
1039 evas_object_resize(sd->text_object, minw, minh);
1042 /* Updates the position of the text object according to the position of the
1043 * cursor (we make sure the cursor is visible) */
1045 _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w)
1047 E_Editable_Smart_Data *sd;
1048 Evas_Coord ox, oy, ow;
1049 Evas_Coord tx, ty, tw;
1050 Evas_Coord cx, cy, cw;
1052 Evas_Coord offset_x = 0;
1054 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1057 evas_object_geometry_get(editable, &ox, &oy, &ow, NULL);
1058 if (real_w >= 0) ow = real_w;
1059 evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, NULL);
1060 evas_object_geometry_get(sd->cursor_object, &cx, &cy, &cw, NULL);
1061 evas_object_geometry_get(sd->selection_object, &sx, &sy, NULL, NULL);
1065 else if (cx < (ox + E_EDITABLE_CURSOR_MARGIN))
1066 offset_x = ox + E_EDITABLE_CURSOR_MARGIN - cx;
1067 else if ((cx + cw + E_EDITABLE_CURSOR_MARGIN) > (ox + ow))
1068 offset_x = (ox + ow) - (cx + cw + E_EDITABLE_CURSOR_MARGIN);
1072 if ((tx + offset_x) > ox)
1074 else if ((tx + tw + offset_x) < (ox + ow))
1075 offset_x = (ox + ow) - (tx + tw);
1080 evas_object_move(sd->text_object, tx + offset_x, ty);
1081 evas_object_move(sd->cursor_object, cx + offset_x, cy);
1082 evas_object_move(sd->selection_object, sx + offset_x, sy);
1086 /* Gets the geometry of the char according to its utf-8 pos */
1088 _e_editable_char_geometry_get_from_pos(Evas_Object *editable, int utf_pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
1090 E_Editable_Smart_Data *sd;
1091 const Evas_Object *text_obj;
1094 int index = 0, i, last_pos, ret;
1101 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1103 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1106 text = evas_object_text_text_get(text_obj);
1107 if ((!text) || (sd->unicode_length <= 0) || (utf_pos <= 0))
1109 e_editable_char_size_get(editable, cw, ch);
1114 if (utf_pos >= sd->unicode_length)
1116 utf_pos = sd->unicode_length - 1;
1122 for (i = 0; i < utf_pos; i++)
1123 index = evas_string_char_next_get(text, index, NULL);
1125 ret = evas_object_text_char_pos_get(text_obj, index, &x, cy, &w, ch);
1126 if (cx) *cx = x - 1 + (last_pos ? w : 0);
1127 if (cw) *cw = last_pos ? 1 : w;
1132 /* Editable object's smart methods */
1135 _e_editable_smart_add(Evas_Object *object)
1138 E_Editable_Smart_Data *sd;
1141 if ((!object) || !(evas = evas_object_evas_get(object)))
1144 sd = malloc(sizeof(E_Editable_Smart_Data));
1147 _e_editable_smart_use++;
1148 evas_object_smart_data_set(object, sd);
1149 evas_object_geometry_get(object, &ox, &oy, NULL, NULL);
1151 sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
1153 sd->char_length = 0;
1154 sd->unicode_length = 0;
1155 sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
1157 sd->cursor_width = 1;
1158 sd->selection_on_fg = 0;
1159 sd->average_char_w = -1;
1160 sd->average_char_h = -1;
1163 sd->cursor_visible = 1;
1164 sd->selection_pos = 0;
1165 sd->selection_visible = 1;
1166 sd->password_mode = 0;
1168 sd->clip_object = evas_object_rectangle_add(evas);
1169 evas_object_move(sd->clip_object, ox, oy);
1170 evas_object_smart_member_add(sd->clip_object, object);
1172 sd->event_object = evas_object_rectangle_add(evas);
1173 evas_object_color_set(sd->event_object, 0, 0, 0, 0);
1174 evas_object_clip_set(sd->event_object, sd->clip_object);
1175 evas_object_move(sd->event_object, ox, oy);
1176 evas_object_smart_member_add(sd->event_object, object);
1178 sd->text_object = edje_object_add(evas);
1179 evas_object_pass_events_set(sd->text_object, 1);
1180 evas_object_clip_set(sd->text_object, sd->clip_object);
1181 evas_object_move(sd->text_object, ox, oy);
1182 evas_object_smart_member_add(sd->text_object, object);
1184 sd->selection_object = edje_object_add(evas);
1185 evas_object_pass_events_set(sd->selection_object, 1);
1186 evas_object_clip_set(sd->selection_object, sd->clip_object);
1187 evas_object_move(sd->selection_object, ox, oy);
1188 evas_object_smart_member_add(sd->selection_object, object);
1190 sd->cursor_object = edje_object_add(evas);
1191 evas_object_pass_events_set(sd->cursor_object, 1);
1192 evas_object_clip_set(sd->cursor_object, sd->clip_object);
1193 evas_object_move(sd->cursor_object, ox, oy);
1194 evas_object_smart_member_add(sd->cursor_object, object);
1196 _e_editable_cursor_update(object);
1199 /* Deletes the editable */
1201 _e_editable_smart_del(Evas_Object *object)
1203 E_Editable_Smart_Data *sd;
1205 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1208 evas_object_del(sd->clip_object);
1209 evas_object_del(sd->event_object);
1210 evas_object_del(sd->text_object);
1211 evas_object_del(sd->cursor_object);
1212 evas_object_del(sd->selection_object);
1213 /* Security - clear out memory that contained a password */
1214 if (sd->password_mode) memset(sd->text, 0, sd->char_length);
1218 _e_editable_smart_use--;
1219 if (_e_editable_smart_use <= 0)
1221 evas_smart_free(_e_editable_smart);
1222 _e_editable_smart = NULL;
1226 /* Moves the editable object */
1228 _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1230 E_Editable_Smart_Data *sd;
1231 Evas_Coord prev_x, prev_y;
1234 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1237 evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1238 evas_object_move(sd->clip_object, x, y);
1239 evas_object_move(sd->event_object, x, y);
1240 evas_object_geometry_get(sd->text_object, &ox, &oy, NULL, NULL);
1241 evas_object_move(sd->text_object, ox + (x - prev_x), oy + (y - prev_y));
1242 evas_object_geometry_get(sd->cursor_object, &ox, &oy, NULL, NULL);
1243 evas_object_move(sd->cursor_object, ox + (x - prev_x), oy + (y - prev_y));
1244 evas_object_geometry_get(sd->selection_object, &ox, &oy, NULL, NULL);
1245 evas_object_move(sd->selection_object, ox + (x - prev_x), oy + (y - prev_y));
1248 /* Resizes the editable object */
1250 _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1252 E_Editable_Smart_Data *sd;
1254 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1257 evas_object_resize(sd->clip_object, w, h);
1258 evas_object_resize(sd->event_object, w, h);
1259 _e_editable_text_position_update(object, w);
1262 /* Shows the editable object */
1264 _e_editable_smart_show(Evas_Object *object)
1266 E_Editable_Smart_Data *sd;
1268 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1271 evas_object_show(sd->clip_object);
1272 evas_object_show(sd->event_object);
1273 evas_object_show(sd->text_object);
1275 if (sd->cursor_visible)
1277 evas_object_show(sd->cursor_object);
1278 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1281 if ((sd->selection_visible) && (sd->cursor_pos != sd->selection_pos))
1282 evas_object_show(sd->selection_object);
1285 /* Hides the editable object */
1287 _e_editable_smart_hide(Evas_Object *object)
1289 E_Editable_Smart_Data *sd;
1291 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1294 evas_object_hide(sd->clip_object);
1295 evas_object_hide(sd->event_object);
1296 evas_object_hide(sd->text_object);
1297 evas_object_hide(sd->cursor_object);
1298 evas_object_hide(sd->selection_object);
1301 /* Changes the color of the editable object */
1303 _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a)
1305 E_Editable_Smart_Data *sd;
1307 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1309 evas_object_color_set(sd->clip_object, r, g, b, a);
1312 /* Clips the editable object against "clip" */
1314 _e_editable_clip_set(Evas_Object *object, Evas_Object *clip)
1316 E_Editable_Smart_Data *sd;
1318 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1320 evas_object_clip_set(sd->clip_object, clip);
1323 /* Unclips the editable object */
1325 _e_editable_clip_unset(Evas_Object *object)
1327 E_Editable_Smart_Data *sd;
1329 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1331 evas_object_clip_unset(sd->clip_object);