1 #include <Elementary.h>
5 * @addtogroup Editfield Editfield
7 * This is a editfield. It can contain a simple label and icon objects.
10 #define ERASER_PADDING (10)
12 typedef struct _Widget_Data Widget_Data;
22 const char *guide_text;
23 Eina_Bool needs_size_calc:1;
24 Eina_Bool show_guide_text:1;
26 Eina_Bool single_line : 1;
27 Eina_Bool eraser_visible : 1;
28 Evas_Event_Mouse_Down down_ev;
31 static void _del_hook(Evas_Object *obj);
32 static void _theme_hook(Evas_Object *obj);
33 static void _disable_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);
38 static void _eraser_drag_end(void *data, Evas_Object *obj, const char *emission, const char *source);
39 static void _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
40 static void _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _eraser_init(Evas_Object *obj);
44 _del_hook(Evas_Object *obj)
46 Widget_Data *wd = elm_widget_data_get(obj);
48 if (wd->label) eina_stringshare_del(wd->label);
53 _on_focus_hook(void *data, Evas_Object *obj)
55 Widget_Data *wd = elm_widget_data_get(obj);
57 if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)) ) {
59 wd->editing = EINA_FALSE;
60 edje_object_signal_emit(wd->base, "elm,action,unfocus", "elm");
61 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
64 text = elm_entry_entry_get(wd->entry);
65 edje_object_part_text_set(wd->base, "elm.content.no.edit", text);
66 edje_object_signal_emit(wd->base, "elm,action,no,edit", "elm");
68 if(_empty_entry(wd->entry)) {
70 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
71 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
72 wd->show_guide_text = EINA_TRUE;
79 _theme_hook(Evas_Object *obj)
81 Widget_Data *wd = elm_widget_data_get(obj);
84 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
85 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
89 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
91 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
94 edje_object_part_swallow(wd->base, "eraser", wd->eraser);
100 _disable_hook(Evas_Object *obj)
102 Widget_Data *wd = elm_widget_data_get(obj);
103 if (elm_widget_disabled_get(obj)) {
104 elm_object_disabled_set(wd->entry, EINA_TRUE);
105 edje_object_signal_emit(wd->base, "elm,action,dim", "elm");
108 elm_object_disabled_set(wd->entry, EINA_FALSE);
109 edje_object_signal_emit(wd->base, "elm,action,dimup", "elm");
114 _changed_hook(Evas_Object *obj)
116 Widget_Data *wd = elm_widget_data_get(obj);
117 if (wd->needs_size_calc)
120 wd->needs_size_calc = 0;
125 _sizing_eval(Evas_Object *obj)
127 Widget_Data *wd = elm_widget_data_get(obj);
128 Evas_Coord minw = -1, minh = -1;
130 edje_object_size_min_calc(wd->base, &minw, &minh);
131 evas_object_size_hint_min_set(obj, minw, minh);
132 evas_object_size_hint_max_set(obj, -1, -1);
136 _request_sizing_eval(Evas_Object *obj)
138 Widget_Data *wd = elm_widget_data_get(obj);
140 if (wd->needs_size_calc) return;
141 wd->needs_size_calc = 1;
142 evas_object_smart_changed(obj);
146 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
149 evas_object_size_hint_weight_get(data, &weight_x, NULL);
150 if (weight_x == EVAS_HINT_EXPAND)
151 _request_sizing_eval(data);
155 _empty_entry(Evas_Object *entry)
161 text = elm_entry_entry_get(entry);
162 if(!text) return EINA_FALSE;
164 strip_text = elm_entry_markup_to_utf8(text);
167 len = strlen(strip_text);
180 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info)
183 Evas_Object *ef_obj = (Evas_Object *)data;
184 Widget_Data *wd = elm_widget_data_get(ef_obj);
186 if(!wd || !ef_obj) return;
188 if(!_empty_entry(wd->entry)) {
191 text = elm_entry_entry_get(wd->entry);
192 edje_object_part_text_set(wd->base, "elm.content.no.edit", text);
195 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
196 wd->show_guide_text = EINA_FALSE;
202 _signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
204 Widget_Data *wd = elm_widget_data_get(data);
207 if(strcmp(source, "left_icon") && strcmp(source, "right_icon") && strcmp(source, "over_change_bg"))
209 edje_object_signal_emit(wd->base, "elm,action,focus", "elm");
210 edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
213 edje_object_signal_emit(wd->base, "elm,action,edit", "elm");
214 elm_widget_focus_set(wd->entry, 1);
216 if(wd->editing == EINA_FALSE) {
217 elm_entry_cursor_end_set(wd->entry);
218 evas_object_smart_callback_call(wd->entry, "clicked", NULL); // after completing of guide, should be eleminated
221 if(!_empty_entry(wd->entry)) {
223 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
224 wd->show_guide_text = EINA_FALSE;
228 evas_object_smart_callback_call(data, "clicked", NULL);
230 wd->editing = EINA_TRUE;
235 _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
237 Widget_Data *wd = elm_widget_data_get(data);
241 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
242 evas_object_geometry_get(wd->eraser, NULL, NULL, &w, NULL);
244 evas_object_size_hint_min_set(wd->eraser, w, h - ERASER_PADDING);
245 evas_object_resize(wd->eraser, w, h - ERASER_PADDING);
249 _eraser_drag_end(void *data, Evas_Object *obj, const char *emission, const char *source)
251 Widget_Data *wd = elm_widget_data_get(data);
252 if (!wd || !wd->entry) return;
253 elm_entry_entry_set(wd->entry, "");
257 _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
259 Widget_Data *wd = elm_widget_data_get(data);
261 memcpy(&wd->down_ev, event_info, sizeof(Evas_Event_Mouse_Down));
265 _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
267 Widget_Data *wd = elm_widget_data_get(data);
268 Evas_Event_Mouse_Up *ev = event_info;
274 edje_object_part_drag_value_get(wd->base, "eraser", &pos, NULL);
276 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
280 dur = ev->timestamp - wd->down_ev.timestamp;
281 distance = wd->down_ev.canvas.x - ev->canvas.x;
283 if ((dur && dur > 1000) || (distance < 10 && distance > -10)) {
284 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
288 if(((float)distance / dur) > 0.5)
289 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
291 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
295 _eraser_init(Evas_Object *obj)
297 Widget_Data *wd = elm_widget_data_get(obj);
301 wd->single_line = EINA_TRUE;
302 wd->eraser_visible = EINA_TRUE;
303 wd->eraser = edje_object_add(evas_object_evas_get(obj));
304 elm_widget_sub_object_add(obj, wd->eraser);
305 _elm_theme_object_set(obj, wd->eraser, "editfield/eraser", "base", "default");
306 edje_object_part_swallow(wd->base, "eraser", wd->eraser);
308 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_DOWN, _eraser_mouse_down, obj);
309 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_UP, _eraser_mouse_up, obj);
310 edje_object_signal_callback_add(wd->base, "drag", "end", _eraser_drag_end, obj);
314 * Add a new editfield object
316 * @param parent The parent object
317 * @return The new object or NULL if it cannot be created
322 elm_editfield_add(Evas_Object *parent)
328 wd = ELM_NEW(Widget_Data);
329 e = evas_object_evas_get(parent);
330 obj = elm_widget_add(e);
331 elm_widget_type_set(obj, "editfield");
332 elm_widget_sub_object_add(parent, obj);
333 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
334 elm_widget_data_set(obj, wd);
335 elm_widget_del_hook_set(obj, _del_hook);
336 elm_widget_theme_hook_set(obj, _theme_hook);
337 elm_widget_disable_hook_set(obj, _disable_hook);
338 elm_widget_changed_hook_set(obj, _changed_hook);
339 elm_widget_can_focus_set(obj, EINA_TRUE);
341 wd->base = edje_object_add(e);
342 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
343 elm_widget_resize_object_set(obj, wd->base);
345 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
346 _signal_mouse_clicked, obj);
347 wd->editing = EINA_FALSE;
348 wd->entry = elm_entry_add(obj);
349 elm_object_style_set(wd->entry, "editfield");
350 evas_object_size_hint_weight_set(wd->entry, 0, EVAS_HINT_EXPAND);
351 evas_object_size_hint_align_set(wd->entry, 0, EVAS_HINT_FILL);
352 evas_object_event_callback_add(wd->entry,
353 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
354 _changed_size_hints, obj);
355 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
357 evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);
358 evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
367 * Set the label of editfield
369 * @param obj The editfield object
370 * @param label The label text
375 elm_editfield_label_set(Evas_Object *obj, const char *label)
377 Widget_Data *wd = elm_widget_data_get(obj);
380 if (wd->label) eina_stringshare_del(wd->label);
383 wd->label = eina_stringshare_add(label);
384 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
386 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
391 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
393 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
396 edje_object_message_signal_process(wd->base);
397 edje_object_part_text_set(wd->base, "elm.text", label);
403 * Get the label used on the editfield object
405 * @param obj The editfield object
411 elm_editfield_label_get(Evas_Object *obj)
413 Widget_Data *wd = elm_widget_data_get(obj);
414 if (!wd) return NULL;
419 * Get the label used on the editfield object
421 * @param obj The editfield object
427 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
429 Widget_Data *wd = elm_widget_data_get(obj);
432 if (wd->guide_text) eina_stringshare_del(wd->guide_text);
435 wd->guide_text = eina_stringshare_add(text);
436 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
437 wd->show_guide_text = EINA_TRUE;
441 wd->guide_text = NULL;
446 * Get the guidance text used on the editfield object
448 * @param obj The editfield object
454 elm_editfield_guide_text_get(Evas_Object *obj)
456 Widget_Data *wd = elm_widget_data_get(obj);
457 if (!wd) return NULL;
459 return wd->guide_text;
463 * Get the entry of the editfield object
465 * @param obj The editfield object
466 * @return entry object
472 elm_editfield_entry_get(Evas_Object *obj)
474 Widget_Data *wd = elm_widget_data_get(obj);
475 if (!wd) return NULL;
480 * Set the left side icon.
482 * @param obj The editfield object
483 * @param icon The icon object
484 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
489 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
491 Widget_Data *wd = elm_widget_data_get(obj);
493 if ((wd->licon != icon) && (wd->licon))
494 elm_widget_sub_object_del(obj, wd->licon);
498 if ( !(edje_object_part_swallow(wd->base, "left_icon", icon)) )
501 elm_widget_sub_object_add(obj, icon);
502 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
503 _changed_size_hints, obj);
504 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
505 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
512 * Get the left side icon
514 * @param obj The editfield object
515 * @return icon object
520 elm_editfield_left_icon_get(Evas_Object *obj)
522 Widget_Data *wd = elm_widget_data_get(obj);
523 if (!wd) return NULL;
528 * Set the right side icon.
530 * @param obj The editfield object
531 * @param icon The icon object
532 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
537 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
539 Widget_Data *wd = elm_widget_data_get(obj);
541 if ((wd->ricon != icon) && (wd->ricon))
542 elm_widget_sub_object_del(obj, wd->ricon);
546 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
549 elm_widget_sub_object_add(obj, icon);
550 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
551 _changed_size_hints, obj);
552 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
559 * Get the right side icon
561 * @param obj The editfield object
562 * @return icon object
567 elm_editfield_right_icon_get(Evas_Object *obj)
569 Widget_Data *wd = elm_widget_data_get(obj);
570 if (!wd) return NULL;
575 * Set entry object style as single-line or multi-line.
577 * @param obj The editfield object
578 * @param single_line 1 if single-line , 0 if multi-line
583 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
585 Widget_Data *wd = elm_widget_data_get(obj);
587 wd->single_line = single_line;
588 elm_entry_single_line_set(wd->entry, single_line);
590 if(wd->single_line && wd->eraser_visible)
591 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
593 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");
597 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
599 Widget_Data *wd = elm_widget_data_get(obj);
601 wd->eraser_visible = visible;
603 if(wd->single_line && wd->eraser_visible)
604 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
606 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");