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 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
76 if(_empty_entry(wd->entry))
80 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
81 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
82 wd->show_guide_text = EINA_TRUE;
89 _theme_hook(Evas_Object *obj)
91 Widget_Data *wd = elm_widget_data_get(obj);
94 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
96 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scroller);
98 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
100 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
101 if(wd->show_guide_text)
103 if(_empty_entry(wd->entry))
107 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
108 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
113 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
115 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
120 _changed_hook(Evas_Object *obj)
122 Widget_Data *wd = elm_widget_data_get(obj);
123 if (wd->needs_size_calc)
126 wd->needs_size_calc = EINA_FALSE;
131 _sizing_eval(Evas_Object *obj)
133 Widget_Data *wd = elm_widget_data_get(obj);
134 Evas_Coord minw = -1, minh = -1;
135 edje_object_size_min_calc(wd->base, &minw, &minh);
136 evas_object_size_hint_min_set(obj, minw, minh);
137 evas_object_size_hint_max_set(obj, -1, -1);
141 _request_sizing_eval(Evas_Object *obj)
143 Widget_Data *wd = elm_widget_data_get(obj);
146 if (wd->needs_size_calc)
148 wd->needs_size_calc = EINA_TRUE;
149 evas_object_smart_changed(obj);
153 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
156 evas_object_size_hint_weight_get(data, &weight_x, NULL);
157 if (weight_x == EVAS_HINT_EXPAND)
158 _request_sizing_eval(data);
162 _empty_entry(Evas_Object *entry)
168 text = elm_entry_entry_get(entry);
169 if(!text) return EINA_FALSE;
170 strip_text = elm_entry_markup_to_utf8(text);
172 len = strlen(strip_text);
182 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info)
184 Evas_Object *ef_obj = (Evas_Object *)data;
185 Widget_Data *wd = elm_widget_data_get(ef_obj);
187 if(!wd || !wd->base) return;
189 if(!_empty_entry(wd->entry))
192 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
195 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
196 wd->show_guide_text = EINA_FALSE;
202 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
206 #ifdef HAVE_CONFORMANT_AUTOSCROLL
208 _entry_cursor_changed_cb(void *data, Evas_Object *obj, void* event_info)
210 Evas_Object *ef_obj = (Evas_Object *)data;
211 evas_object_smart_callback_call(ef_obj, SIG_IMPREGION_CHANGED, NULL);
216 _signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
218 Widget_Data *wd = elm_widget_data_get(data);
219 if(!wd || !wd->base) return;
221 if(!strcmp(source, "eraser"))
223 elm_entry_entry_set(wd->entry, "");
224 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
226 else if(strcmp(source, "left_icon") && strcmp(source, "right_icon") && strcmp(source, "eraser"))
228 edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
230 elm_object_focus(wd->entry);
232 if(wd->editing == EINA_FALSE)
233 elm_entry_cursor_end_set(wd->entry);
235 if(!(_empty_entry(wd->entry)) && (wd->eraser_show))
236 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
240 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
241 wd->show_guide_text = EINA_FALSE;
243 evas_object_smart_callback_call(data, "clicked", NULL);
244 wd->editing = EINA_TRUE;
249 _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
251 Widget_Data *wd = elm_widget_data_get(data);
253 if (!wd || !wd->base) return;
254 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
258 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
260 Widget_Data *wd = elm_widget_data_get(obj);
262 edje_object_signal_emit(wd->base, emission, source);
267 * Add a new editfield object
269 * @param parent The parent object
270 * @return The new object or NULL if it cannot be created
275 elm_editfield_add(Evas_Object *parent)
281 e = evas_object_evas_get(parent);
284 wd = ELM_NEW(Widget_Data);
285 obj = elm_widget_add(e);
286 ELM_SET_WIDTYPE(widtype, "editfield");
287 elm_widget_type_set(obj, "editfield");
288 elm_widget_sub_object_add(parent, obj);
289 elm_widget_data_set(obj, wd);
290 elm_widget_del_hook_set(obj, _del_hook);
291 elm_widget_theme_hook_set(obj, _theme_hook);
292 elm_widget_changed_hook_set(obj, _changed_hook);
293 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
294 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
295 elm_widget_can_focus_set(obj, EINA_TRUE);
296 #ifdef HAVE_CONFORMANT_AUTOSCROLL
297 elm_widget_imp_region_get_hook_set(obj, _imp_region_get_hook, NULL);
300 wd->base = edje_object_add(e);
301 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
302 elm_widget_resize_object_set(obj, wd->base);
303 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
304 _signal_mouse_clicked, obj);
305 edje_object_signal_callback_add(wd->base, "clicked", "*",
306 _signal_mouse_clicked, obj);
308 evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
310 wd->editing = EINA_FALSE;
311 wd->single_line = EINA_FALSE;
312 wd->eraser_show = EINA_FALSE;
314 wd->entry = elm_entry_add(obj);
315 elm_object_style_set(wd->entry, "editfield");
316 evas_object_size_hint_weight_set(wd->entry, 0, EVAS_HINT_EXPAND);
317 evas_object_size_hint_align_set(wd->entry, 0, EVAS_HINT_FILL);
318 evas_object_event_callback_add(wd->entry,
319 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
320 _changed_size_hints, obj);
321 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
322 evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);
323 elm_widget_sub_object_add(obj, wd->entry);
324 #ifdef HAVE_CONFORMANT_AUTOSCROLL
325 evas_object_smart_callback_add(wd->entry, SIG_CURSOR_CHANGED, _entry_cursor_changed_cb, obj);
334 * Set the label of editfield
336 * @param obj The editfield object
337 * @param label The label text
342 elm_editfield_label_set(Evas_Object *obj, const char *label)
344 Widget_Data *wd = elm_widget_data_get(obj);
345 ELM_CHECK_WIDTYPE(obj, widtype);
346 if (!wd || !wd->base)
349 eina_stringshare_del(wd->label);
352 wd->label = eina_stringshare_add(label);
353 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
354 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
359 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
360 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
362 edje_object_message_signal_process(wd->base);
363 edje_object_part_text_set(wd->base, "elm.text", label);
368 * Get the label used on the editfield object
370 * @param obj The editfield object
376 elm_editfield_label_get(Evas_Object *obj)
378 Widget_Data *wd = elm_widget_data_get(obj);
379 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
380 if (!wd || !wd->base)
386 * Set the guidance text used on the editfield object
388 * @param obj The editfield object
394 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
396 Widget_Data *wd = elm_widget_data_get(obj);
397 ELM_CHECK_WIDTYPE(obj, widtype);
398 if (!wd || !wd->base)
401 eina_stringshare_del(wd->guide_text);
404 wd->guide_text = eina_stringshare_add(text);
405 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
406 wd->show_guide_text = EINA_TRUE;
409 wd->guide_text = NULL;
413 * Get the guidance text used on the editfield object
415 * @param obj The editfield object
421 elm_editfield_guide_text_get(Evas_Object *obj)
423 Widget_Data *wd = elm_widget_data_get(obj);
424 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
425 if (!wd || !wd->base)
427 return wd->guide_text;
431 * Get the entry of the editfield object
433 * @param obj The editfield object
434 * @return entry object
440 elm_editfield_entry_get(Evas_Object *obj)
442 Widget_Data *wd = elm_widget_data_get(obj);
443 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
450 * Set the left side icon.
452 * @param obj The editfield object
453 * @param icon The icon object
458 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
460 Widget_Data *wd = elm_widget_data_get(obj);
461 ELM_CHECK_WIDTYPE(obj, widtype) ;
462 if (!wd || !wd->base || !icon)
464 if ((wd->licon != icon) && (wd->licon))
465 elm_widget_sub_object_del(obj, wd->licon);
468 if (!(edje_object_part_swallow(wd->base, "left_icon", icon)))
471 elm_widget_sub_object_add(obj, icon);
472 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
473 _changed_size_hints, obj);
474 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
475 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
482 * Get the left side icon
484 * @param obj The editfield object
485 * @return icon object
490 elm_editfield_left_icon_get(Evas_Object *obj)
492 Widget_Data *wd = elm_widget_data_get(obj);
493 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
494 if (!wd || !wd->base || !wd->licon)
500 * Set the right side icon.
502 * @param obj The editfield object
503 * @param icon The icon object
508 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
510 Widget_Data *wd = elm_widget_data_get(obj);
511 ELM_CHECK_WIDTYPE(obj, widtype) ;
512 if (!wd || !wd->base || !icon)
514 if ((wd->ricon != icon) && (wd->ricon))
515 elm_widget_sub_object_del(obj, wd->ricon);
518 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
521 elm_widget_sub_object_add(obj, icon);
522 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
523 _changed_size_hints, obj);
524 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
531 * Get the right side icon
533 * @param obj The editfield object
534 * @return icon object
539 elm_editfield_right_icon_get(Evas_Object *obj)
541 Widget_Data *wd = elm_widget_data_get(obj);
542 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
543 if (!wd || !wd->base || !wd->ricon)
549 * Set entry object style as single-line or multi-line.
551 * @param obj The editfield object
552 * @param single_line 1 if single-line , 0 if multi-line
557 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
559 Widget_Data *wd = elm_widget_data_get(obj);
561 ELM_CHECK_WIDTYPE(obj, widtype);
562 if (!wd || !wd->base || wd->single_line == single_line)
564 wd->single_line = single_line;
565 elm_entry_single_line_set(wd->entry, single_line);
568 wd->scroller = elm_scroller_add(obj);
569 elm_scroller_bounce_set(wd->scroller, 0, 0);
570 elm_scroller_policy_set(wd->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
571 elm_widget_sub_object_add(obj, wd->scroller);
572 elm_scroller_content_min_limit(wd->scroller, 0, 1);
574 edje_object_part_unswallow(wd->base, wd->entry);
575 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scroller);
576 evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
577 evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
579 elm_scroller_content_set(wd->scroller, wd->entry);
582 entry = elm_entry_add(obj);
583 elm_object_style_set(entry, "editfield");
584 evas_object_size_hint_weight_set(entry, 0, EVAS_HINT_EXPAND);
585 evas_object_size_hint_align_set(entry, 0, EVAS_HINT_FILL);
586 evas_object_event_callback_add(entry,
587 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
588 _changed_size_hints, obj);
589 edje_object_part_swallow(wd->base, "elm.swallow.content", entry);
590 evas_object_smart_callback_add(entry, "changed", _entry_changed_cb, obj);
591 elm_widget_sub_object_add(obj, entry);
592 elm_entry_entry_set(entry, elm_entry_entry_get(wd->entry));
594 edje_object_part_unswallow(wd->base, wd->scroller);
595 evas_object_del(wd->entry);
597 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
602 * Get the current entry object style(single-line or multi-line)
604 * @param obj The editfield object
605 * @return 1 if single-line , 0 if multi-line
610 elm_editfield_entry_single_line_get(Evas_Object *obj)
612 Widget_Data *wd = elm_widget_data_get(obj);
613 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
614 if (!wd || !wd->base)
616 return wd->single_line;
620 * Set enable user to clean all of text.
622 * @param obj The editfield object
623 * @param visible If true, the eraser is visible and user can clean all of text by using eraser.
624 * If false, the eraser is invisible.
629 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
631 Widget_Data *wd = elm_widget_data_get(obj);
632 ELM_CHECK_WIDTYPE(obj, widtype);
633 if (!wd || !wd->base)
636 wd->eraser_show = visible;
639 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
645 * Get the current state of erase (visible/invisible)
647 * @param obj The editfield object
648 * @return 1 if visible, 0 if invisible
653 elm_editfield_eraser_get(Evas_Object *obj)
655 Widget_Data *wd = elm_widget_data_get(obj);
656 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
657 if (!wd || !wd->base)
659 return wd->eraser_show;
662 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/