bcb3978974710e1adb49849aa50ca167909e627a
[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 Eina_Bool __search_entry_timer_cb(void *data)
27 {
28         SEARCH_FUNC_START;
29         struct appdata *ad = (struct appdata *)data;
30
31         search_set_result_list(ad);
32         ad->search_timer = NULL;
33
34         SEARCH_FUNC_END;
35         return ECORE_CALLBACK_CANCEL;
36 }
37
38 void __search_searchbar_entry_changed_cb(void *data, Evas_Object * obj,
39                                        void *event_info)
40 {
41         SEARCH_FUNC_START;
42
43         struct appdata *ad = (struct appdata *)data;
44         const char *text;
45         text = elm_entry_markup_to_utf8(elm_object_text_get(ad->search_entry));
46
47         SEARCH_DEBUG_LOG("text : %s", text);
48
49         if (elm_object_focus_get(ad->search_bar)) {
50                 if (elm_entry_is_empty(ad->search_entry))
51                         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm");
52                 else
53                         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm");
54         } else {
55                 if (elm_entry_is_empty(ad->search_entry))
56                         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm");
57                 else
58                         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm");
59         }
60
61         if ((text != NULL) && (strlen(text) > 0)
62                     && (SEARCH_STRCMP(text, ad->search_word) == 0)) {
63                         SEARCH_DEBUG_LOG("text is same as prev text");
64         } else {
65                 /* Make timer for check user's input */
66                 search_stop_search(ad);
67
68                 ad->search_timer = ecore_timer_add(0.4, __search_entry_timer_cb, ad);
69         }
70
71         SEARCH_FUNC_END;
72         return;
73 }
74
75
76 static void __search_searchbar_entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
77 {
78         SEARCH_FUNC_START;
79
80         struct appdata *ad = (struct appdata *)data;
81
82         if (!elm_entry_is_empty(ad->search_entry))
83                 elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm");
84
85         elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm");
86         elm_object_signal_emit(ad->search_bar, "cancel,in", "");
87
88         SEARCH_FUNC_END;
89 }
90
91 static void __search_searchbar_entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
92 {
93         SEARCH_FUNC_START;
94
95         struct appdata *ad = (struct appdata *)data;
96
97         if (elm_entry_is_empty(ad->search_entry))
98                 elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm");
99
100         elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm");
101
102         SEARCH_FUNC_END;
103 }
104
105 static void __search_searchbar_bg_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
106 {
107         SEARCH_FUNC_START;
108
109         struct appdata *ad = (struct appdata *)data;
110
111         elm_object_focus_set(ad->search_entry, EINA_TRUE);
112
113         SEARCH_FUNC_END;
114 }
115
116 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.
117 {
118         SEARCH_FUNC_START;
119
120         struct appdata *ad = (struct appdata *)data;
121
122         elm_entry_entry_set(ad->search_entry, "");
123
124         SEARCH_FUNC_END;
125 }
126
127 static void __search_searchbar_key_down_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)
128 {
129         SEARCH_FUNC_START;
130
131         struct appdata *ad = (struct appdata *)data;
132         Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *) event_info;
133
134         if (SEARCH_STRCMP(ev->key, "Return") == 0) {
135                              ecore_imf_context_input_panel_hide
136                             ((Ecore_IMF_Context *)elm_entry_imf_context_get
137                              (ad->search_entry));
138         }
139
140         SEARCH_FUNC_END;
141 }
142
143 static void __search_searchbar_cancel_clicked_cb(void *data, Evas_Object * obj,
144                                                  void *event_info)
145 {
146         SEARCH_FUNC_START;
147
148         struct appdata *ad = (struct appdata *)data;
149
150         const char* text;
151
152         elm_object_focus_set(ad->cate_btn, EINA_TRUE);
153         evas_object_hide(ad->search_cancel_btn);
154         elm_object_signal_emit(ad->search_bar, "cancel,out", "");
155         text = elm_entry_entry_get(ad->search_entry);
156
157         if (text != NULL && strlen(text) > 0)
158                 elm_entry_entry_set(ad->search_entry, NULL);
159
160         search_set_result_list(ad);
161
162         malloc_trim(0);
163
164         SEARCH_FUNC_END;
165 }
166
167 static void __search_searchbar_gl_drag_scroll_start_cb(void *data, Evas_Object * obj, void *event_info)
168 {
169         SEARCH_FUNC_START;
170
171         struct appdata *ad = (struct appdata *)data;
172
173         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
174
175         if (imf_context) {
176                 ecore_imf_context_input_panel_hide(imf_context);
177         }
178
179         SEARCH_FUNC_END;
180 }
181
182
183 static void
184 __search_searchbar_state_event_cb(void *data, Ecore_IMF_Context *imf_context, int value)
185 {
186         SEARCH_FUNC_START;
187
188         struct appdata *ad = (struct appdata *)data;
189
190         switch (value)
191         {
192                 case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
193                         evas_object_smart_callback_add(
194                                         ad->search_gl,
195                                         "scroll,drag,start",
196                                         __search_searchbar_gl_drag_scroll_start_cb,
197                                         data);
198                 break;
199                 case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
200                         /* ISE state has changed to ISE_STATE_HIDE status */
201                         evas_object_smart_callback_del(
202                                         ad->search_gl,
203                                         "scroll,drag,start",
204                                         __search_searchbar_gl_drag_scroll_start_cb);
205                 break;
206         }
207
208         SEARCH_FUNC_END;
209 }
210
211 static void __search_searchbar_create(void *data)
212 {
213         SEARCH_FUNC_START;
214
215         struct appdata *ad = (struct appdata *)data;
216         if (!ad)
217                 return;
218
219         if (ad->search_bar) {
220                 elm_object_signal_callback_del(
221                                                                 ad->search_bar,
222                                                                 "elm,bg,clicked",
223                                                                 "elm",
224                                                                 __search_searchbar_bg_clicked_cb);
225                 elm_object_signal_callback_del(
226                                                                 ad->search_bar,
227                                                                 "elm,eraser,clicked",
228                                                                 "elm",
229                                                                 __search_searchbar_eraser_clicked_cb);
230
231                 evas_object_del(ad->search_bar);
232                 ad->search_bar = NULL;
233         }
234
235         if (ad->search_entry) {
236                 evas_object_smart_callback_del(
237                                                                 ad->search_entry,
238                                                                 "changed",
239                                                                 __search_searchbar_entry_changed_cb);
240                 evas_object_smart_callback_del(
241                                                                 ad->search_entry,
242                                                                 "preedit,changed",
243                                                                 __search_searchbar_entry_changed_cb);
244                 evas_object_smart_callback_del(
245                                                                 ad->search_entry,
246                                                                 "focused",
247                                                                 __search_searchbar_entry_focused_cb);
248                 evas_object_smart_callback_del(
249                                                                 ad->search_entry,
250                                                                 "unfocused",
251                                                                 __search_searchbar_entry_unfocused_cb);
252
253                 evas_object_del(ad->search_entry);
254                 ad->search_entry = NULL;
255         }
256
257         if (ad->search_cancel_btn) {
258                 evas_object_smart_callback_del(
259                                                                 ad->search_cancel_btn,
260                                                                 "clicked",
261                                                __search_searchbar_cancel_clicked_cb);
262                 evas_object_del(ad->search_cancel_btn);
263                 ad->search_cancel_btn = NULL;
264         }
265
266         ad->search_bar = elm_layout_add(ad->navi_bar);
267         elm_layout_theme_set(ad->search_bar , "layout", "searchbar", "cancel_button");
268
269         ad->search_cancel_btn = elm_button_add(ad->search_bar);
270         elm_object_part_content_set(ad->search_bar, "button_cancel", ad->search_cancel_btn);
271         elm_object_style_set(ad->search_cancel_btn, "searchbar/default");
272         elm_object_text_set(ad->search_cancel_btn, dgettext("sys_string", "IDS_COM_SK_CANCEL"));
273
274         ad->search_entry = elm_entry_add(ad->search_bar);
275         elm_entry_scrollable_set(ad->search_entry, EINA_TRUE);
276         elm_entry_single_line_set(ad->search_entry, EINA_TRUE);
277         elm_object_part_content_set(ad->search_bar, "elm.swallow.content", ad->search_entry);
278         elm_object_part_text_set(ad->search_bar, "elm.guidetext", dgettext("sys_string", "IDS_COM_BODY_SEARCH"));
279         elm_entry_cnp_mode_set(ad->search_entry, ELM_CNP_MODE_PLAINTEXT);
280
281         evas_object_size_hint_weight_set(ad->search_bar, EVAS_HINT_EXPAND, 0);
282         evas_object_size_hint_align_set(ad->search_bar, EVAS_HINT_FILL, 0.0);
283
284         elm_entry_input_panel_layout_set(ad->search_entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
285         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
286         ecore_imf_context_input_panel_event_callback_add(imf_context,
287                                                          ECORE_IMF_INPUT_PANEL_STATE_EVENT,
288                                                          __search_searchbar_state_event_cb,
289                                                          data);
290
291         /* Set Searchbar Callback */
292         elm_object_signal_callback_add(
293                                                                 ad->search_bar,
294                                                                 "elm,bg,clicked",
295                                                                 "elm",
296                                                                 __search_searchbar_bg_clicked_cb,
297                                                                 ad);
298         elm_object_signal_callback_add(
299                                                                 ad->search_bar,
300                                                                 "elm,eraser,clicked",
301                                                                 "elm",
302                                                                 __search_searchbar_eraser_clicked_cb,
303                                                                 ad);
304
305         /* Set Search-Entry Callback */
306         evas_object_smart_callback_add(
307                                                                 ad->search_entry,
308                                                                 "changed",
309                                                                 __search_searchbar_entry_changed_cb,
310                                                                 ad);
311         evas_object_smart_callback_add(
312                                                                 ad->search_entry,
313                                                                 "preedit,changed",
314                                                                 __search_searchbar_entry_changed_cb,
315                                                                 ad);
316
317         evas_object_smart_callback_add(
318                                                                 ad->search_entry,
319                                                                 "focused",
320                                                                 __search_searchbar_entry_focused_cb,
321                                                                 ad);
322         evas_object_smart_callback_add(
323                                                                 ad->search_entry,
324                                                                 "unfocused",
325                                                                 __search_searchbar_entry_unfocused_cb,
326                                                                 ad);
327         evas_object_event_callback_add(
328                                                                 ad->search_entry,
329                                                                 EVAS_CALLBACK_KEY_DOWN,
330                                                                 __search_searchbar_key_down_cb,
331                                                         ad);
332
333         /* Set Searchbar Cancel Button Callback */
334         evas_object_smart_callback_add(
335                                                                 ad->search_cancel_btn,
336                                                                 "clicked",
337                                                                 __search_searchbar_cancel_clicked_cb,
338                                                                 ad);
339
340         evas_object_show(ad->search_bar);
341
342         SEARCH_FUNC_END;
343 }
344
345 static Evas_Object *__search_init_noresult_view(void *data)
346 {
347         SEARCH_FUNC_START;
348
349         struct appdata *ad = (struct appdata *)data;
350         Evas_Object *noc;
351
352         noc = elm_layout_add(ad->navi_bar);
353         elm_layout_theme_set(noc, "layout", "nocontents", "search");
354         elm_object_part_text_set(noc, "elm.text", dgettext("sys_string", "IDS_COM_BODY_NO_SEARCH_RESULTS"));
355         elm_object_focus_allow_set(noc, EINA_TRUE);
356
357         SEARCH_FUNC_END;
358
359         return noc;
360 }
361
362 Evas_Object *search_searchbar_category_icon_add(char* img, Evas_Object *parent)
363 {
364         SEARCH_FUNC_START;
365
366         char buf[MAX_LENGTH_PER_PATH] = { 0, };
367         Evas_Object* cate_icon = NULL;
368
369         if( img != NULL ) {
370         cate_icon = elm_icon_add(parent);
371
372         snprintf(buf, sizeof(buf), SEARCH_ICON_PATH "%s", img);
373
374         SEARCH_DEBUG_LOG("buf : %s", buf);
375
376         elm_icon_file_set(cate_icon, buf, NULL);
377
378         evas_object_size_hint_aspect_set(cate_icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
379         elm_icon_resizable_set(cate_icon, EINA_FALSE, EINA_FALSE);
380         }
381
382         SEARCH_FUNC_END;
383
384         return cate_icon;
385 }
386
387 void search_searchbar_cb(void *data, Evas_Object * obj, void *event_info)
388 {
389         SEARCH_FUNC_START;
390
391         struct appdata *ad = (struct appdata *)data;
392
393         Evas_Object *cate_btn;
394         Evas_Object *cate_icon;
395         int category = 0;
396         char *imgpath = NULL;
397
398         /* create layout */
399
400         ad->sb_layout = elm_layout_add(ad->navi_bar);
401         elm_layout_file_set(ad->sb_layout,
402                                                 SEARCH_EDJ,
403                                                 "smartsearch/search_result");
404
405         category = SEARCH_CATE_PHONE;
406
407         imgpath = ad->category_info[ad->search_category].btn_icon_path;
408         cate_icon = search_searchbar_category_icon_add(imgpath, ad->sb_layout);
409
410         cate_btn = elm_button_add(ad->sb_layout);
411         elm_object_content_set(ad->cate_btn, cate_icon);
412
413         evas_object_show(cate_btn);
414         ad->cate_btn = cate_btn;
415
416         elm_object_part_content_set(ad->sb_layout, "searchbar_area_category", cate_btn);
417
418         /* set search bar area */
419         __search_searchbar_create(ad);
420         elm_object_part_content_set(ad->sb_layout, "searchbar_area_entry", ad->search_bar);
421
422         /* set search result area */
423         ad->noresult_view = __search_init_noresult_view(ad);
424
425         elm_object_part_content_set(ad->sb_layout,
426                                                 "list_noresult",
427                                                 ad->noresult_view);
428
429         evas_object_size_hint_weight_set(
430                                                         ad->sb_layout,
431                                                         EVAS_HINT_EXPAND,
432                                                         EVAS_HINT_EXPAND);
433
434         SEARCH_FUNC_END;
435 }