9403621ab939f5a895c3f92d80dca58a62981414
[apps/home/smartsearch.git] / src / search_bar.cpp
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  * 
4  * Licensed under the Flora License, Version 1.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *     http://www.tizenopensource.org/license
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18
19
20
21
22 #include <string.h>
23 #include "smartsearch.h"
24 #include "Elementary.h"
25
26 static const char* g_search_category_icon[SEARCH_CATE_BTN_IMG_TYPE_MAX] = 
27 {
28         "B10_Phone.png", 
29         "B10_Phone_press.png",
30 };
31
32 void __search_searchbar_entry_changed_cb(void *data, Evas_Object * obj,
33                                        void *event_info)
34 {
35         SEARCH_FUNC_START;
36
37         struct appdata *ad = (struct appdata *)data;
38         const char *text;
39         text = elm_entry_markup_to_utf8(elm_object_text_get(ad->search_entry));
40
41         SEARCH_DEBUG_LOG("text : %s", text);
42
43         if (elm_object_focus_get(ad->search_bar)) {
44                 if (elm_entry_is_empty(ad->search_entry))
45                         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm");
46                 else
47                         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm");
48         } else {
49                 if (elm_entry_is_empty(ad->search_entry)) 
50                         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm");
51                 else
52                         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm");
53         }
54
55         if ((text != NULL) && (strlen(text) > 0)
56                     && (SEARCH_STRCMP(text, ad->search_word) == 0)) {
57                         SEARCH_DEBUG_LOG("text is same as prev text");
58         } else {
59                 if(ad->idler_search)
60                         ecore_idler_del(ad->idler_search);
61                 
62                 ad->idler_search = ecore_idler_add(search_set_result_list, ad);
63         }               
64
65         SEARCH_FUNC_END;
66         return;
67 }
68
69
70 static void __search_searchbar_entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
71 {
72         SEARCH_FUNC_START;
73
74         struct appdata *ad = (struct appdata *)data;
75
76         if (!elm_entry_is_empty(ad->search_entry))
77                 elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm");
78
79         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm");
80         elm_object_signal_emit(ad->search_bar, "cancel,in", "");
81
82         SEARCH_FUNC_END;
83 }
84
85 static void __search_searchbar_entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
86 {
87         SEARCH_FUNC_START;
88
89         struct appdata *ad = (struct appdata *)data;
90
91         if (elm_entry_is_empty(ad->search_entry))
92                 elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm");
93
94         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm");
95
96         SEARCH_FUNC_END;
97 }
98
99 static void __search_searchbar_bg_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
100 {
101         SEARCH_FUNC_START;
102
103         struct appdata *ad = (struct appdata *)data;
104
105         elm_object_focus_set(ad->search_entry, EINA_TRUE);
106
107         SEARCH_FUNC_END;
108 }
109
110 static void __search_searchbar_eraser_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source) // When X marked button is clicked, empty entry's contents.
111 {
112         SEARCH_FUNC_START;
113
114         struct appdata *ad = (struct appdata *)data;
115
116         elm_entry_entry_set(ad->search_entry, "");
117
118         SEARCH_FUNC_END;
119 }
120
121 static void __search_searchbar_key_down_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)
122 {
123         SEARCH_FUNC_START;
124
125         struct appdata *ad = (struct appdata *)data;
126         Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *) event_info;
127
128         if (SEARCH_STRCMP(ev->key, "Return") == 0) {
129                              ecore_imf_context_input_panel_hide
130                             ((Ecore_IMF_Context *)elm_entry_imf_context_get
131                              (ad->search_entry));
132         }
133
134         SEARCH_FUNC_END;
135 }
136
137 static void __search_searchbar_cancel_clicked_cb(void *data, Evas_Object * obj,
138                                                  void *event_info)
139 {
140         SEARCH_FUNC_START;
141
142         struct appdata *ad = (struct appdata *)data;
143
144         const char* text;
145
146         elm_object_focus_set(ad->cate_btn, EINA_TRUE);
147         evas_object_hide(ad->search_cancel_btn);
148         elm_object_signal_emit(ad->search_bar, "cancel,out", "");
149         text = elm_entry_entry_get(ad->search_entry);
150
151         if (text != NULL && strlen(text) > 0)
152                 elm_entry_entry_set(ad->search_entry, NULL);
153
154         search_set_result_list(ad);
155
156         malloc_trim(0);
157
158         SEARCH_FUNC_END;
159 }
160
161 static void __search_searchbar_gl_drag_scroll_start_cb(void *data, Evas_Object * obj, void *event_info)
162 {
163         SEARCH_FUNC_START;
164
165         struct appdata *ad = (struct appdata *)data;
166
167         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
168
169         if (imf_context) {
170                 ecore_imf_context_input_panel_hide(imf_context);
171         }
172
173         SEARCH_FUNC_END;
174 }
175
176
177 static void
178 __search_searchbar_state_event_cb(void *data, Ecore_IMF_Context *imf_context, int value)
179 {
180         SEARCH_FUNC_START;
181
182         struct appdata *ad = (struct appdata *)data;
183
184         switch (value)
185         {
186                 case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
187                         evas_object_smart_callback_add(
188                                         ad->search_gl, 
189                                         "scroll,drag,start", 
190                                         __search_searchbar_gl_drag_scroll_start_cb, 
191                                         data);                          
192                 break;
193                 case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
194                 // ISE state has changed to ISE_STATE_HIDE status
195                         evas_object_smart_callback_del(
196                                         ad->search_gl, 
197                                         "scroll,drag,start", 
198                                         __search_searchbar_gl_drag_scroll_start_cb);
199                 break;
200         }
201
202         SEARCH_FUNC_END;        
203 }
204
205 static void __search_searchbar_create(void *data)
206 {
207         SEARCH_FUNC_START;
208
209         struct appdata *ad = (struct appdata *)data;
210         if (!ad)
211                 return;
212
213         if (ad->search_bar) {
214                 elm_object_signal_callback_del(
215                                                                 ad->search_bar,
216                                                                 "elm,bg,clicked",
217                                                                 "elm",
218                                                                 __search_searchbar_bg_clicked_cb);
219                 elm_object_signal_callback_del(
220                                                                 ad->search_bar,
221                                                                 "elm,eraser,clicked",
222                                                                 "elm",
223                                                                 __search_searchbar_eraser_clicked_cb);
224
225                 evas_object_del(ad->search_bar);
226                 ad->search_bar = NULL;
227         }
228
229         if (ad->search_entry) {
230                 evas_object_smart_callback_del(
231                                                                 ad->search_entry,
232                                                                 "changed",
233                                                                 __search_searchbar_entry_changed_cb);
234                 evas_object_smart_callback_del(
235                                                                 ad->search_entry,
236                                                                 "preedit,changed",
237                                                                 __search_searchbar_entry_changed_cb);
238                 evas_object_smart_callback_del(
239                                                                 ad->search_entry,
240                                                                 "focused",
241                                                                 __search_searchbar_entry_focused_cb);
242                 evas_object_smart_callback_del(
243                                                                 ad->search_entry,
244                                                                 "unfocused",
245                                                                 __search_searchbar_entry_unfocused_cb);
246
247                 evas_object_del(ad->search_entry);
248                 ad->search_entry = NULL;
249         }
250
251         if (ad->search_cancel_btn) {
252                 evas_object_smart_callback_del(
253                                                                 ad->search_cancel_btn,
254                                                                 "clicked",
255                                                __search_searchbar_cancel_clicked_cb);
256                 evas_object_del(ad->search_cancel_btn);
257                 ad->search_cancel_btn = NULL;
258         }
259
260         ad->search_bar = elm_layout_add(ad->navi_bar);
261         elm_layout_theme_set(ad->search_bar , "layout", "searchbar", "cancel_button");
262
263         ad->search_cancel_btn = elm_button_add(ad->search_bar);
264         elm_object_part_content_set(ad->search_bar, "button_cancel", ad->search_cancel_btn);
265         elm_object_style_set(ad->search_cancel_btn, "searchbar/default");
266         elm_object_text_set(ad->search_cancel_btn, dgettext("sys_string", "IDS_COM_SK_CANCEL"));
267         
268         ad->search_entry = elm_entry_add(ad->search_bar);
269         elm_entry_scrollable_set(ad->search_entry, EINA_TRUE);
270         elm_entry_single_line_set(ad->search_entry, EINA_TRUE);
271         elm_object_part_content_set(ad->search_bar, "elm.swallow.content", ad->search_entry);
272         elm_object_part_text_set(ad->search_bar, "elm.guidetext", dgettext("sys_string", "IDS_COM_BODY_SEARCH"));
273         elm_entry_cnp_mode_set(ad->search_entry, ELM_CNP_MODE_PLAINTEXT);
274
275         evas_object_size_hint_weight_set(ad->search_bar, EVAS_HINT_EXPAND, 0);
276         evas_object_size_hint_align_set(ad->search_bar, EVAS_HINT_FILL, 0.0);
277
278         elm_entry_input_panel_layout_set(ad->search_entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
279         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
280         ecore_imf_context_input_panel_event_callback_add(imf_context,
281                                                          ECORE_IMF_INPUT_PANEL_STATE_EVENT,
282                                                          __search_searchbar_state_event_cb,
283                                                          data);
284
285         /* Set Searchbar Callback */
286         elm_object_signal_callback_add(
287                                                                 ad->search_bar,
288                                                                 "elm,bg,clicked",
289                                                                 "elm",
290                                                                 __search_searchbar_bg_clicked_cb,
291                                                                 ad);
292         elm_object_signal_callback_add(
293                                                                 ad->search_bar,
294                                                                 "elm,eraser,clicked",
295                                                                 "elm",
296                                                                 __search_searchbar_eraser_clicked_cb,
297                                                                 ad);
298         
299         /* Set Search-Entry Callback */
300         evas_object_smart_callback_add(
301                                                                 ad->search_entry,
302                                                                 "changed",
303                                                                 __search_searchbar_entry_changed_cb,
304                                                                 ad);
305         evas_object_smart_callback_add(
306                                                                 ad->search_entry,
307                                                                 "preedit,changed",
308                                                                 __search_searchbar_entry_changed_cb,
309                                                                 ad);
310
311         evas_object_smart_callback_add(
312                                                                 ad->search_entry,
313                                                                 "focused",
314                                                                 __search_searchbar_entry_focused_cb,
315                                                                 ad);
316         evas_object_smart_callback_add(
317                                                                 ad->search_entry,
318                                                                 "unfocused",
319                                                                 __search_searchbar_entry_unfocused_cb,
320                                                                 ad);
321         evas_object_event_callback_add(
322                                                                 ad->search_entry,
323                                                                 EVAS_CALLBACK_KEY_DOWN, 
324                                                                 __search_searchbar_key_down_cb,
325                                                         ad);
326
327         /* Set Searchbar Cancel Button Callback */
328         evas_object_smart_callback_add(
329                                                                 ad->search_cancel_btn,
330                                                                 "clicked",
331                                                                 __search_searchbar_cancel_clicked_cb,
332                                                                 ad);
333
334         evas_object_show(ad->search_bar);
335
336         SEARCH_FUNC_END;
337 }
338
339 static Evas_Object *__search_init_noresult_view(void *data)
340 {
341         SEARCH_FUNC_START;
342
343         struct appdata *ad = (struct appdata *)data;
344         Evas_Object *noc;
345
346         noc = elm_layout_add(ad->navi_bar);
347         elm_layout_theme_set(noc, "layout", "nocontents", "search");
348         elm_object_part_text_set(noc, "elm.text", dgettext("sys_string", "IDS_COM_BODY_NO_SEARCH_RESULTS"));
349         elm_object_focus_allow_set(noc, EINA_TRUE);
350
351         SEARCH_FUNC_END;
352
353         return noc;
354 }
355
356 Evas_Object *search_searchbar_category_icon_add(int cate_type, int press_type, Evas_Object *parent)
357 {
358         SEARCH_FUNC_START;
359
360         Evas_Object* cate_icon;
361         char buf[128] = { 0, };
362
363         cate_icon = elm_icon_add(parent);
364         
365         snprintf(buf, sizeof(buf), SEARCH_ICON_PATH "%s", g_search_category_icon[press_type]);
366
367         elm_icon_file_set(cate_icon, buf, NULL);
368
369         evas_object_size_hint_aspect_set(cate_icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
370         elm_icon_resizable_set(cate_icon, EINA_TRUE, EINA_TRUE);
371
372         SEARCH_FUNC_END;
373
374         return cate_icon;
375 }
376
377 void search_searchbar_cb(void *data, Evas_Object * obj, void *event_info)
378 {
379         SEARCH_FUNC_START;
380
381         struct appdata *ad = (struct appdata *)data;
382         
383         Evas_Object *cate_btn;
384         Evas_Object *cate_icon;
385         int category = 0;
386         int err = 0;
387
388         /* create layout */
389
390         ad->sb_layout = elm_layout_add(ad->navi_bar);
391         elm_layout_file_set(ad->sb_layout,
392                                                 SEARCH_EDJ,
393                                                 "smartsearch/search_result");
394
395         category = SEARCH_TYPE_PHONE;
396
397         cate_icon = search_searchbar_category_icon_add(category, 
398                                                                                                         SEARCH_CATE_BTN_IMG_TYPE_UNPRESSED, 
399                                                                                                         ad->sb_layout);
400
401         cate_btn = elm_button_add(ad->sb_layout);
402         elm_object_content_set(ad->cate_btn, cate_icon);
403         
404         evas_object_show(cate_btn);
405         ad->cate_btn = cate_btn;
406
407         elm_object_part_content_set(ad->sb_layout, "searchbar_area_category", cate_btn);
408         
409         /* set search bar area */
410         __search_searchbar_create(ad);
411         elm_object_part_content_set(ad->sb_layout, "searchbar_area_entry", ad->search_bar);
412
413         /* set search result area */
414         ad->noresult_view = __search_init_noresult_view(ad);
415
416         elm_object_part_content_set(ad->sb_layout, 
417                                                 "list_noresult",
418                                                 ad->noresult_view);
419
420         evas_object_size_hint_weight_set(
421                                                         ad->sb_layout, 
422                                                         EVAS_HINT_EXPAND,
423                                                         EVAS_HINT_EXPAND);
424
425         SEARCH_FUNC_END;
426 }