1 #include <Elementary.h>
5 * @defgroup Editfield Editfield
8 * This is a editfield. It can contain a simple label and icon objects.
10 * Smart callbacks that you can add are:
12 * clicked - This signal is emitted when an editfield is clicked.
14 * unfocused - This signal is emitted when an editfield is unfocused.
18 //#define ERASER_PADDING (10)
20 typedef struct _Widget_Data Widget_Data;
29 const char *guide_text;
30 Eina_Bool needs_size_calc:1;
31 Eina_Bool show_guide_text:1;
33 Eina_Bool single_line:1;
34 Eina_Bool eraser_show:1;
37 static const char *widtype = NULL;
38 static void _del_hook(Evas_Object *obj);
39 static void _theme_hook(Evas_Object *obj);
40 static void _sizing_eval(Evas_Object *obj);
41 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
42 static void _show_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
43 static void _on_focus_hook(void *data, Evas_Object *obj);
44 static Eina_Bool _empty_entry(Evas_Object *entry);
47 _del_hook(Evas_Object *obj)
49 Widget_Data *wd = elm_widget_data_get(obj);
51 if (wd->label) eina_stringshare_del(wd->label);
56 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
58 Widget_Data *wd = elm_widget_data_get(obj);
61 if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)) )
63 evas_object_smart_callback_call(obj, "unfocused", NULL);
64 wd->editing = EINA_FALSE;
65 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
67 if (!wd->single_line) // FIXME : if textblock works well, delete
68 edje_object_signal_emit(wd->base, "elm,state,entry,show", "elm"); // FIXME : if textblock works well, delete
70 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
71 if(_empty_entry(wd->entry))
75 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
76 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
77 wd->show_guide_text = EINA_TRUE;
84 _theme_hook(Evas_Object *obj)
86 Widget_Data *wd = elm_widget_data_get(obj);
91 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
92 snprintf(buf, sizeof(buf), "editfield/%s", elm_widget_style_get(obj));
93 elm_object_style_set(wd->entry, buf);
94 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
96 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
97 if(wd->show_guide_text)
99 if(_empty_entry(wd->entry))
103 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
104 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
109 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
111 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
116 _changed_hook(Evas_Object *obj)
118 Widget_Data *wd = elm_widget_data_get(obj);
119 if (wd->needs_size_calc)
122 wd->needs_size_calc = EINA_FALSE;
127 _sizing_eval(Evas_Object *obj)
129 Widget_Data *wd = elm_widget_data_get(obj);
130 Evas_Coord minw = -1, minh = -1;
131 edje_object_size_min_calc(wd->base, &minw, &minh);
132 evas_object_size_hint_min_set(obj, minw, minh);
133 evas_object_size_hint_max_set(obj, -1, -1);
137 _request_sizing_eval(Evas_Object *obj)
139 Widget_Data *wd = elm_widget_data_get(obj);
142 if (wd->needs_size_calc)
144 wd->needs_size_calc = EINA_TRUE;
145 evas_object_smart_changed(obj);
149 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
152 evas_object_size_hint_weight_get(data, &weight_x, NULL);
153 if (weight_x == EVAS_HINT_EXPAND)
154 _request_sizing_eval(data);
158 _show_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
160 Widget_Data *wd = elm_widget_data_get(data);
161 if ((!wd) && (!wd->entry)) return;
162 if (wd->editing && wd->single_line) // FIXME : single_line is not needed for this conditional state after TEXTBLOCK fixing
163 elm_object_focus(wd->entry);
167 _empty_entry(Evas_Object *entry)
173 text = elm_entry_entry_get(entry);
174 if(!text) return EINA_FALSE;
175 strip_text = elm_entry_markup_to_utf8(text);
177 len = strlen(strip_text);
187 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info __UNUSED__)
189 Evas_Object *ef_obj = (Evas_Object *)data;
190 Widget_Data *wd = elm_widget_data_get(ef_obj);
192 if(!wd || !wd->base) return;
196 if(elm_entry_password_get(wd->entry))
198 edje_object_signal_emit(wd->base, "elm,state,password,set", "elm");
199 edje_object_part_text_set(wd->base, "elm.content.password", elm_entry_entry_get(wd->entry));
203 edje_object_signal_emit(wd->base, "elm,state,password,unset", "elm");
204 edje_object_part_text_set(wd->base, "elm.content.single", elm_entry_entry_get(wd->entry));
207 // else // Add after TEXTBLOCK fix
208 // edje_object_part_text_set(wd->base, "elm.content.multi", elm_entry_entry_get(wd->entry));
210 if(!_empty_entry(wd->entry))
212 if(wd->eraser_show && elm_object_focus_get(obj))
213 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
216 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
217 wd->show_guide_text = EINA_FALSE;
223 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
226 if (!wd->editing && wd->single_line)
227 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
231 _signal_mouse_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source)
233 Widget_Data *wd = elm_widget_data_get(data);
234 if(!wd || !wd->base) return;
236 if(!strcmp(source, "eraser"))
238 elm_entry_entry_set(wd->entry, "");
239 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
241 else if(strcmp(source, "left_icon") && strcmp(source, "right_icon") && strcmp(source, "eraser"))
243 edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
245 if(wd->editing == EINA_FALSE)
246 elm_entry_cursor_end_set(wd->entry);
248 wd->editing = EINA_TRUE;
250 if (!wd->single_line) //FIXME : after fixing TEXTBLOCK, this should be deleted
251 elm_object_focus(wd->entry);
253 if(!(_empty_entry(wd->entry)) && (wd->eraser_show))
254 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
258 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
259 wd->show_guide_text = EINA_FALSE;
261 evas_object_smart_callback_call(data, "clicked", NULL);
266 _resize_cb(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
268 Widget_Data *wd = elm_widget_data_get(data);
270 if (!wd || !wd->base) return;
271 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
275 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
277 Widget_Data *wd = elm_widget_data_get(obj);
279 edje_object_signal_emit(wd->base, emission, source);
284 * Add a new editfield object
286 * @param parent The parent object
287 * @return The new object or NULL if it cannot be created
292 elm_editfield_add(Evas_Object *parent)
298 e = evas_object_evas_get(parent);
301 wd = ELM_NEW(Widget_Data);
302 obj = elm_widget_add(e);
303 ELM_SET_WIDTYPE(widtype, "editfield");
304 elm_widget_type_set(obj, "editfield");
305 elm_widget_sub_object_add(parent, obj);
306 elm_widget_data_set(obj, wd);
307 elm_widget_del_hook_set(obj, _del_hook);
308 elm_widget_theme_hook_set(obj, _theme_hook);
309 elm_widget_changed_hook_set(obj, _changed_hook);
310 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
311 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
312 elm_widget_can_focus_set(obj, EINA_TRUE);
314 wd->base = edje_object_add(e);
315 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
316 elm_widget_resize_object_set(obj, wd->base);
317 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
318 _signal_mouse_clicked, obj);
319 edje_object_signal_callback_add(wd->base, "clicked", "*",
320 _signal_mouse_clicked, obj);
322 evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
324 wd->editing = EINA_FALSE;
325 wd->single_line = EINA_FALSE;
326 wd->eraser_show = EINA_TRUE;
328 wd->entry = elm_entry_add(obj);
329 elm_object_style_set(wd->entry, "editfield");
330 evas_object_size_hint_weight_set(wd->entry, 0, EVAS_HINT_EXPAND);
331 evas_object_size_hint_align_set(wd->entry, 0, EVAS_HINT_FILL);
332 evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
333 evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_SHOW, _show_cb, obj);
334 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
335 evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);
336 elm_widget_sub_object_add(obj, wd->entry);
337 evas_object_show(wd->entry);
344 * Set the label of editfield
346 * @param obj The editfield object
347 * @param label The label text
352 elm_editfield_label_set(Evas_Object *obj, const char *label)
354 Widget_Data *wd = elm_widget_data_get(obj);
355 ELM_CHECK_WIDTYPE(obj, widtype);
356 if (!wd || !wd->base)
359 eina_stringshare_del(wd->label);
362 wd->label = eina_stringshare_add(label);
363 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
364 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
369 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
370 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
372 edje_object_message_signal_process(wd->base);
373 edje_object_part_text_set(wd->base, "elm.text", label);
378 * Get the label used on the editfield object
380 * @param obj The editfield object
386 elm_editfield_label_get(Evas_Object *obj)
388 Widget_Data *wd = elm_widget_data_get(obj);
389 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
390 if (!wd || !wd->base)
396 * Set the guidance text used on the editfield object
398 * @param obj The editfield object
404 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
406 Widget_Data *wd = elm_widget_data_get(obj);
407 ELM_CHECK_WIDTYPE(obj, widtype);
408 if (!wd || !wd->base)
411 eina_stringshare_del(wd->guide_text);
414 wd->guide_text = eina_stringshare_add(text);
415 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
416 wd->show_guide_text = EINA_TRUE;
419 wd->guide_text = NULL;
423 * Get the guidance text used on the editfield object
425 * @param obj The editfield object
431 elm_editfield_guide_text_get(Evas_Object *obj)
433 Widget_Data *wd = elm_widget_data_get(obj);
434 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
435 if (!wd || !wd->base)
437 return wd->guide_text;
441 * Get the entry of the editfield object
443 * @param obj The editfield object
444 * @return entry object
450 elm_editfield_entry_get(Evas_Object *obj)
452 Widget_Data *wd = elm_widget_data_get(obj);
453 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
460 * Set the left side icon.
462 * @param obj The editfield object
463 * @param icon The icon object
468 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
470 Widget_Data *wd = elm_widget_data_get(obj);
471 ELM_CHECK_WIDTYPE(obj, widtype) ;
472 if (!wd || !wd->base || !icon)
474 if ((wd->licon != icon) && (wd->licon))
475 elm_widget_sub_object_del(obj, wd->licon);
478 if (!(edje_object_part_swallow(wd->base, "left_icon", icon)))
481 elm_widget_sub_object_add(obj, icon);
482 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
483 _changed_size_hints, obj);
484 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
485 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
492 * Get the left side icon
494 * @param obj The editfield object
495 * @return icon object
500 elm_editfield_left_icon_get(Evas_Object *obj)
502 Widget_Data *wd = elm_widget_data_get(obj);
503 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
504 if (!wd || !wd->base || !wd->licon)
510 * Set the right side icon.
512 * @param obj The editfield object
513 * @param icon The icon object
518 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
520 Widget_Data *wd = elm_widget_data_get(obj);
521 ELM_CHECK_WIDTYPE(obj, widtype) ;
522 if (!wd || !wd->base || !icon)
524 if ((wd->ricon != icon) && (wd->ricon))
525 elm_widget_sub_object_del(obj, wd->ricon);
528 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
531 elm_widget_sub_object_add(obj, icon);
532 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
533 _changed_size_hints, obj);
534 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
541 * Get the right side icon
543 * @param obj The editfield object
544 * @return icon object
549 elm_editfield_right_icon_get(Evas_Object *obj)
551 Widget_Data *wd = elm_widget_data_get(obj);
552 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
553 if (!wd || !wd->base || !wd->ricon)
559 * Set entry object style as single-line or multi-line.
561 * @param obj The editfield object
562 * @param single_line 1 if single-line , 0 if multi-line
567 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
569 Widget_Data *wd = elm_widget_data_get(obj);
570 ELM_CHECK_WIDTYPE(obj, widtype);
571 if (!wd || !wd->base || wd->single_line == single_line)
573 wd->single_line = !!single_line;
574 elm_entry_single_line_set(wd->entry, single_line);
577 elm_entry_scrollable_set(wd->entry, EINA_TRUE);
578 elm_entry_single_line_set(wd->entry,EINA_TRUE);
579 edje_object_signal_emit(wd->base, "elm,state,text,singleline", "elm");
583 elm_entry_scrollable_set(wd->entry, EINA_FALSE);
584 elm_entry_single_line_set(wd->entry,EINA_FALSE);
585 edje_object_signal_emit(wd->base, "elm,state,text,multiline", "elm");
588 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
592 * Get the current entry object style(single-line or multi-line)
594 * @param obj The editfield object
595 * @return 1 if single-line , 0 if multi-line
600 elm_editfield_entry_single_line_get(Evas_Object *obj)
602 Widget_Data *wd = elm_widget_data_get(obj);
603 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
604 if (!wd || !wd->base)
606 return wd->single_line;
610 * Set enable user to clean all of text.
612 * @param obj The editfield object
613 * @param visible If true, the eraser is visible and user can clean all of text by using eraser.
614 * If false, the eraser is invisible.
619 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
621 Widget_Data *wd = elm_widget_data_get(obj);
622 ELM_CHECK_WIDTYPE(obj, widtype);
623 if (!wd || !wd->base)
626 wd->eraser_show = !!visible;
629 edje_object_signal_emit(wd->base, "elm,state,eraser,hidden", "elm");
635 * Get the current state of erase (visible/invisible)
637 * @param obj The editfield object
638 * @return 1 if visible, 0 if invisible
643 elm_editfield_eraser_get(Evas_Object *obj)
645 Widget_Data *wd = elm_widget_data_get(obj);
646 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
647 if (!wd || !wd->base)
649 return wd->eraser_show;
652 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/