2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
4 #include <Elementary.h>
8 * @defgroup Editfield Editfield
11 * This is a editfield. It can contain a simple label and icon objects.
14 #define ERASER_PADDING (10)
16 typedef struct _Widget_Data Widget_Data;
26 const char *guide_text;
27 Eina_Bool needs_size_calc:1;
28 Eina_Bool show_guide_text:1;
30 Eina_Bool single_line : 1;
31 Eina_Bool eraser_visible : 1;
32 Evas_Event_Mouse_Down down_ev;
35 static const char *widtype = NULL;
36 static void _del_hook(Evas_Object *obj);
37 static void _theme_hook(Evas_Object *obj);
38 static void _sizing_eval(Evas_Object *obj);
39 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
40 static void _on_focus_hook(void *data, Evas_Object *obj);
41 static Eina_Bool _empty_entry(Evas_Object *entry);
42 static void _eraser_drag_end(void *data, Evas_Object *obj, const char *emission, const char *source);
43 static void _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
44 static void _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
45 static void _eraser_init(Evas_Object *obj);
48 _del_hook(Evas_Object *obj)
50 Widget_Data *wd = elm_widget_data_get(obj);
52 if (wd->label) eina_stringshare_del(wd->label);
57 _on_focus_hook(void *data, Evas_Object *obj)
59 Widget_Data *wd = elm_widget_data_get(obj);
62 if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)) )
64 wd->editing = EINA_FALSE;
65 edje_object_signal_emit(wd->base, "elm,state,text,fix", "elm");
67 edje_object_signal_emit(wd->base, "elm,action,unfocus", "elm");
68 edje_object_signal_emit(wd->base, "elm,state,over,show", "elm");
69 text = elm_entry_entry_get(wd->entry);
70 edje_object_part_text_set(wd->base, "elm.content.no.edit", text);
71 edje_object_signal_emit(wd->base, "elm,action,no,edit", "elm");
73 if(_empty_entry(wd->entry))
77 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
78 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
79 wd->show_guide_text = EINA_TRUE;
86 _theme_hook(Evas_Object *obj)
88 Widget_Data *wd = elm_widget_data_get(obj);
91 _elm_theme_object_set(obj, wd->base, "editfield", "base", elm_widget_style_get(obj));
92 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
94 edje_object_signal_emit(wd->base, "elm,state,text,fix", "elm");
95 if(wd->show_guide_text)
97 if(_empty_entry(wd->entry))
101 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
102 edje_object_signal_emit(wd->base, "elm,state,guidetext,visible", "elm");
107 edje_object_part_swallow(wd->base, "right_icon", wd->ricon);
109 edje_object_part_swallow(wd->base, "left_icon", wd->licon);
111 // edje_object_part_swallow(wd->base, "eraser", wd->eraser);
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, Evas_Object *obj, void *event_info)
152 evas_object_size_hint_weight_get(data, &weight_x, NULL);
153 if (weight_x == EVAS_HINT_EXPAND)
154 _request_sizing_eval(data);
158 _empty_entry(Evas_Object *entry)
164 text = elm_scrolled_entry_entry_get(entry);
165 if(!text) return EINA_FALSE;
166 strip_text = elm_entry_markup_to_utf8(text);
168 len = strlen(strip_text);
178 _entry_changed_cb(void *data, Evas_Object *obj, void* event_info)
181 Evas_Object *ef_obj = (Evas_Object *)data;
182 Widget_Data *wd = elm_widget_data_get(ef_obj);
184 if(!wd || !wd->base) return;
186 if(!_empty_entry(wd->entry))
188 // text = elm_entry_entry_get(wd->entry);
189 // edje_object_part_text_set(wd->base, "elm.content.no.edit", text);
192 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
193 wd->show_guide_text = EINA_FALSE;
199 _signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
201 Widget_Data *wd = elm_widget_data_get(data);
202 if(!wd || !wd->base) return;
204 if(strcmp(source, "left_icon") && strcmp(source, "right_icon")) // && strcmp(source, "over_change_bg"))
206 edje_object_signal_emit(wd->base, "elm,state,text,edit", "elm");
207 // edje_object_signal_emit(wd->base, "elm,action,focus", "elm");
208 // edje_object_signal_emit(wd->base, "elm,state,over,hide", "elm");
209 // edje_object_signal_emit(wd->base, "elm,action,edit", "elm");
210 elm_widget_focus_set(wd->entry, EINA_TRUE);
211 elm_scrolled_entry_cursor_end_set(wd->entry);
213 if(!_empty_entry(wd->entry))
217 edje_object_signal_emit(wd->base, "elm,state,guidetext,hidden", "elm");
218 wd->show_guide_text = EINA_FALSE;
221 evas_object_smart_callback_call(data, "clicked", NULL);
222 wd->editing = EINA_TRUE;
228 _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
230 Widget_Data *wd = elm_widget_data_get(data);
232 if (!wd || !wd->base) return;
233 evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
234 evas_object_geometry_get(wd->eraser, NULL, NULL, &w, NULL);
235 evas_object_size_hint_min_set(wd->eraser, w, h - ERASER_PADDING);
236 evas_object_resize(wd->eraser, w, h - ERASER_PADDING);
240 _eraser_drag_end(void *data, Evas_Object *obj, const char *emission, const char *source)
242 Widget_Data *wd = elm_widget_data_get(data);
243 if (!wd || !wd->base || !wd->entry)
245 elm_scrolled_entry_entry_set(wd->entry, "");
246 edje_object_part_text_set(wd->base, "elm.content.no.edit", "");
250 _eraser_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
252 Widget_Data *wd = elm_widget_data_get(data);
253 if (!wd || !wd->base)
255 memcpy(&wd->down_ev, event_info, sizeof(Evas_Event_Mouse_Down));
259 _eraser_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
261 Widget_Data *wd = elm_widget_data_get(data);
262 Evas_Event_Mouse_Up *ev = event_info;
266 if (!wd || !wd->base)
268 edje_object_part_drag_value_get(wd->base, "eraser", &pos, NULL);
271 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
274 dur = ev->timestamp - wd->down_ev.timestamp;
275 distance = wd->down_ev.canvas.x - ev->canvas.x;
276 if ((dur && dur > 1000) || (distance < 10 && distance > -10))
278 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
281 if(((float)distance / dur) > 0.5)
282 edje_object_signal_emit(wd->base, "elm,state,eraser,flick", "elm");
284 edje_object_signal_emit(wd->base, "elm,state,eraser,drag", "elm");
288 _eraser_init(Evas_Object *obj)
290 Widget_Data *wd = elm_widget_data_get(obj);
291 if (!wd || !wd->base)
293 wd->eraser = edje_object_add(evas_object_evas_get(obj));
294 elm_widget_sub_object_add(obj, wd->eraser);
295 _elm_theme_object_set(obj, wd->eraser, "editfield/eraser", "base", "default");
296 edje_object_part_swallow(wd->base, "eraser", wd->eraser);
297 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_DOWN, _eraser_mouse_down, obj);
298 evas_object_event_callback_add(wd->eraser, EVAS_CALLBACK_MOUSE_UP, _eraser_mouse_up, obj);
299 edje_object_signal_callback_add(wd->base, "drag", "end", _eraser_drag_end, obj);
303 * Add a new editfield object
305 * @param parent The parent object
306 * @return The new object or NULL if it cannot be created
311 elm_editfield_add(Evas_Object *parent)
317 wd = ELM_NEW(Widget_Data);
318 e = evas_object_evas_get(parent);
321 obj = elm_widget_add(e);
322 ELM_SET_WIDTYPE(widtype, "editfield");
323 elm_widget_type_set(obj, "editfield");
324 elm_widget_sub_object_add(parent, obj);
325 elm_widget_data_set(obj, wd);
326 elm_widget_del_hook_set(obj, _del_hook);
327 elm_widget_theme_hook_set(obj, _theme_hook);
328 elm_widget_changed_hook_set(obj, _changed_hook);
329 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
330 elm_widget_can_focus_set(obj, EINA_TRUE);
332 wd->base = edje_object_add(e);
333 _elm_theme_object_set(obj, wd->base, "editfield", "base", "default");
334 elm_widget_resize_object_set(obj, wd->base);
335 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*",
336 _signal_mouse_clicked, obj);
337 evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
339 wd->show_guide_text = EINA_FALSE;
340 wd->single_line = EINA_TRUE;
341 // wd->editing = EINA_FALSE;
342 // wd->eraser_visible = EINA_FALSE;
344 wd->entry = elm_scrolled_entry_add(obj);
345 elm_scrolled_entry_single_line_set(wd->entry, EINA_TRUE);
346 elm_object_style_set(wd->entry, "editfield");
347 evas_object_size_hint_weight_set(wd->entry, 0, EVAS_HINT_EXPAND);
348 evas_object_size_hint_align_set(wd->entry, 0, EVAS_HINT_FILL);
349 evas_object_event_callback_add(wd->entry,
350 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
351 _changed_size_hints, obj);
352 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->entry);
353 evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);
354 elm_widget_sub_object_add(obj, wd->entry);
362 * Set the label of editfield
364 * @param obj The editfield object
365 * @param label The label text
370 elm_editfield_label_set(Evas_Object *obj, const char *label)
372 Widget_Data *wd = elm_widget_data_get(obj);
373 ELM_CHECK_WIDTYPE(obj, widtype);
374 if (!wd || !wd->base)
377 eina_stringshare_del(wd->label);
380 wd->label = eina_stringshare_add(label);
381 edje_object_signal_emit(wd->base, "elm,state,text,visible", "elm");
382 edje_object_signal_emit(wd->base, "elm,state,left,icon,hide", "elm");
387 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
388 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
390 edje_object_message_signal_process(wd->base);
391 edje_object_part_text_set(wd->base, "elm.text", label);
396 * Get the label used on the editfield object
398 * @param obj The editfield object
404 elm_editfield_label_get(Evas_Object *obj)
406 Widget_Data *wd = elm_widget_data_get(obj);
407 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
408 if (!wd || !wd->base)
414 * Get the label used on the editfield object
416 * @param obj The editfield object
422 elm_editfield_guide_text_set(Evas_Object *obj, const char *text)
424 Widget_Data *wd = elm_widget_data_get(obj);
425 ELM_CHECK_WIDTYPE(obj, widtype);
426 if (!wd || !wd->base)
429 eina_stringshare_del(wd->guide_text);
432 wd->guide_text = eina_stringshare_add(text);
433 edje_object_part_text_set(wd->base, "elm.guidetext", wd->guide_text);
434 wd->show_guide_text = EINA_TRUE;
437 wd->guide_text = NULL;
441 * Get the guidance text used on the editfield object
443 * @param obj The editfield object
449 elm_editfield_guide_text_get(Evas_Object *obj)
451 Widget_Data *wd = elm_widget_data_get(obj);
452 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
453 if (!wd || !wd->base)
455 return wd->guide_text;
459 * Get the entry of the editfield object
461 * @param obj The editfield object
462 * @return entry object
468 elm_editfield_entry_get(Evas_Object *obj)
470 Widget_Data *wd = elm_widget_data_get(obj);
471 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
478 * Set the left side icon.
480 * @param obj The editfield object
481 * @param icon The icon object
482 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
487 elm_editfield_left_icon_set(Evas_Object *obj, Evas_Object *icon)
489 Widget_Data *wd = elm_widget_data_get(obj);
490 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
491 if (!wd || !wd->base)
493 if ((wd->licon != icon) && (wd->licon))
494 elm_widget_sub_object_del(obj, wd->licon);
497 if (!(edje_object_part_swallow(wd->base, "left_icon", icon)))
500 elm_widget_sub_object_add(obj, icon);
501 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
502 _changed_size_hints, obj);
503 edje_object_signal_emit(wd->base, "elm,state,left,icon,show", "elm");
504 edje_object_signal_emit(wd->base, "elm,state,text,hidden", "elm");
511 * Get the left side icon
513 * @param obj The editfield object
514 * @return icon object
519 elm_editfield_left_icon_get(Evas_Object *obj)
521 Widget_Data *wd = elm_widget_data_get(obj);
522 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
523 if (!wd || !wd->base || !wd->licon)
529 * Set the right side icon.
531 * @param obj The editfield object
532 * @param icon The icon object
533 * @return 1 if setting is done, 0 if there is no swallow part for the icon.
538 elm_editfield_right_icon_set(Evas_Object *obj, Evas_Object *icon)
540 Widget_Data *wd = elm_widget_data_get(obj);
541 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
542 if (!wd || !wd->base)
544 if ((wd->ricon != icon) && (wd->ricon))
545 elm_widget_sub_object_del(obj, wd->ricon);
548 if ( !(edje_object_part_swallow(wd->base, "right_icon", icon)) )
551 elm_widget_sub_object_add(obj, icon);
552 evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
553 _changed_size_hints, obj);
554 edje_object_signal_emit(wd->base, "elm,state,right,icon,show", "elm");
561 * Get the right side icon
563 * @param obj The editfield object
564 * @return icon object
569 elm_editfield_right_icon_get(Evas_Object *obj)
571 Widget_Data *wd = elm_widget_data_get(obj);
572 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
573 if (!wd || !wd->base || !wd->ricon)
579 * Set entry object style as single-line or multi-line.
581 * @param obj The editfield object
582 * @param single_line 1 if single-line , 0 if multi-line
587 elm_editfield_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
589 Widget_Data *wd = elm_widget_data_get(obj);
590 ELM_CHECK_WIDTYPE(obj, widtype);
591 if (!wd || !wd->base)
593 wd->single_line = single_line;
594 elm_scrolled_entry_single_line_set(wd->entry, single_line);
595 /* if(wd->single_line && wd->eraser_visible)
596 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
598 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");
603 * Set enable user to clean all of text.
605 * @param obj The editfield object
606 * @param visible If true, the eraser is visible and user can clean all of text by using eraser.
607 * If false, the eraser is invisible.
612 elm_editfield_eraser_set(Evas_Object *obj, Eina_Bool visible)
614 Widget_Data *wd = elm_widget_data_get(obj);
615 ELM_CHECK_WIDTYPE(obj, widtype);
616 if (!wd || !wd->base)
618 wd->eraser_visible = visible;
620 if(wd->single_line && wd->eraser_visible)
621 edje_object_signal_emit(wd->base, "elm,state,eraser,show", "elm");
623 edje_object_signal_emit(wd->base, "elm,state,eraser,hide", "elm");