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 (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
118 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
120 if ((!category) || (!group)) return;
121 obj_group = alloca(strlen(group) + strlen("/selection") + 1);
123 /* Gets the theme for the text object */
124 sprintf(obj_group, "%s/text", group);
125 e_theme_edje_object_set(sd->text_object, category, obj_group);
126 sd->average_char_w = -1;
127 sd->average_char_h = -1;
129 /* Gets the theme for the cursor */
130 sprintf(obj_group, "%s/cursor", group);
131 e_theme_edje_object_set(sd->cursor_object, category, obj_group);
133 edje_object_size_min_get(sd->cursor_object, &sd->cursor_width, NULL);
134 if (sd->cursor_width < 1) sd->cursor_width = 1;
136 /* Gets the theme for the selection */
137 sprintf(obj_group, "%s/selection", group);
138 e_theme_edje_object_set(sd->selection_object, category, obj_group);
140 data = edje_object_data_get(sd->selection_object, "on_foreground");
141 if ((data) && (strcmp(data, "1") == 0))
143 sd->selection_on_fg = 1;
144 evas_object_stack_above(sd->selection_object, sd->text_object);
148 sd->selection_on_fg = 0;
149 evas_object_stack_below(sd->selection_object, sd->text_object);
152 _e_editable_text_update(editable);
153 _e_editable_cursor_update(editable);
157 * Sets whether or not the editable object is in password mode. In password
158 * mode, the editable object displays '*' instead of the characters
160 * @param editable an editable object
161 * @param password_mode 1 to turn on the password mode of the editable object,
165 e_editable_password_set(Evas_Object *editable, int password_mode)
167 E_Editable_Smart_Data *sd;
169 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
170 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
172 if (sd->password_mode == password_mode) return;
174 sd->password_mode = password_mode;
175 _e_editable_text_update(editable);
176 _e_editable_cursor_update(editable);
180 * Gets whether or not the editable is in password mode
182 * @param editable an editable object
183 * @return Returns 1 if the editable object is in the password mode, 0 otherwise
186 e_editable_password_get(Evas_Object *editable)
188 E_Editable_Smart_Data *sd;
190 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
191 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
193 return sd->password_mode;
197 * Sets the text of the editable object
199 * @param editable an editable object
200 * @param text the text to set
203 e_editable_text_set(Evas_Object *editable, const char *text)
205 E_Editable_Smart_Data *sd;
207 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
208 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
211 if (sd->password_mode) memset(sd->text, 0, sd->char_length);
214 sd->unicode_length = 0;
215 sd->allocated_length = -1;
217 if (_e_editable_text_insert(editable, 0, text) <= 0)
219 sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
222 sd->unicode_length = 0;
223 sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
224 _e_editable_text_update(editable);
227 sd->cursor_pos = sd->unicode_length;
228 sd->selection_pos = sd->unicode_length;
229 _e_editable_cursor_update(editable);
233 * Gets the entire text of the editable object
235 * @param editable an editable object
236 * @return Returns the entire text of the editable object
239 e_editable_text_get(Evas_Object *editable)
241 E_Editable_Smart_Data *sd;
243 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(NULL);
244 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
250 * Gets a range of the text of the editable object, from position @a start to
253 * @param editable an editable object
254 * @param start the start position of the text range to get
255 * @param end the end position of the text range to get
256 * @return Returns the range of text. The returned string will have to be freed
259 e_editable_text_range_get(Evas_Object *editable, int start, int end)
261 E_Editable_Smart_Data *sd;
263 int start_id = 0, end_id = 0, i;
265 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(NULL);
266 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
269 start = E_CLAMP(start, 0, sd->unicode_length);
270 end = E_CLAMP(end, 0, sd->unicode_length);
271 if (end <= start) return NULL;
273 for (i = 0; i < end; i++)
275 end_id = evas_string_char_next_get(sd->text, end_id, NULL);
276 if (i < start) start_id = end_id;
279 if (end_id <= start_id) return NULL;
281 range = malloc((end_id - start_id + 1) * sizeof(char));
282 if (!range) return NULL;
284 strncpy(range, &sd->text[start_id], end_id - start_id);
285 range[end_id - start_id] = '\0';
291 * Gets the unicode length of the text of the editable object. The unicode
292 * length is not always the length returned by strlen() since a UTF-8 char can
295 * @param editable an editable object
296 * @return Returns the unicode length of the text of the editable object
299 e_editable_text_length_get(Evas_Object *editable)
301 E_Editable_Smart_Data *sd;
303 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
304 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
306 return sd->unicode_length;
310 * Inserts some text at the given position in the editable object
312 * @param editable the editable object in which the text should be inserted
313 * @param pos the position where to insert the text
314 * @param text the text to insert
315 * @return Returns 1 if the text has been modified, 0 otherwise
318 e_editable_insert(Evas_Object *editable, int pos, const char *text)
320 E_Editable_Smart_Data *sd;
323 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
324 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
327 unicode_length = _e_editable_text_insert(editable, pos, text);
328 if (unicode_length <= 0) return 0;
330 if (sd->cursor_pos >= pos)
331 e_editable_cursor_pos_set(editable, sd->cursor_pos + unicode_length);
332 if (sd->selection_pos >= pos)
333 e_editable_selection_pos_set(editable, sd->selection_pos + unicode_length);
335 _e_editable_text_position_update(editable, -1);
340 * Deletes the text of the editable object, between position "start" and
343 * @param editable the editable object in which the text should be deleted
344 * @param start the position of the first char to delete
345 * @param end the position of the last char to delete
346 * @return Returns 1 if the text has been modified, 0 otherwise
349 e_editable_delete(Evas_Object *editable, int start, int end)
351 E_Editable_Smart_Data *sd;
354 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
355 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
358 unicode_length = _e_editable_text_delete(editable, start, end);
359 if (unicode_length <= 0) return 0;
361 if (sd->cursor_pos > end)
362 e_editable_cursor_pos_set(editable, sd->cursor_pos - unicode_length);
363 else if (sd->cursor_pos > start)
364 e_editable_cursor_pos_set(editable, start);
366 if (sd->selection_pos > end)
367 e_editable_selection_pos_set(editable, sd->selection_pos - unicode_length);
368 else if (sd->selection_pos > start)
369 e_editable_selection_pos_set(editable, start);
371 _e_editable_text_position_update(editable, -1);
376 * Moves the cursor of the editable object to the given position
378 * @param editable an editable object
379 * @param pos the position where to move the cursor
382 e_editable_cursor_pos_set(Evas_Object *editable, int pos)
384 E_Editable_Smart_Data *sd;
386 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
387 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
390 pos = E_CLAMP(pos, 0, sd->unicode_length);
391 if (sd->cursor_pos == pos) return;
393 sd->cursor_pos = pos;
394 _e_editable_cursor_update(editable);
398 * Gets the position of the cursor of the editable object
400 * @param editable an editable object
401 * @return Returns the position of the cursor of the editable object
404 e_editable_cursor_pos_get(Evas_Object *editable)
406 E_Editable_Smart_Data *sd;
408 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
409 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
411 return sd->cursor_pos;
415 * Gets the geometry of the cursor of the editable object
417 * @param editable an editable object
418 * @param cx the x of the cursor
419 * @param cy the y of the cursor
420 * @param cw the width of the cursor
421 * @param ch the height of the cursor
424 e_editable_cursor_geometry_get(Evas_Object *editable, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
426 E_Editable_Smart_Data *sd;
428 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
429 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
432 evas_object_geometry_get(sd->cursor_object, cx, cy, cw, ch);
436 * Moves the cursor to the start of the editable object
438 * @param editable an editable object
441 e_editable_cursor_move_to_start(Evas_Object *editable)
443 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
446 e_editable_cursor_pos_set(editable, 0);
450 * Moves the cursor to the end of the editable object
452 * @param editable an editable object
455 e_editable_cursor_move_to_end(Evas_Object *editable)
457 E_Editable_Smart_Data *sd;
459 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
460 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
462 e_editable_cursor_pos_set(editable, sd->unicode_length);
466 * Moves the cursor backward by one character offset
468 * @param editable an editable object
471 e_editable_cursor_move_left(Evas_Object *editable)
473 E_Editable_Smart_Data *sd;
475 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
476 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
478 e_editable_cursor_pos_set(editable, sd->cursor_pos - 1);
482 * Moves the cursor forward by one character offset
484 * @param editable an editable object
487 e_editable_cursor_move_right(Evas_Object *editable)
489 E_Editable_Smart_Data *sd;
491 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
492 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
494 e_editable_cursor_pos_set(editable, sd->cursor_pos + 1);
498 * Shows the cursor of the editable object
500 * @param editable the editable object whose cursor should be shown
503 e_editable_cursor_show(Evas_Object *editable)
505 E_Editable_Smart_Data *sd;
507 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
508 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
510 if (sd->cursor_visible) return;
512 sd->cursor_visible = 1;
513 if (evas_object_visible_get(editable))
515 evas_object_show(sd->cursor_object);
516 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
521 * Hides the cursor of the editable object
523 * @param editable the editable object whose cursor should be hidden
526 e_editable_cursor_hide(Evas_Object *editable)
528 E_Editable_Smart_Data *sd;
530 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
531 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
533 if (!sd->cursor_visible) return;
535 sd->cursor_visible = 0;
536 evas_object_hide(sd->cursor_object);
540 * Moves the selection bound of the editable object to the given position
542 * @param editable an editable object
543 * @param pos the position where to move the selection bound
546 e_editable_selection_pos_set(Evas_Object *editable, int pos)
548 E_Editable_Smart_Data *sd;
550 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
551 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
554 pos = E_CLAMP(pos, 0, sd->unicode_length);
555 if (sd->selection_pos == pos) return;
557 sd->selection_pos = pos;
558 _e_editable_selection_update(editable);
562 * Gets the position of the selection bound of the editable object
564 * @param editable an editable object
565 * @return Returns the position of the selection bound of the editable object
568 e_editable_selection_pos_get(Evas_Object *editable)
570 E_Editable_Smart_Data *sd;
572 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
573 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
575 return sd->selection_pos;
579 * Moves the selection bound to the start of the editable object
581 * @param editable an editable object
584 e_editable_selection_move_to_start(Evas_Object *editable)
586 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
589 e_editable_selection_pos_set(editable, 0);
593 * Moves the selection bound to the end of the editable object
595 * @param editable an editable object
598 e_editable_selection_move_to_end(Evas_Object *editable)
600 E_Editable_Smart_Data *sd;
602 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
603 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
605 e_editable_selection_pos_set(editable, sd->unicode_length);
609 * Moves the selection bound backward by one character offset
611 * @param editable an editable object
614 e_editable_selection_move_left(Evas_Object *editable)
616 E_Editable_Smart_Data *sd;
618 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
619 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
621 e_editable_selection_pos_set(editable, sd->selection_pos - 1);
625 * Moves the selection bound forward by one character offset
627 * @param editable an editable object
630 e_editable_selection_move_right(Evas_Object *editable)
632 E_Editable_Smart_Data *sd;
634 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
635 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
637 e_editable_selection_pos_set(editable, sd->selection_pos + 1);
641 * Selects all the text of the editable object. The selection bound will be
642 * moved to the start of the editable object and the cursor will be moved to
645 * @param editable an editable object
648 e_editable_select_all(Evas_Object *editable)
650 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
651 e_editable_selection_move_to_start(editable);
652 e_editable_cursor_move_to_end(editable);
656 * Unselects all the text of the editable object. The selection bound will be
657 * moved to the cursor position
659 * @param editable an editable object
662 e_editable_unselect_all(Evas_Object *editable)
664 E_Editable_Smart_Data *sd;
666 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
667 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
669 e_editable_selection_pos_set(editable, sd->cursor_pos);
673 * Selects the word at the provided character index
676 e_editable_select_word(Evas_Object *editable, int idx)
678 E_Editable_Smart_Data *sd;
679 int spos = 0, epos = -1, i = 0, pos = 0;
681 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
682 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
684 if ((idx < 0) || (idx >= sd->unicode_length)) return;
686 while (i < sd->char_length)
688 if (sd->text[i] == ' ')
690 if (pos < idx) spos = pos + 1;
697 i = evas_string_char_next_get(sd->text, i, NULL);
700 if (epos == -1) epos = pos;
701 e_editable_selection_pos_set(editable, spos);
702 e_editable_cursor_pos_set(editable, epos);
706 * Shows the selection of the editable object
708 * @param editable an editable object
711 e_editable_selection_show(Evas_Object *editable)
713 E_Editable_Smart_Data *sd;
715 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
716 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
718 if (sd->selection_visible) return;
719 sd->selection_visible = 1;
720 if ((evas_object_visible_get(editable)) &&
721 (sd->cursor_pos != sd->selection_pos))
722 evas_object_show(sd->selection_object);
726 * Hides the selection of the editable object
728 * @param editable an editable object
731 e_editable_selection_hide(Evas_Object *editable)
733 E_Editable_Smart_Data *sd;
735 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
736 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
738 if (!sd->selection_visible) return;
739 sd->selection_visible = 0;
740 evas_object_hide(sd->selection_object);
744 * Gets the cursor position at the coords ( @a x, @a y ). It's used to know
745 * where to place the cursor or the selection bound on mouse evevents.
747 * @param editable an editable object
748 * @param x the x coord, relative to the editable object
749 * @param y the y coord, relative to the editable object
750 * @return Returns the position where to place the cursor according to the
754 e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y)
756 E_Editable_Smart_Data *sd;
757 const Evas_Object *text_obj;
759 Evas_Coord tx, ty, tw, th;
761 Evas_Coord canvas_x, canvas_y;
765 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
766 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
768 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
771 evas_object_geometry_get(editable, &ox, &oy, NULL, NULL);
772 evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th);
776 if ((canvas_y < ty) || (canvas_x < tx))
778 else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw)))
779 pos = sd->unicode_length;
782 idx = evas_object_text_char_coords_get(text_obj,
783 canvas_x - tx, canvas_y - ty,
784 &cx, NULL, &cw, NULL);
785 text = evas_object_text_text_get(text_obj);
786 if ((idx >= 0) && (text))
788 if ((canvas_x - tx) > (cx + (cw / 2))) idx++;
793 while ((i < idx) && (j != i))
797 i = evas_string_char_next_get(text, i, NULL);
799 if (pos > sd->unicode_length) pos = sd->unicode_length;
807 * A utility function to get the average size of a character written inside
808 * the editable object
810 * @param editable an editable object
811 * @param w the location where to store the average width of a character
812 * @param h the location where to store the average height of a character
815 e_editable_char_size_get(Evas_Object *editable, int *w, int *h)
819 const Evas_Object *text_obj;
821 E_Editable_Smart_Data *sd;
822 char *text = "Tout est bon dans l'abricot sauf le noyau!"
823 "Wakey wakey! Eggs and Bakey!";
824 const char *font, *font_source;
825 Evas_Text_Style_Type style;
830 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
831 if ((!editable) || (!(evas = evas_object_evas_get(editable))))
833 if (!(sd = evas_object_smart_data_get(editable))) return;
834 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
837 if ((sd->average_char_w <= 0) || (sd->average_char_h <= 0))
839 font_source = evas_object_text_font_source_get(text_obj);
840 evas_object_text_font_get(text_obj, &font, &font_size);
841 style = evas_object_text_style_get(text_obj);
843 obj = evas_object_text_add(evas);
844 evas_object_scale_set(obj, edje_scale_get());
845 evas_object_text_font_source_set(obj, font_source);
846 evas_object_text_font_set(obj, font, font_size);
847 evas_object_text_style_set(obj, style);
848 evas_object_text_text_set(obj, text);
849 evas_object_geometry_get(obj, NULL, NULL, &tw, &th);
850 evas_object_del(obj);
851 sd->average_char_w = (tw / strlen(text));
852 sd->average_char_h = th;
854 if (w) *w = sd->average_char_w;
855 if (h) *h = sd->average_char_h;
859 e_editable_enable(Evas_Object *editable)
861 E_Editable_Smart_Data *sd;
863 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
864 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
867 edje_object_signal_emit(sd->text_object, "e,state,enabled", "e");
871 e_editable_disable(Evas_Object *editable)
873 E_Editable_Smart_Data *sd;
875 if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
876 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
879 edje_object_signal_emit(sd->text_object, "e,state,disabled", "e");
882 /* Private functions */
884 /* A utility function to insert some text inside the editable object.
885 * It doesn't update the position of the cursor, nor the selection... */
887 _e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
889 E_Editable_Smart_Data *sd;
890 int char_length = -1, unicode_length = -1;
891 int prev_char_length, new_char_length, new_unicode_length;
894 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
896 if ((!text) || (*text == '\0')) return 0;
898 if (pos < 0) pos = 0;
899 else if (pos > sd->unicode_length)
900 pos = sd->unicode_length;
902 for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL))
908 for (i = 0; i < pos; i++)
909 idx = evas_string_char_next_get(sd->text, idx, NULL);
911 if ((unicode_length <= 0) || (char_length <= 0)) return 0;
913 prev_char_length = sd->char_length;
914 new_char_length = sd->char_length + char_length;
915 new_unicode_length = sd->unicode_length + unicode_length;
917 if (new_char_length > sd->allocated_length)
919 int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length);
920 char *old = sd->text;
922 if (sd->password_mode)
924 /* security -- copy contents into new buffer, and overwrite old contents */
925 sd->text = malloc(new_allocated_length + 1);
933 memcpy(sd->text, old, prev_char_length + 1);
934 memset(old, 0, prev_char_length);
940 char *p = realloc(sd->text, new_allocated_length + 1);
948 sd->allocated_length = new_allocated_length;
950 sd->unicode_length = new_unicode_length;
951 sd->char_length = new_char_length;
953 if (prev_char_length > idx)
954 memmove(&sd->text[idx + char_length], &sd->text[idx], prev_char_length - idx);
955 strncpy(&sd->text[idx], text, char_length);
956 sd->text[sd->char_length] = '\0';
958 _e_editable_text_update(editable);
959 return unicode_length;
962 /* A utility function to delete a range of text from the editable object.
963 * It doesn't update the position of the cursor, nor the selection... */
965 _e_editable_text_delete(Evas_Object *editable, int start, int end)
967 E_Editable_Smart_Data *sd;
968 int start_id = 0, end_id = 0, i = 0;
970 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
973 start = E_CLAMP(start, 0, sd->unicode_length);
974 end = E_CLAMP(end, 0, sd->unicode_length);
975 if (end <= start) return 0;
977 for (i = 0; i < end; i++)
979 end_id = evas_string_char_next_get(sd->text, end_id, NULL);
980 if (i < start) start_id = end_id;
983 if (end_id <= start_id) return 0;
985 memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id);
986 sd->char_length -= (end_id - start_id);
987 sd->unicode_length -= (end - start);
988 sd->text[sd->char_length] = '\0';
990 _e_editable_text_update(editable);
995 /* Updates the position of the cursor
996 * It also updates automatically the text position and the selection */
998 _e_editable_cursor_update(Evas_Object *editable)
1000 E_Editable_Smart_Data *sd;
1001 const Evas_Object *text_obj;
1003 Evas_Coord cx, cy, ch;
1005 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1007 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1010 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
1011 _e_editable_char_geometry_get_from_pos(editable, sd->cursor_pos,
1012 &cx, &cy, NULL, &ch);
1014 evas_object_move(sd->cursor_object, tx + cx, ty + cy);
1015 evas_object_resize(sd->cursor_object, sd->cursor_width, ch);
1017 if (sd->cursor_visible && evas_object_visible_get(editable))
1019 evas_object_show(sd->cursor_object);
1020 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1023 _e_editable_selection_update(editable);
1024 _e_editable_text_position_update(editable, -1);
1027 /* Updates the selection of the editable object */
1029 _e_editable_selection_update(Evas_Object *editable)
1031 E_Editable_Smart_Data *sd;
1032 const Evas_Object *text_obj;
1035 Evas_Coord sx, sy, sw, sh;
1036 int start_pos, end_pos;
1038 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1040 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1043 if ((sd->cursor_pos == sd->selection_pos) || (!sd->selection_visible))
1044 evas_object_hide(sd->selection_object);
1047 evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
1048 start_pos = (sd->cursor_pos <= sd->selection_pos) ?
1049 sd->cursor_pos : sd->selection_pos;
1050 end_pos = (sd->cursor_pos >= sd->selection_pos) ?
1051 sd->cursor_pos : sd->selection_pos;
1053 _e_editable_char_geometry_get_from_pos(editable, start_pos,
1054 &cx, &cy, NULL, NULL);
1058 _e_editable_char_geometry_get_from_pos(editable, end_pos,
1059 &cx, NULL, NULL, &sh);
1062 evas_object_move(sd->selection_object, sx, sy);
1063 evas_object_resize(sd->selection_object, sw, sh);
1064 evas_object_show(sd->selection_object);
1068 /* Updates the text of the text object of the editable object
1069 * (it fills it with '*' if the editable is in password mode)
1070 * It does not update the position of the text */
1072 _e_editable_text_update(Evas_Object *editable)
1074 E_Editable_Smart_Data *sd;
1075 Evas_Coord minw, minh;
1077 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1080 if (sd->password_mode)
1084 text = malloc((sd->unicode_length + 1) * sizeof(char));
1087 memset(text, '*', sd->unicode_length * sizeof(char));
1088 text[sd->unicode_length] = '\0';
1089 edje_object_part_text_set(sd->text_object, "e.text.text", text);
1093 edje_object_part_text_set(sd->text_object, "e.text.text", sd->text);
1095 edje_object_size_min_calc(sd->text_object, &minw, &minh);
1096 evas_object_resize(sd->text_object, minw, minh);
1099 /* Updates the position of the text object according to the position of the
1100 * cursor (we make sure the cursor is visible) */
1102 _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w)
1104 E_Editable_Smart_Data *sd;
1105 Evas_Coord ox, oy, ow;
1106 Evas_Coord tx, ty, tw;
1107 Evas_Coord cx, cy, cw;
1109 Evas_Coord offset_x = 0;
1111 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1114 evas_object_geometry_get(editable, &ox, &oy, &ow, NULL);
1115 if (real_w >= 0) ow = real_w;
1116 evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, NULL);
1117 evas_object_geometry_get(sd->cursor_object, &cx, &cy, &cw, NULL);
1118 evas_object_geometry_get(sd->selection_object, &sx, &sy, NULL, NULL);
1122 else if (cx < (ox + E_EDITABLE_CURSOR_MARGIN))
1123 offset_x = ox + E_EDITABLE_CURSOR_MARGIN - cx;
1124 else if ((cx + cw + E_EDITABLE_CURSOR_MARGIN) > (ox + ow))
1125 offset_x = (ox + ow) - (cx + cw + E_EDITABLE_CURSOR_MARGIN);
1129 if ((tx + offset_x) > ox)
1131 else if ((tx + tw + offset_x) < (ox + ow))
1132 offset_x = (ox + ow) - (tx + tw);
1137 evas_object_move(sd->text_object, tx + offset_x, ty);
1138 evas_object_move(sd->cursor_object, cx + offset_x, cy);
1139 evas_object_move(sd->selection_object, sx + offset_x, sy);
1143 /* Gets the geometry of the char according to its utf-8 pos */
1145 _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)
1147 E_Editable_Smart_Data *sd;
1148 const Evas_Object *text_obj;
1151 int idx = 0, i, last_pos, ret;
1158 if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1160 if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1163 text = evas_object_text_text_get(text_obj);
1164 if ((!text) || (sd->unicode_length <= 0) || (utf_pos <= 0))
1166 e_editable_char_size_get(editable, cw, ch);
1171 if (utf_pos >= sd->unicode_length)
1173 utf_pos = sd->unicode_length - 1;
1179 for (i = 0; i < utf_pos; i++)
1180 idx = evas_string_char_next_get(text, idx, NULL);
1182 ret = evas_object_text_char_pos_get(text_obj, idx, &x, cy, &w, ch);
1183 if (cx) *cx = x - 1 + (last_pos ? w : 0);
1184 if (cw) *cw = last_pos ? 1 : w;
1189 /* Editable object's smart methods */
1192 _e_editable_smart_add(Evas_Object *object)
1195 E_Editable_Smart_Data *sd;
1198 if ((!object) || !(evas = evas_object_evas_get(object)))
1201 sd = malloc(sizeof(E_Editable_Smart_Data));
1204 _e_editable_smart_use++;
1205 evas_object_smart_data_set(object, sd);
1206 evas_object_geometry_get(object, &ox, &oy, NULL, NULL);
1208 sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
1209 if (!sd->text) return;
1212 sd->char_length = 0;
1213 sd->unicode_length = 0;
1214 sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
1216 sd->cursor_width = 1;
1217 sd->selection_on_fg = 0;
1218 sd->average_char_w = -1;
1219 sd->average_char_h = -1;
1222 sd->cursor_visible = 1;
1223 sd->selection_pos = 0;
1224 sd->selection_visible = 1;
1225 sd->password_mode = 0;
1227 sd->clip_object = evas_object_rectangle_add(evas);
1228 evas_object_move(sd->clip_object, ox, oy);
1229 evas_object_smart_member_add(sd->clip_object, object);
1231 sd->event_object = evas_object_rectangle_add(evas);
1232 evas_object_color_set(sd->event_object, 0, 0, 0, 0);
1233 evas_object_clip_set(sd->event_object, sd->clip_object);
1234 evas_object_move(sd->event_object, ox, oy);
1235 evas_object_smart_member_add(sd->event_object, object);
1237 sd->text_object = edje_object_add(evas);
1238 evas_object_pass_events_set(sd->text_object, 1);
1239 evas_object_clip_set(sd->text_object, sd->clip_object);
1240 evas_object_move(sd->text_object, ox, oy);
1241 evas_object_smart_member_add(sd->text_object, object);
1243 sd->selection_object = edje_object_add(evas);
1244 evas_object_pass_events_set(sd->selection_object, 1);
1245 evas_object_clip_set(sd->selection_object, sd->clip_object);
1246 evas_object_move(sd->selection_object, ox, oy);
1247 evas_object_smart_member_add(sd->selection_object, object);
1249 sd->cursor_object = edje_object_add(evas);
1250 evas_object_pass_events_set(sd->cursor_object, 1);
1251 evas_object_clip_set(sd->cursor_object, sd->clip_object);
1252 evas_object_move(sd->cursor_object, ox, oy);
1253 evas_object_smart_member_add(sd->cursor_object, object);
1255 _e_editable_cursor_update(object);
1258 /* Deletes the editable */
1260 _e_editable_smart_del(Evas_Object *object)
1262 E_Editable_Smart_Data *sd;
1264 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1267 evas_object_del(sd->clip_object);
1268 evas_object_del(sd->event_object);
1269 evas_object_del(sd->text_object);
1270 evas_object_del(sd->cursor_object);
1271 evas_object_del(sd->selection_object);
1272 /* Security - clear out memory that contained a password */
1273 if (sd->password_mode) memset(sd->text, 0, sd->char_length);
1277 _e_editable_smart_use--;
1278 if (_e_editable_smart_use <= 0)
1280 evas_smart_free(_e_editable_smart);
1281 _e_editable_smart = NULL;
1285 /* Moves the editable object */
1287 _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1289 E_Editable_Smart_Data *sd;
1290 Evas_Coord prev_x, prev_y;
1293 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1296 evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1297 evas_object_move(sd->clip_object, x, y);
1298 evas_object_move(sd->event_object, x, y);
1299 evas_object_geometry_get(sd->text_object, &ox, &oy, NULL, NULL);
1300 evas_object_move(sd->text_object, ox + (x - prev_x), oy + (y - prev_y));
1301 evas_object_geometry_get(sd->cursor_object, &ox, &oy, NULL, NULL);
1302 evas_object_move(sd->cursor_object, ox + (x - prev_x), oy + (y - prev_y));
1303 evas_object_geometry_get(sd->selection_object, &ox, &oy, NULL, NULL);
1304 evas_object_move(sd->selection_object, ox + (x - prev_x), oy + (y - prev_y));
1307 /* Resizes the editable object */
1309 _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1311 E_Editable_Smart_Data *sd;
1313 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1316 evas_object_resize(sd->clip_object, w, h);
1317 evas_object_resize(sd->event_object, w, h);
1318 _e_editable_text_position_update(object, w);
1321 /* Shows the editable object */
1323 _e_editable_smart_show(Evas_Object *object)
1325 E_Editable_Smart_Data *sd;
1327 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1330 evas_object_show(sd->clip_object);
1331 evas_object_show(sd->event_object);
1332 evas_object_show(sd->text_object);
1334 if (sd->cursor_visible)
1336 evas_object_show(sd->cursor_object);
1337 edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1340 if ((sd->selection_visible) && (sd->cursor_pos != sd->selection_pos))
1341 evas_object_show(sd->selection_object);
1344 /* Hides the editable object */
1346 _e_editable_smart_hide(Evas_Object *object)
1348 E_Editable_Smart_Data *sd;
1350 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1353 evas_object_hide(sd->clip_object);
1354 evas_object_hide(sd->event_object);
1355 evas_object_hide(sd->text_object);
1356 evas_object_hide(sd->cursor_object);
1357 evas_object_hide(sd->selection_object);
1360 /* Changes the color of the editable object */
1362 _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a)
1364 E_Editable_Smart_Data *sd;
1366 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1368 evas_object_color_set(sd->clip_object, r, g, b, a);
1371 /* Clips the editable object against "clip" */
1373 _e_editable_clip_set(Evas_Object *object, Evas_Object *clip)
1375 E_Editable_Smart_Data *sd;
1377 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1379 evas_object_clip_set(sd->clip_object, clip);
1382 /* Unclips the editable object */
1384 _e_editable_clip_unset(Evas_Object *object)
1386 E_Editable_Smart_Data *sd;
1388 if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1390 evas_object_clip_unset(sd->clip_object);