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 * Gets the geometry of the cursor of the editable object
405 * @param editable an editable object
406 * @param cx the x of the cursor
407 * @param cy the y of the cursor
408 * @param cw the width of the cursor
409 * @param ch the height of the cursor
412 e_editable_cursor_geometry_get(Evas_Object *editable, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
414 E_Editable_Smart_Data *sd;
416 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
419 evas_object_geometry_get(sd->cursor_object, cx, cy, cw, ch);
423 * Moves the cursor to the start of the editable object
425 * @param editable an editable object
428 e_editable_cursor_move_to_start(Evas_Object *editable)
432 e_editable_cursor_pos_set(editable, 0);
436 * Moves the cursor to the end of the editable object
438 * @param editable an editable object
441 e_editable_cursor_move_to_end(Evas_Object *editable)
443 E_Editable_Smart_Data *sd;
445 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
447 e_editable_cursor_pos_set(editable, sd->unicode_length);
451 * Moves the cursor backward by one character offset
453 * @param editable an editable object
456 e_editable_cursor_move_left(Evas_Object *editable)
458 E_Editable_Smart_Data *sd;
460 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
462 e_editable_cursor_pos_set(editable, sd->cursor_pos - 1);
466 * Moves the cursor forward by one character offset
468 * @param editable an editable object
471 e_editable_cursor_move_right(Evas_Object *editable)
473 E_Editable_Smart_Data *sd;
475 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
477 e_editable_cursor_pos_set(editable, sd->cursor_pos + 1);
481 * Shows the cursor of the editable object
483 * @param editable the editable object whose cursor should be shown
486 e_editable_cursor_show(Evas_Object *editable)
488 E_Editable_Smart_Data *sd;
490 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
492 if (sd->cursor_visible) return;
494 sd->cursor_visible = 1;
495 if (evas_object_visible_get(editable))
497 evas_object_show(sd->cursor_object);
498 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
503 * Hides the cursor of the editable object
505 * @param editable the editable object whose cursor should be hidden
508 e_editable_cursor_hide(Evas_Object *editable)
510 E_Editable_Smart_Data *sd;
512 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
514 if (!sd->cursor_visible) return;
516 sd->cursor_visible = 0;
517 evas_object_hide(sd->cursor_object);
521 * Moves the selection bound of the editable object to the given position
523 * @param editable an editable object
524 * @param pos the position where to move the selection bound
527 e_editable_selection_pos_set(Evas_Object *editable, int pos)
529 E_Editable_Smart_Data *sd;
531 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
534 pos = E_CLAMP(pos, 0, sd->unicode_length);
535 if (sd->selection_pos == pos) return;
537 sd->selection_pos = pos;
538 _e_editable_selection_update(editable);
542 * Gets the position of the selection bound of the editable object
544 * @param editable an editable object
545 * @return Returns the position of the selection bound of the editable object
548 e_editable_selection_pos_get(Evas_Object *editable)
550 E_Editable_Smart_Data *sd;
552 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
554 return sd->selection_pos;
558 * Moves the selection bound to the start of the editable object
560 * @param editable an editable object
563 e_editable_selection_move_to_start(Evas_Object *editable)
567 e_editable_selection_pos_set(editable, 0);
571 * Moves the selection bound to the end of the editable object
573 * @param editable an editable object
576 e_editable_selection_move_to_end(Evas_Object *editable)
578 E_Editable_Smart_Data *sd;
580 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
582 e_editable_selection_pos_set(editable, sd->unicode_length);
586 * Moves the selection bound backward by one character offset
588 * @param editable an editable object
591 e_editable_selection_move_left(Evas_Object *editable)
593 E_Editable_Smart_Data *sd;
595 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
597 e_editable_selection_pos_set(editable, sd->selection_pos - 1);
601 * Moves the selection bound forward by one character offset
603 * @param editable an editable object
606 e_editable_selection_move_right(Evas_Object *editable)
608 E_Editable_Smart_Data *sd;
610 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
612 e_editable_selection_pos_set(editable, sd->selection_pos + 1);
616 * Selects all the text of the editable object. The selection bound will be
617 * moved to the start of the editable object and the cursor will be moved to
620 * @param editable an editable object
623 e_editable_select_all(Evas_Object *editable)
625 if (!editable) return;
626 e_editable_selection_move_to_start(editable);
627 e_editable_cursor_move_to_end(editable);
631 * Unselects all the text of the editable object. The selection bound will be
632 * moved to the cursor position
634 * @param editable an editable object
637 e_editable_unselect_all(Evas_Object *editable)
639 E_Editable_Smart_Data *sd;
641 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
643 e_editable_selection_pos_set(editable, sd->cursor_pos);
647 * Selects the word at the provided character index
650 e_editable_select_word(Evas_Object *editable, int index)
652 E_Editable_Smart_Data *sd;
653 int spos = 0, epos = -1, i = 0, pos = 0;
655 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
657 if ((index < 0) || (index >= sd->unicode_length)) return;
659 while (i < sd->char_length)
661 if (sd->text[i] == ' ')
663 if (pos < index) spos = pos + 1;
664 else if (pos > index)
670 i = evas_string_char_next_get(sd->text, i, NULL);
673 if (epos == -1) epos = pos;
674 e_editable_selection_pos_set(editable, spos);
675 e_editable_cursor_pos_set(editable, epos);
679 * Shows the selection of the editable object
681 * @param editable an editable object
684 e_editable_selection_show(Evas_Object *editable)
686 E_Editable_Smart_Data *sd;
688 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
690 if (sd->selection_visible) return;
691 sd->selection_visible = 1;
692 if ((evas_object_visible_get(editable)) &&
693 (sd->cursor_pos != sd->selection_pos))
694 evas_object_show(sd->selection_object);
698 * Hides the selection of the editable object
700 * @param editable an editable object
703 e_editable_selection_hide(Evas_Object *editable)
705 E_Editable_Smart_Data *sd;
707 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
709 if (!sd->selection_visible) return;
710 sd->selection_visible = 0;
711 evas_object_hide(sd->selection_object);
715 * Gets the cursor position at the coords ( @a x, @a y ). It's used to know
716 * where to place the cursor or the selection bound on mouse evevents.
718 * @param editable an editable object
719 * @param x the x coord, relative to the editable object
720 * @param y the y coord, relative to the editable object
721 * @return Returns the position where to place the cursor according to the
725 e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y)
727 E_Editable_Smart_Data *sd;
728 const Evas_Object *text_obj;
730 Evas_Coord tx, ty, tw, th;
732 Evas_Coord canvas_x, canvas_y;
733 int index, pos, i, j;
736 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
738 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
741 evas_object_geometry_get(editable, &ox, &oy, NULL, NULL);
742 evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th);
746 if ((canvas_y < ty) || (canvas_x < tx))
748 else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw)))
749 pos = sd->unicode_length;
752 index = evas_object_text_char_coords_get(text_obj,
753 canvas_x - tx, canvas_y - ty,
754 &cx, NULL, &cw, NULL);
755 text = evas_object_text_text_get(text_obj);
756 if ((index >= 0) && (text))
758 if ((canvas_x - tx) > (cx + (cw / 2))) index++;
763 while ((i < index) && (j != i))
767 i = evas_string_char_next_get(text, i, NULL);
769 if (pos > sd->unicode_length) pos = sd->unicode_length;
777 * A utility function to get the average size of a character written inside
778 * the editable object
780 * @param editable an editable object
781 * @param w the location where to store the average width of a character
782 * @param h the location where to store the average height of a character
785 e_editable_char_size_get(Evas_Object *editable, int *w, int *h)
789 const Evas_Object *text_obj;
791 E_Editable_Smart_Data *sd;
792 char *text = "Tout est bon dans l'abricot sauf le noyau!"
793 "Wakey wakey! Eggs and Bakey!";
794 const char *font, *font_source;
795 Evas_Text_Style_Type style;
800 if ((!editable) || (!(evas = evas_object_evas_get(editable))))
802 if (!(sd = evas_object_smart_data_get(editable))) return;
803 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
806 if ((sd->average_char_w <= 0) || (sd->average_char_h <= 0))
808 font_source = evas_object_text_font_source_get(text_obj);
809 evas_object_text_font_get(text_obj, &font, &font_size);
810 style = evas_object_text_style_get(text_obj);
812 obj = evas_object_text_add(evas);
813 evas_object_scale_set(obj, edje_scale_get());
814 evas_object_text_font_source_set(obj, font_source);
815 evas_object_text_font_set(obj, font, font_size);
816 evas_object_text_style_set(obj, style);
817 evas_object_text_text_set(obj, text);
818 evas_object_geometry_get(obj, NULL, NULL, &tw, &th);
819 evas_object_del(obj);
820 sd->average_char_w = (tw / strlen(text));
821 sd->average_char_h = th;
823 if (w) *w = sd->average_char_w;
824 if (h) *h = sd->average_char_h;
828 e_editable_enable(Evas_Object *editable)
830 E_Editable_Smart_Data *sd;
832 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
835 edje_object_signal_emit(sd->text_object, "e,state,enabled", "e");
839 e_editable_disable(Evas_Object *editable)
841 E_Editable_Smart_Data *sd;
843 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
846 edje_object_signal_emit(sd->text_object, "e,state,disabled", "e");
848 /* Private functions */
850 /* A utility function to insert some text inside the editable object.
851 * It doesn't update the position of the cursor, nor the selection... */
853 _e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
855 E_Editable_Smart_Data *sd;
856 int char_length = -1, unicode_length = -1;
857 int prev_char_length, new_char_length, new_unicode_length;
858 int index = 0, i = 0;
860 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
862 if ((!text) || (*text == '\0')) return 0;
864 if (pos < 0) pos = 0;
865 else if (pos > sd->unicode_length)
866 pos = sd->unicode_length;
868 for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL))
874 for (i = 0; i < pos; i++)
875 index = evas_string_char_next_get(sd->text, index, NULL);
877 if ((unicode_length <= 0) || (char_length <= 0)) return 0;
879 prev_char_length = sd->char_length;
880 new_char_length = sd->char_length + char_length;
881 new_unicode_length = sd->unicode_length + unicode_length;
883 if (new_char_length > sd->allocated_length)
885 int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length);
886 char *old = sd->text;
888 if (sd->password_mode)
890 /* security -- copy contents into new buffer, and overwrite old contents */
891 sd->text = malloc(new_allocated_length + 1);
899 memcpy(sd->text, old, prev_char_length + 1);
900 memset(old, 0, prev_char_length);
906 sd->text = realloc(sd->text, new_allocated_length + 1);
913 sd->allocated_length = new_allocated_length;
915 sd->unicode_length = new_unicode_length;
916 sd->char_length = new_char_length;
918 if (prev_char_length > index)
919 memmove(&sd->text[index + char_length], &sd->text[index], prev_char_length - index);
920 strncpy(&sd->text[index], text, char_length);
921 sd->text[sd->char_length] = '\0';
923 _e_editable_text_update(editable);
924 return unicode_length;
927 /* A utility function to delete a range of text from the editable object.
928 * It doesn't update the position of the cursor, nor the selection... */
930 _e_editable_text_delete(Evas_Object *editable, int start, int end)
932 E_Editable_Smart_Data *sd;
933 int start_id = 0, end_id = 0, i = 0;
935 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
938 start = E_CLAMP(start, 0, sd->unicode_length);
939 end = E_CLAMP(end, 0, sd->unicode_length);
940 if (end <= start) return 0;
942 for (i = 0; i < end; i++)
944 end_id = evas_string_char_next_get(sd->text, end_id, NULL);
945 if (i < start) start_id = end_id;
948 if (end_id <= start_id) return 0;
950 memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id);
951 sd->char_length -= (end_id - start_id);
952 sd->unicode_length -= (end - start);
953 sd->text[sd->char_length] = '\0';
955 _e_editable_text_update(editable);
957 return (end - start);
960 /* Updates the position of the cursor
961 * It also updates automatically the text position and the selection */
963 _e_editable_cursor_update(Evas_Object *editable)
965 E_Editable_Smart_Data *sd;
966 const Evas_Object *text_obj;
968 Evas_Coord cx, cy, ch;
970 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
972 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
975 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
976 _e_editable_char_geometry_get_from_pos(editable, sd->cursor_pos,
977 &cx, &cy, NULL, &ch);
979 evas_object_move(sd->cursor_object, tx + cx, ty + cy);
980 evas_object_resize(sd->cursor_object, sd->cursor_width, ch);
982 if (sd->cursor_visible && evas_object_visible_get(editable))
984 evas_object_show(sd->cursor_object);
985 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
988 _e_editable_selection_update(editable);
989 _e_editable_text_position_update(editable, -1);
992 /* Updates the selection of the editable object */
994 _e_editable_selection_update(Evas_Object *editable)
996 E_Editable_Smart_Data *sd;
997 const Evas_Object *text_obj;
1000 Evas_Coord sx, sy, sw, sh;
1001 int start_pos, end_pos;
1003 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1005 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1008 if ((sd->cursor_pos == sd->selection_pos) || (!sd->selection_visible))
1009 evas_object_hide(sd->selection_object);
1012 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
1013 start_pos = (sd->cursor_pos <= sd->selection_pos) ?
1014 sd->cursor_pos : sd->selection_pos;
1015 end_pos = (sd->cursor_pos >= sd->selection_pos) ?
1016 sd->cursor_pos : sd->selection_pos;
1018 _e_editable_char_geometry_get_from_pos(editable, start_pos,
1019 &cx, &cy, NULL, NULL);
1023 _e_editable_char_geometry_get_from_pos(editable, end_pos,
1024 &cx, NULL, NULL, &sh);
1027 evas_object_move(sd->selection_object, sx, sy);
1028 evas_object_resize(sd->selection_object, sw, sh);
1029 evas_object_show(sd->selection_object);
1033 /* Updates the text of the text object of the editable object
1034 * (it fills it with '*' if the editable is in password mode)
1035 * It does not update the position of the text */
1037 _e_editable_text_update(Evas_Object *editable)
1039 E_Editable_Smart_Data *sd;
1040 Evas_Coord minw, minh;
1042 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1045 if (sd->password_mode)
1049 text = malloc((sd->unicode_length + 1) * sizeof(char));
1050 memset(text, '*', sd->unicode_length * sizeof(char));
1051 text[sd->unicode_length] = '\0';
1052 edje_object_part_text_set(sd->text_object, "e.text.text", text);
1056 edje_object_part_text_set(sd->text_object, "e.text.text", sd->text);
1058 edje_object_size_min_calc(sd->text_object, &minw, &minh);
1059 evas_object_resize(sd->text_object, minw, minh);
1062 /* Updates the position of the text object according to the position of the
1063 * cursor (we make sure the cursor is visible) */
1065 _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w)
1067 E_Editable_Smart_Data *sd;
1068 Evas_Coord ox, oy, ow;
1069 Evas_Coord tx, ty, tw;
1070 Evas_Coord cx, cy, cw;
1072 Evas_Coord offset_x = 0;
1074 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1077 evas_object_geometry_get(editable, &ox, &oy, &ow, NULL);
1078 if (real_w >= 0) ow = real_w;
1079 evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, NULL);
1080 evas_object_geometry_get(sd->cursor_object, &cx, &cy, &cw, NULL);
1081 evas_object_geometry_get(sd->selection_object, &sx, &sy, NULL, NULL);
1085 else if (cx < (ox + E_EDITABLE_CURSOR_MARGIN))
1086 offset_x = ox + E_EDITABLE_CURSOR_MARGIN - cx;
1087 else if ((cx + cw + E_EDITABLE_CURSOR_MARGIN) > (ox + ow))
1088 offset_x = (ox + ow) - (cx + cw + E_EDITABLE_CURSOR_MARGIN);
1092 if ((tx + offset_x) > ox)
1094 else if ((tx + tw + offset_x) < (ox + ow))
1095 offset_x = (ox + ow) - (tx + tw);
1100 evas_object_move(sd->text_object, tx + offset_x, ty);
1101 evas_object_move(sd->cursor_object, cx + offset_x, cy);
1102 evas_object_move(sd->selection_object, sx + offset_x, sy);
1106 /* Gets the geometry of the char according to its utf-8 pos */
1108 _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)
1110 E_Editable_Smart_Data *sd;
1111 const Evas_Object *text_obj;
1114 int index = 0, i, last_pos, ret;
1121 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1123 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1126 text = evas_object_text_text_get(text_obj);
1127 if ((!text) || (sd->unicode_length <= 0) || (utf_pos <= 0))
1129 e_editable_char_size_get(editable, cw, ch);
1134 if (utf_pos >= sd->unicode_length)
1136 utf_pos = sd->unicode_length - 1;
1142 for (i = 0; i < utf_pos; i++)
1143 index = evas_string_char_next_get(text, index, NULL);
1145 ret = evas_object_text_char_pos_get(text_obj, index, &x, cy, &w, ch);
1146 if (cx) *cx = x - 1 + (last_pos ? w : 0);
1147 if (cw) *cw = last_pos ? 1 : w;
1152 /* Editable object's smart methods */
1155 _e_editable_smart_add(Evas_Object *object)
1158 E_Editable_Smart_Data *sd;
1161 if ((!object) || !(evas = evas_object_evas_get(object)))
1164 sd = malloc(sizeof(E_Editable_Smart_Data));
1167 _e_editable_smart_use++;
1168 evas_object_smart_data_set(object, sd);
1169 evas_object_geometry_get(object, &ox, &oy, NULL, NULL);
1171 sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
1173 sd->char_length = 0;
1174 sd->unicode_length = 0;
1175 sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
1177 sd->cursor_width = 1;
1178 sd->selection_on_fg = 0;
1179 sd->average_char_w = -1;
1180 sd->average_char_h = -1;
1183 sd->cursor_visible = 1;
1184 sd->selection_pos = 0;
1185 sd->selection_visible = 1;
1186 sd->password_mode = 0;
1188 sd->clip_object = evas_object_rectangle_add(evas);
1189 evas_object_move(sd->clip_object, ox, oy);
1190 evas_object_smart_member_add(sd->clip_object, object);
1192 sd->event_object = evas_object_rectangle_add(evas);
1193 evas_object_color_set(sd->event_object, 0, 0, 0, 0);
1194 evas_object_clip_set(sd->event_object, sd->clip_object);
1195 evas_object_move(sd->event_object, ox, oy);
1196 evas_object_smart_member_add(sd->event_object, object);
1198 sd->text_object = edje_object_add(evas);
1199 evas_object_pass_events_set(sd->text_object, 1);
1200 evas_object_clip_set(sd->text_object, sd->clip_object);
1201 evas_object_move(sd->text_object, ox, oy);
1202 evas_object_smart_member_add(sd->text_object, object);
1204 sd->selection_object = edje_object_add(evas);
1205 evas_object_pass_events_set(sd->selection_object, 1);
1206 evas_object_clip_set(sd->selection_object, sd->clip_object);
1207 evas_object_move(sd->selection_object, ox, oy);
1208 evas_object_smart_member_add(sd->selection_object, object);
1210 sd->cursor_object = edje_object_add(evas);
1211 evas_object_pass_events_set(sd->cursor_object, 1);
1212 evas_object_clip_set(sd->cursor_object, sd->clip_object);
1213 evas_object_move(sd->cursor_object, ox, oy);
1214 evas_object_smart_member_add(sd->cursor_object, object);
1216 _e_editable_cursor_update(object);
1219 /* Deletes the editable */
1221 _e_editable_smart_del(Evas_Object *object)
1223 E_Editable_Smart_Data *sd;
1225 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1228 evas_object_del(sd->clip_object);
1229 evas_object_del(sd->event_object);
1230 evas_object_del(sd->text_object);
1231 evas_object_del(sd->cursor_object);
1232 evas_object_del(sd->selection_object);
1233 /* Security - clear out memory that contained a password */
1234 if (sd->password_mode) memset(sd->text, 0, sd->char_length);
1238 _e_editable_smart_use--;
1239 if (_e_editable_smart_use <= 0)
1241 evas_smart_free(_e_editable_smart);
1242 _e_editable_smart = NULL;
1246 /* Moves the editable object */
1248 _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1250 E_Editable_Smart_Data *sd;
1251 Evas_Coord prev_x, prev_y;
1254 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1257 evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1258 evas_object_move(sd->clip_object, x, y);
1259 evas_object_move(sd->event_object, x, y);
1260 evas_object_geometry_get(sd->text_object, &ox, &oy, NULL, NULL);
1261 evas_object_move(sd->text_object, ox + (x - prev_x), oy + (y - prev_y));
1262 evas_object_geometry_get(sd->cursor_object, &ox, &oy, NULL, NULL);
1263 evas_object_move(sd->cursor_object, ox + (x - prev_x), oy + (y - prev_y));
1264 evas_object_geometry_get(sd->selection_object, &ox, &oy, NULL, NULL);
1265 evas_object_move(sd->selection_object, ox + (x - prev_x), oy + (y - prev_y));
1268 /* Resizes the editable object */
1270 _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1272 E_Editable_Smart_Data *sd;
1274 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1277 evas_object_resize(sd->clip_object, w, h);
1278 evas_object_resize(sd->event_object, w, h);
1279 _e_editable_text_position_update(object, w);
1282 /* Shows the editable object */
1284 _e_editable_smart_show(Evas_Object *object)
1286 E_Editable_Smart_Data *sd;
1288 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1291 evas_object_show(sd->clip_object);
1292 evas_object_show(sd->event_object);
1293 evas_object_show(sd->text_object);
1295 if (sd->cursor_visible)
1297 evas_object_show(sd->cursor_object);
1298 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1301 if ((sd->selection_visible) && (sd->cursor_pos != sd->selection_pos))
1302 evas_object_show(sd->selection_object);
1305 /* Hides the editable object */
1307 _e_editable_smart_hide(Evas_Object *object)
1309 E_Editable_Smart_Data *sd;
1311 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1314 evas_object_hide(sd->clip_object);
1315 evas_object_hide(sd->event_object);
1316 evas_object_hide(sd->text_object);
1317 evas_object_hide(sd->cursor_object);
1318 evas_object_hide(sd->selection_object);
1321 /* Changes the color of the editable object */
1323 _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a)
1325 E_Editable_Smart_Data *sd;
1327 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1329 evas_object_color_set(sd->clip_object, r, g, b, a);
1332 /* Clips the editable object against "clip" */
1334 _e_editable_clip_set(Evas_Object *object, Evas_Object *clip)
1336 E_Editable_Smart_Data *sd;
1338 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1340 evas_object_clip_set(sd->clip_object, clip);
1343 /* Unclips the editable object */
1345 _e_editable_clip_unset(Evas_Object *object)
1347 E_Editable_Smart_Data *sd;
1349 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1351 evas_object_clip_unset(sd->clip_object);