[efl-upgrade]
[framework/uifw/elementary.git] / src / lib / elm_searchbar.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4 #include <Elementary.h>
5 #include "elm_priv.h"
6
7 /**
8  * @defgroup Searchbar Searchbar
9  * @ingroup Elementary
10  *
11  * This is Searchbar. 
12  * It can contain a simple entry and button object.
13  */
14
15 typedef struct _Widget_Data Widget_Data;
16
17 struct _Widget_Data
18 {
19    Evas_Object *base, *eb, *cancel_btn;
20    Eina_Bool cancel_btn_ani_flag;
21 };
22
23 static void _del_hook(Evas_Object *obj);
24 static void _theme_hook(Evas_Object *obj);
25 static void _sizing_eval(Evas_Object *obj);
26 static void _clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
27 static void _changed(void *data, Evas_Object *obj, const char *emission, const char *source);
28 static void _cancel_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
29
30 static void _del_hook(Evas_Object *obj)
31 {
32    Widget_Data *wd = elm_widget_data_get(obj);
33
34    if (!wd) return;
35
36    free(wd);
37 }
38
39 static void _theme_hook(Evas_Object *obj)
40 {
41    Widget_Data *wd = elm_widget_data_get(obj);
42    if (!wd) return;
43
44    _elm_theme_object_set(obj, wd->base, "searchbar", "base", elm_widget_style_get(obj));
45
46    if (wd->eb)
47      edje_object_part_swallow(wd->base, "search_textfield", wd->eb);
48    if (wd->cancel_btn)
49      edje_object_part_swallow(wd->base, "button_cancel", wd->cancel_btn);
50
51    edje_object_scale_set(wd->cancel_btn, elm_widget_scale_get(obj) * _elm_config->scale);
52    _sizing_eval(obj);
53 }
54
55 static void _sizing_eval(Evas_Object *obj)
56 {
57    Widget_Data *wd = elm_widget_data_get(obj);
58    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
59
60    if (!wd) return;
61    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
62    edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
63    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
64    evas_object_size_hint_min_set(obj, minw, minh);
65    evas_object_size_hint_max_set(obj, maxw, maxh);
66 }
67
68 static void _clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
69 {
70    Widget_Data *wd = elm_widget_data_get(data);
71    if (!wd) return;
72
73    elm_entry_cursor_end_set(elm_editfield_entry_get(wd->eb));
74    if (wd->cancel_btn_ani_flag == EINA_TRUE)
75      edje_object_signal_emit(wd->base, "CANCELIN", "PROG");
76    else
77      edje_object_signal_emit(wd->base, "CANCELSHOW", "PROG");
78
79    evas_object_smart_callback_call(data, "clicked", NULL);
80 }
81
82 static void _changed(void *data, Evas_Object *obj, const char *emission, const char *source)
83 {
84    Widget_Data *wd = elm_widget_data_get(data);
85
86    if (!wd) return;
87
88    // TODO : inform to use entry changed callback 
89 //   evas_object_smart_callback_call(data, "changed", NULL);
90 }
91
92 static void _cancel_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
93 {
94    Widget_Data *wd = elm_widget_data_get(data);
95    if (!wd) return;
96
97    if (wd->cancel_btn_ani_flag == EINA_TRUE)
98      edje_object_signal_emit(wd->base, "CANCELOUT", "PROG");
99    else
100      edje_object_signal_emit(wd->base, "CANCELHIDE", "PROG");
101
102    const char* text;
103    text = elm_entry_entry_get(elm_editfield_entry_get(wd->eb));
104    if (text != NULL && strlen(text) > 0)
105      elm_entry_entry_set(elm_editfield_entry_get(wd->eb), NULL);
106
107    evas_object_smart_callback_call(data, "cancel,clicked", NULL);
108 }
109
110 static void
111 _searchicon_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
112 {
113    Widget_Data *wd = elm_widget_data_get(data);
114    if (!wd) return;
115
116    if (!strcmp(source, "search_icon"))
117      evas_object_smart_callback_call(data, "searchsymbol,clicked", NULL);
118    else if (!strcmp(source, "base_bg"))
119      _clicked(data, obj, emission, source);
120 }
121
122 /**
123  * Add a new searchbar to the parent
124  * @param parent The parent object
125  * @return The new object or NULL if it cannot be created
126  *
127  * @ingroup Searchbar
128  */
129 EAPI Evas_Object *elm_searchbar_add(Evas_Object *parent)
130 {
131    Evas_Object *obj;
132    Evas *e;
133    Widget_Data *wd;
134
135    wd = ELM_NEW(Widget_Data);
136    e = evas_object_evas_get(parent);
137    if (e == NULL) return NULL;
138    obj = elm_widget_add(e);
139    if (obj == NULL) return NULL;
140    elm_widget_type_set(obj, "searchbar");
141    elm_widget_sub_object_add(parent, obj);
142    elm_widget_data_set(obj, wd);
143    elm_widget_del_hook_set(obj, _del_hook);
144    elm_widget_theme_hook_set(obj, _theme_hook);
145    elm_widget_can_focus_set(obj, 1 );
146
147    wd->base = edje_object_add(e);
148    if (wd->base == NULL) return NULL;
149
150    _elm_theme_object_set(obj, wd->base, "searchbar", "base", "default");
151
152    //   evas_object_size_hint_weight_set(wd->base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
153    //   evas_object_size_hint_align_set(wd->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
154
155    // Add Entry
156    wd->eb = elm_editfield_add(parent);
157    elm_object_style_set(wd->eb, "searchbar");
158    edje_object_part_swallow(wd->base, "search_textfield", wd->eb);
159 //   elm_editfield_guide_text_set(wd->eb, "Search");
160    elm_editfield_entry_single_line_set(wd->eb, EINA_TRUE);
161    elm_editfield_eraser_set(wd->eb, EINA_TRUE);
162    evas_object_smart_callback_add(wd->eb, "clicked", _clicked, obj);
163    evas_object_smart_callback_add(elm_editfield_entry_get(wd->eb), "changed", _changed, obj);
164    edje_object_signal_callback_add(wd->base, "mouse,up,1", "*", _searchicon_clicked, obj);
165
166    elm_widget_sub_object_add(obj, wd->eb);
167
168    // Add Button
169    wd->cancel_btn = elm_button_add(parent);
170    edje_object_part_swallow(wd->base, "button_cancel", wd->cancel_btn);
171    elm_object_style_set(wd->cancel_btn, "custom/darkblue");
172    elm_button_label_set(wd->cancel_btn, "Cancel");
173    evas_object_smart_callback_add(wd->cancel_btn, "clicked", _cancel_clicked, obj);
174    elm_widget_sub_object_add(obj, wd->cancel_btn);
175
176    wd->cancel_btn_ani_flag = EINA_FALSE;
177
178    elm_widget_resize_object_set(obj, wd->base);
179
180    _sizing_eval(obj);
181
182    return obj;
183 }
184
185 /**
186  * set the text of entry
187  *
188  * @param obj The searchbar object
189  * @return void
190  *
191  * @ingroup Searchbar
192  */
193 EAPI void elm_searchbar_text_set(Evas_Object *obj, const char *entry)
194 {
195    Widget_Data *wd = elm_widget_data_get(obj);
196    if (!wd) return NULL;
197
198    elm_entry_entry_set(elm_editfield_entry_get(wd->eb), entry);
199 }
200
201 /**
202  * get the text of entry
203  *
204  * @param obj The searchbar object
205  * @return string pointer of entry
206  *
207  * @ingroup Searchbar
208  */
209 EAPI const char* elm_searchbar_text_get(Evas_Object *obj)
210 {
211    Widget_Data *wd = elm_widget_data_get(obj);
212    if (!wd) return NULL;
213
214    return elm_entry_entry_get(elm_editfield_entry_get(wd->eb));
215 }
216
217 /**
218  * get the pointer of entry
219  *
220  * @param obj The searchbar object
221  * @return the entry object
222  *
223  * @ingroup Searchbar
224  */
225 EAPI Evas_Object *elm_searchbar_entry_get(Evas_Object *obj)
226 {
227    Widget_Data *wd = elm_widget_data_get(obj);
228    if (!wd) return NULL;
229
230    return elm_editfield_entry_get(wd->eb);
231 }
232
233 /**
234  * set the cancel button animation flag
235  *
236  * @param obj The searchbar object
237  * @param cancel_btn_ani_flag The flag of animating cancen button or not
238  * @return void
239  *
240  * @ingroup Searchbar
241  */
242 EAPI void elm_searchbar_cancel_button_animation_set(Evas_Object *obj, Eina_Bool cancel_btn_ani_flag)
243 {
244    Widget_Data *wd = elm_widget_data_get(obj);
245    if (!wd) return;
246
247    if (cancel_btn_ani_flag == EINA_TRUE)
248      wd->cancel_btn_ani_flag = EINA_TRUE;
249    else
250      wd->cancel_btn_ani_flag = EINA_FALSE;
251 }