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;
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_visible : 1;
29 Evas_Event_Mouse_Down down_ev;
32 static const char *widtype = NULL;
33 static void _del_hook(Evas_Object *obj);
34 static void _theme_hook(Evas_Object *obj);
35 static void _sizing_eval(Evas_Object *obj);
36 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _on_focus_hook(void *data, Evas_Object *obj);
38 static Eina_Bool _empty_entry(Evas_Object *entry);
39 static void _eraser_drag_end(void *data, Evas_Object *obj, const char *emission, const char *source);
40 static void _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
42 static void _eraser_init(Evas_Object *obj);
45 _del_hook(Evas_Object *obj)
47 Widget_Data *wd = elm_widget_data_get(obj);
49 if (wd->label) eina_stringshare_del(wd->label);
54 _on_focus_hook(void *data, Evas_Object *obj)
56 Widget_Data *wd = elm_widget_data_get(obj);
60 if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)) ) {
61 wd->editing = EINA_FALSE;
62 edje_object_signal_emit(wd->base, "elm,action,unfocus", "elm");
63 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");
67 if(_empty_entry(wd->entry)) {
69 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
70 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
71 wd->show_guide_text = EINA_TRUE;
78 _theme_hook(Evas_Object *obj)
80 Widget_Data *wd = elm_widget_data_get(obj);
83 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
84 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
86 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
88 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
90 edje_object_part_swallow(wd->base, "eraser", wd->eraser);
95 _changed_hook(Evas_Object *obj)
97 Widget_Data *wd = elm_widget_data_get(obj);
98 if (wd->needs_size_calc)
101 wd->needs_size_calc = EINA_FALSE;
106 _sizing_eval(Evas_Object *obj)
108 Widget_Data *wd = elm_widget_data_get(obj);
109 Evas_Coord minw = -1, minh = -1;
110 edje_object_size_min_calc(wd->base, &minw, &minh);
111 evas_object_size_hint_min_set(obj, minw, minh);
112 evas_object_size_hint_max_set(obj, -1, -1);
116 _request_sizing_eval(Evas_Object *obj)
118 Widget_Data *wd = elm_widget_data_get(obj);
121 if (wd->needs_size_calc)
123 wd->needs_size_calc = EINA_TRUE;
124 evas_object_smart_changed(obj);
128 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
131 evas_object_size_hint_weight_get(data, &weight_x, NULL);
132 if (weight_x == EVAS_HINT_EXPAND)
133 _request_sizing_eval(data);
137 _empty_entry(Evas_Object *entry)
143 text = elm_entry_entry_get(entry);
144 if(!text) return EINA_FALSE;
145 strip_text = elm_entry_markup_to_utf8(text);
147 len = strlen(strip_text);
157 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info)
160 Evas_Object *ef_obj = (Evas_Object *)data;
161 Widget_Data *wd = elm_widget_data_get(ef_obj);
163 if(!wd || !wd->base) return;
165 if(!_empty_entry(wd->entry)) {
166 text = elm_entry_entry_get(wd->entry);
167 edje_object_part_text_set(wd->base, "elm.content.no.edit", text);
169 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
170 wd->show_guide_text = EINA_FALSE;
176 _signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
178 Widget_Data *wd = elm_widget_data_get(data);
179 if(!wd || !wd->base) return;
181 if(strcmp(source, "left_icon") && strcmp(source, "right_icon") && strcmp(source, "over_change_bg"))
183 edje_object_signal_emit(wd->base, "elm,action,focus", "elm");
184 edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
185 edje_object_signal_emit(wd->base, "elm,action,edit", "elm");
186 elm_widget_focus_set(wd->entry, EINA_TRUE);
187 if(wd->editing == EINA_FALSE)
188 elm_entry_cursor_end_set(wd->entry);
189 if(!_empty_entry(wd->entry)) {
191 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
192 wd->show_guide_text = EINA_FALSE;
195 evas_object_smart_callback_call(data, "clicked", NULL);
196 wd->editing = EINA_TRUE;
201 _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
203 Widget_Data *wd = elm_widget_data_get(data);
205 if (!wd || !wd->base) return;
206 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
207 evas_object_geometry_get(wd->eraser, NULL, NULL, &w, NULL);
208 evas_object_size_hint_min_set(wd->eraser, w, h - ERASER_PADDING);
209 evas_object_resize(wd->eraser, w, h - ERASER_PADDING);
213 _eraser_drag_end(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 || !wd->entry)
218 elm_entry_entry_set(wd->entry, "");
219 edje_object_part_text_set(wd->base, "elm.content.no.edit", "");
223 _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
225 Widget_Data *wd = elm_widget_data_get(data);
226 if (!wd || !wd->base)
228 memcpy(&wd->down_ev, event_info, sizeof(Evas_Event_Mouse_Down));
232 _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
234 Widget_Data *wd = elm_widget_data_get(data);
235 Evas_Event_Mouse_Up *ev = event_info;
239 if (!wd || !wd->base)
241 edje_object_part_drag_value_get(wd->base, "eraser", &pos, NULL);
243 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
246 dur = ev->timestamp - wd->down_ev.timestamp;
247 distance = wd->down_ev.canvas.x - ev->canvas.x;
248 if ((dur && dur > 1000) || (distance < 10 && distance > -10)) {
249 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
252 if(((float)distance / dur) > 0.5)
253 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
255 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
259 _eraser_init(Evas_Object *obj)
261 Widget_Data *wd = elm_widget_data_get(obj);
262 if (!wd || !wd->base)
264 wd->eraser = edje_object_add(evas_object_evas_get(obj));
265 elm_widget_sub_object_add(obj, wd->eraser);
266 _elm_theme_object_set(obj, wd->eraser, "editfield/eraser", "base", "default");
267 edje_object_part_swallow(wd->base, "eraser", wd->eraser);
268 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_DOWN, _eraser_mouse_down, obj);
269 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_UP, _eraser_mouse_up, obj);
270 edje_object_signal_callback_add(wd->base, "drag", "end", _eraser_drag_end, obj);
274 * Add a new editfield object
276 * @param parent The parent object
277 * @return The new object or NULL if it cannot be created
282 elm_editfield_add(Evas_Object *parent)
288 wd = ELM_NEW(Widget_Data);
289 e = evas_object_evas_get(parent);
292 obj = elm_widget_add(e);
293 ELM_SET_WIDTYPE(widtype, "editfield");
294 elm_widget_type_set(obj, "editfield");
295 elm_widget_sub_object_add(parent, obj);
296 elm_widget_data_set(obj, wd);
297 elm_widget_del_hook_set(obj, _del_hook);
298 elm_widget_theme_hook_set(obj, _theme_hook);
299 elm_widget_changed_hook_set(obj, _changed_hook);
300 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
301 elm_widget_can_focus_set(obj, EINA_TRUE);
303 wd->base = edje_object_add(e);
304 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
305 elm_widget_resize_object_set(obj, wd->base);
306 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
307 _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_visible = 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);
331 * Set the label of editfield
333 * @param obj The editfield object
334 * @param label The label text
339 elm_editfield_label_set(Evas_Object *obj, const char *label)
341 Widget_Data *wd = elm_widget_data_get(obj);
342 ELM_CHECK_WIDTYPE(obj, widtype);
343 if (!wd || !wd->base)
346 eina_stringshare_del(wd->label);
348 wd->label = eina_stringshare_add(label);
349 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
350 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
354 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
355 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
357 edje_object_message_signal_process(wd->base);
358 edje_object_part_text_set(wd->base, "elm.text", label);
363 * Get the label used on the editfield object
365 * @param obj The editfield object
371 elm_editfield_label_get(Evas_Object *obj)
373 Widget_Data *wd = elm_widget_data_get(obj);
374 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
375 if (!wd || !wd->base)
381 * Get the label used on the editfield object
383 * @param obj The editfield object
389 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
391 Widget_Data *wd = elm_widget_data_get(obj);
392 ELM_CHECK_WIDTYPE(obj, widtype);
393 if (!wd || !wd->base)
396 eina_stringshare_del(wd->guide_text);
398 wd->guide_text = eina_stringshare_add(text);
399 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
400 wd->show_guide_text = EINA_TRUE;
403 wd->guide_text = NULL;
407 * Get the guidance text used on the editfield object
409 * @param obj The editfield object
415 elm_editfield_guide_text_get(Evas_Object *obj)
417 Widget_Data *wd = elm_widget_data_get(obj);
418 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
419 if (!wd || !wd->base)
421 return wd->guide_text;
425 * Get the entry of the editfield object
427 * @param obj The editfield object
428 * @return entry object
434 elm_editfield_entry_get(Evas_Object *obj)
436 Widget_Data *wd = elm_widget_data_get(obj);
437 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
444 * Set the left side icon.
446 * @param obj The editfield object
447 * @param icon The icon object
448 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
453 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
455 Widget_Data *wd = elm_widget_data_get(obj);
456 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
457 if (!wd || !wd->base)
459 if ((wd->licon != icon) && (wd->licon))
460 elm_widget_sub_object_del(obj, wd->licon);
463 if (!(edje_object_part_swallow(wd->base, "left_icon", icon)))
466 elm_widget_sub_object_add(obj, icon);
467 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
468 _changed_size_hints, obj);
469 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
470 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
477 * Get the left side icon
479 * @param obj The editfield object
480 * @return icon object
485 elm_editfield_left_icon_get(Evas_Object *obj)
487 Widget_Data *wd = elm_widget_data_get(obj);
488 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
489 if (!wd || !wd->base || !wd->licon)
495 * Set the right side icon.
497 * @param obj The editfield object
498 * @param icon The icon object
499 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
504 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
506 Widget_Data *wd = elm_widget_data_get(obj);
507 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
508 if (!wd || !wd->base)
510 if ((wd->ricon != icon) && (wd->ricon))
511 elm_widget_sub_object_del(obj, wd->ricon);
514 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
517 elm_widget_sub_object_add(obj, icon);
518 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
519 _changed_size_hints, obj);
520 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
527 * Get the right side icon
529 * @param obj The editfield object
530 * @return icon object
535 elm_editfield_right_icon_get(Evas_Object *obj)
537 Widget_Data *wd = elm_widget_data_get(obj);
538 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
539 if (!wd || !wd->base || !wd->ricon)
545 * Set entry object style as single-line or multi-line.
547 * @param obj The editfield object
548 * @param single_line 1 if single-line , 0 if multi-line
553 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
555 Widget_Data *wd = elm_widget_data_get(obj);
556 ELM_CHECK_WIDTYPE(obj, widtype);
557 if (!wd || !wd->base)
559 wd->single_line = single_line;
560 elm_entry_single_line_set(wd->entry, single_line);
561 if(wd->single_line && wd->eraser_visible)
562 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
564 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");
568 * Set enable user to clean all of text.
570 * @param obj The editfield object
571 * @param visible If true, the eraser is visible and user can clean all of text by using eraser.
572 * If false, the eraser is invisible.
577 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
579 Widget_Data *wd = elm_widget_data_get(obj);
580 ELM_CHECK_WIDTYPE(obj, widtype);
581 if (!wd || !wd->base)
583 wd->eraser_visible = visible;
585 if(wd->single_line && wd->eraser_visible)
586 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
588 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");