1 #include <Elementary.h>
5 * @defgroup Editfield Editfield
8 * This is a editfield. It can contain a simple label and icon objects.
11 //#define ERASER_PADDING (10)
13 typedef struct _Widget_Data Widget_Data;
19 Evas_Object *scroller;
23 const char *guide_text;
24 Eina_Bool needs_size_calc:1;
25 Eina_Bool show_guide_text:1;
27 Eina_Bool single_line:1;
28 Eina_Bool eraser_show:1;
31 static const char *widtype = NULL;
32 static void _del_hook(Evas_Object *obj);
33 static void _theme_hook(Evas_Object *obj);
34 static void _sizing_eval(Evas_Object *obj);
35 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _on_focus_hook(void *data, Evas_Object *obj);
37 static Eina_Bool _empty_entry(Evas_Object *entry);
39 #ifdef HAVE_CONFORMANT_AUTOSCROLL
40 static const char SIG_CURSOR_CHANGED[] = "cursor,changed";
41 static const char SIG_IMPREGION_CHANGED[] = "impregion,changed";
45 _del_hook(Evas_Object *obj)
47 Widget_Data *wd = elm_widget_data_get(obj);
49 if (wd->label) eina_stringshare_del(wd->label);
53 #ifdef HAVE_CONFORMANT_AUTOSCROLL
55 _imp_region_get_hook(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
57 Widget_Data *wd = elm_widget_data_get(obj);
59 elm_widget_imp_region_get(wd->entry, x, y, w, h);
65 _on_focus_hook(void *data, Evas_Object *obj)
67 Widget_Data *wd = elm_widget_data_get(obj);
70 if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)) )
72 evas_object_smart_callback_call(obj, "unfocused", NULL);
73 wd->editing = EINA_FALSE;
74 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
75 if(_empty_entry(wd->entry))
79 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
80 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
81 wd->show_guide_text = EINA_TRUE;
88 _theme_hook(Evas_Object *obj)
90 Widget_Data *wd = elm_widget_data_get(obj);
93 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
95 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scroller);
97 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
99 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
101 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
103 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
104 if(wd->show_guide_text)
106 if(_empty_entry(wd->entry))
110 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
111 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
116 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
118 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
123 _changed_hook(Evas_Object *obj)
125 Widget_Data *wd = elm_widget_data_get(obj);
126 if (wd->needs_size_calc)
129 wd->needs_size_calc = EINA_FALSE;
134 _sizing_eval(Evas_Object *obj)
136 Widget_Data *wd = elm_widget_data_get(obj);
137 Evas_Coord minw = -1, minh = -1;
138 edje_object_size_min_calc(wd->base, &minw, &minh);
139 evas_object_size_hint_min_set(obj, minw, minh);
140 evas_object_size_hint_max_set(obj, -1, -1);
144 _request_sizing_eval(Evas_Object *obj)
146 Widget_Data *wd = elm_widget_data_get(obj);
149 if (wd->needs_size_calc)
151 wd->needs_size_calc = EINA_TRUE;
152 evas_object_smart_changed(obj);
156 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
159 evas_object_size_hint_weight_get(data, &weight_x, NULL);
160 if (weight_x == EVAS_HINT_EXPAND)
161 _request_sizing_eval(data);
165 _empty_entry(Evas_Object *entry)
171 text = elm_entry_entry_get(entry);
172 if(!text) return EINA_FALSE;
173 strip_text = elm_entry_markup_to_utf8(text);
175 len = strlen(strip_text);
185 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info)
187 Evas_Object *ef_obj = (Evas_Object *)data;
188 Widget_Data *wd = elm_widget_data_get(ef_obj);
190 if(!wd || !wd->base) return;
192 if(!_empty_entry(wd->entry))
196 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
197 wd->show_guide_text = EINA_FALSE;
202 #ifdef HAVE_CONFORMANT_AUTOSCROLL
204 _entry_cursor_changed_cb(void *data, Evas_Object *obj, void* event_info)
206 Evas_Object *ef_obj = (Evas_Object *)data;
207 Widget_Data *wd = elm_widget_data_get(ef_obj);
208 evas_object_smart_callback_call(ef_obj, SIG_IMPREGION_CHANGED, NULL);
213 _signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
215 Widget_Data *wd = elm_widget_data_get(data);
216 if(!wd || !wd->base) return;
218 if(!strcmp(source, "eraser"))
220 elm_entry_entry_set(wd->entry, "");
221 if(wd->editing == EINA_FALSE) {
224 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
225 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
226 wd->show_guide_text = EINA_TRUE;
230 else if(strcmp(source, "left_icon") && strcmp(source, "right_icon") && strcmp(source, "eraser"))
232 edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
234 elm_widget_focus_set(wd->scroller, EINA_TRUE);
236 elm_widget_focus_set(wd->entry, EINA_TRUE);
238 if(wd->editing == EINA_FALSE)
239 elm_entry_cursor_end_set(wd->entry);
243 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
244 wd->show_guide_text = EINA_FALSE;
246 evas_object_smart_callback_call(data, "clicked", NULL);
247 wd->editing = EINA_TRUE;
252 _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
254 Widget_Data *wd = elm_widget_data_get(data);
256 if (!wd || !wd->base) return;
257 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
261 * Add a new editfield object
263 * @param parent The parent object
264 * @return The new object or NULL if it cannot be created
269 elm_editfield_add(Evas_Object *parent)
275 wd = ELM_NEW(Widget_Data);
276 e = evas_object_evas_get(parent);
279 obj = elm_widget_add(e);
280 ELM_SET_WIDTYPE(widtype, "editfield");
281 elm_widget_type_set(obj, "editfield");
282 elm_widget_sub_object_add(parent, obj);
283 elm_widget_data_set(obj, wd);
284 elm_widget_del_hook_set(obj, _del_hook);
285 elm_widget_theme_hook_set(obj, _theme_hook);
286 elm_widget_changed_hook_set(obj, _changed_hook);
287 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
288 elm_widget_can_focus_set(obj, EINA_TRUE);
289 #ifdef HAVE_CONFORMANT_AUTOSCROLL
290 elm_widget_imp_region_get_hook_set(obj, _imp_region_get_hook, NULL);
293 wd->base = edje_object_add(e);
294 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
295 elm_widget_resize_object_set(obj, wd->base);
296 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
297 _signal_mouse_clicked, obj);
298 evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
300 wd->editing = EINA_FALSE;
301 wd->single_line = EINA_FALSE;
302 wd->eraser_show = EINA_FALSE;
304 wd->entry = elm_entry_add(obj);
305 elm_object_style_set(wd->entry, "editfield");
306 evas_object_size_hint_weight_set(wd->entry, 0, EVAS_HINT_EXPAND);
307 evas_object_size_hint_align_set(wd->entry, 0, EVAS_HINT_FILL);
308 evas_object_event_callback_add(wd->entry,
309 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
310 _changed_size_hints, obj);
311 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
312 evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);
313 elm_widget_sub_object_add(obj, wd->entry);
314 #ifdef HAVE_CONFORMANT_AUTOSCROLL
315 evas_object_smart_callback_add(wd->entry, SIG_CURSOR_CHANGED, _entry_cursor_changed_cb, obj);
324 * Set the label of editfield
326 * @param obj The editfield object
327 * @param label The label text
332 elm_editfield_label_set(Evas_Object *obj, const char *label)
334 Widget_Data *wd = elm_widget_data_get(obj);
335 ELM_CHECK_WIDTYPE(obj, widtype);
336 if (!wd || !wd->base)
339 eina_stringshare_del(wd->label);
342 wd->label = eina_stringshare_add(label);
343 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
344 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
349 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
350 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
352 edje_object_message_signal_process(wd->base);
353 edje_object_part_text_set(wd->base, "elm.text", label);
358 * Get the label used on the editfield object
360 * @param obj The editfield object
366 elm_editfield_label_get(Evas_Object *obj)
368 Widget_Data *wd = elm_widget_data_get(obj);
369 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
370 if (!wd || !wd->base)
376 * Get the label used on the editfield object
378 * @param obj The editfield object
384 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
386 Widget_Data *wd = elm_widget_data_get(obj);
387 ELM_CHECK_WIDTYPE(obj, widtype);
388 if (!wd || !wd->base)
391 eina_stringshare_del(wd->guide_text);
394 wd->guide_text = eina_stringshare_add(text);
395 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
396 wd->show_guide_text = EINA_TRUE;
399 wd->guide_text = NULL;
403 * Get the guidance text used on the editfield object
405 * @param obj The editfield object
411 elm_editfield_guide_text_get(Evas_Object *obj)
413 Widget_Data *wd = elm_widget_data_get(obj);
414 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
415 if (!wd || !wd->base)
417 return wd->guide_text;
421 * Get the entry of the editfield object
423 * @param obj The editfield object
424 * @return entry object
430 elm_editfield_entry_get(Evas_Object *obj)
432 Widget_Data *wd = elm_widget_data_get(obj);
433 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
440 * Set the left side icon.
442 * @param obj The editfield object
443 * @param icon The icon object
444 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
449 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
451 Widget_Data *wd = elm_widget_data_get(obj);
452 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
453 if (!wd || !wd->base)
455 if ((wd->licon != icon) && (wd->licon))
456 elm_widget_sub_object_del(obj, wd->licon);
459 if (!(edje_object_part_swallow(wd->base, "left_icon", icon)))
462 elm_widget_sub_object_add(obj, icon);
463 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
464 _changed_size_hints, obj);
465 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
466 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
473 * Get the left side icon
475 * @param obj The editfield object
476 * @return icon object
481 elm_editfield_left_icon_get(Evas_Object *obj)
483 Widget_Data *wd = elm_widget_data_get(obj);
484 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
485 if (!wd || !wd->base || !wd->licon)
491 * Set the right side icon.
493 * @param obj The editfield object
494 * @param icon The icon object
495 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
500 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
502 Widget_Data *wd = elm_widget_data_get(obj);
503 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
504 if (!wd || !wd->base)
506 if ((wd->ricon != icon) && (wd->ricon))
507 elm_widget_sub_object_del(obj, wd->ricon);
510 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
513 elm_widget_sub_object_add(obj, icon);
514 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
515 _changed_size_hints, obj);
516 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
523 * Get the right side icon
525 * @param obj The editfield object
526 * @return icon object
531 elm_editfield_right_icon_get(Evas_Object *obj)
533 Widget_Data *wd = elm_widget_data_get(obj);
534 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
535 if (!wd || !wd->base || !wd->ricon)
541 * Set entry object style as single-line or multi-line.
543 * @param obj The editfield object
544 * @param single_line 1 if single-line , 0 if multi-line
549 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
551 Widget_Data *wd = elm_widget_data_get(obj);
553 ELM_CHECK_WIDTYPE(obj, widtype);
554 if (!wd || !wd->base || wd->single_line == single_line)
556 wd->single_line = single_line;
557 elm_entry_single_line_set(wd->entry, single_line);
560 wd->scroller = elm_scroller_add(obj);
561 elm_scroller_bounce_set(wd->scroller, 0, 0);
562 elm_scroller_policy_set(wd->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
563 elm_widget_sub_object_add(obj, wd->scroller);
564 elm_scroller_content_min_limit(wd->scroller, 0, 1);
566 edje_object_part_unswallow(wd->base, wd->entry);
567 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scroller);
568 elm_scroller_content_set(wd->scroller, wd->entry);
571 entry = elm_entry_add(obj);
572 elm_object_style_set(entry, "editfield");
573 evas_object_size_hint_weight_set(entry, 0, EVAS_HINT_EXPAND);
574 evas_object_size_hint_align_set(entry, 0, EVAS_HINT_FILL);
575 evas_object_event_callback_add(entry,
576 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
577 _changed_size_hints, obj);
578 edje_object_part_swallow(wd->base, "elm.swallow.content", entry);
579 evas_object_smart_callback_add(entry, "changed", _entry_changed_cb, obj);
580 elm_widget_sub_object_add(obj, entry);
581 elm_entry_entry_set(entry, elm_entry_entry_get(wd->entry));
583 edje_object_part_unswallow(wd->base, wd->scroller);
584 evas_object_del(wd->entry);
586 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
591 * Get the current entry object style(single-line or multi-line)
593 * @param obj The editfield object
594 * @return 1 if single-line , 0 if multi-line
599 elm_editfield_entry_single_line_get(Evas_Object *obj)
601 Widget_Data *wd = elm_widget_data_get(obj);
602 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
603 if (!wd || !wd->base)
605 return wd->single_line;
609 * Set enable user to clean all of text.
611 * @param obj The editfield object
612 * @param visible If true, the eraser is visible and user can clean all of text by using eraser.
613 * If false, the eraser is invisible.
618 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
620 Widget_Data *wd = elm_widget_data_get(obj);
621 ELM_CHECK_WIDTYPE(obj, widtype);
622 if (!wd || !wd->base)
625 wd->eraser_show = visible;
628 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
630 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
636 * Get the current state of erase (visible/invisible)
638 * @param obj The editfield object
639 * @return 1 if visible, 0 if invisible
644 elm_editfield_eraser_get(Evas_Object *obj)
646 Widget_Data *wd = elm_widget_data_get(obj);
647 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
648 if (!wd || !wd->base)
650 return wd->eraser_show;