Fix layout issue realte to giant font size
[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         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
125
126         if (imf_context) {
127                 ecore_imf_context_input_panel_show(imf_context);
128         }
129
130         SEARCH_FUNC_END;
131 }
132
133 static void __search_searchbar_key_down_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)
134 {
135         SEARCH_FUNC_START;
136
137         struct appdata *ad = (struct appdata *)data;
138         Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *) event_info;
139
140         if (SEARCH_STRCMP(ev->key, "Return") == 0) {
141                              ecore_imf_context_input_panel_hide
142                             ((Ecore_IMF_Context *)elm_entry_imf_context_get
143                              (ad->search_entry));
144         }
145
146         SEARCH_FUNC_END;
147 }
148
149 static void __search_searchbar_cancel_clicked_cb(void *data, Evas_Object * obj,
150                                                  void *event_info)
151 {
152         SEARCH_FUNC_START;
153
154         struct appdata *ad = (struct appdata *)data;
155
156         const char* text;
157
158         elm_object_focus_set(ad->cate_btn, EINA_TRUE);
159         evas_object_hide(ad->search_cancel_btn);
160         elm_object_signal_emit(ad->search_bar, "cancel,out", "");
161         text = elm_entry_entry_get(ad->search_entry);
162
163         if (text != NULL && strlen(text) > 0)
164                 elm_entry_entry_set(ad->search_entry, NULL);
165
166         search_set_result_list(ad);
167
168         malloc_trim(0);
169
170         SEARCH_FUNC_END;
171 }
172
173 static void __search_searchbar_gl_drag_scroll_start_cb(void *data, Evas_Object * obj, void *event_info)
174 {
175         SEARCH_FUNC_START;
176
177         struct appdata *ad = (struct appdata *)data;
178
179         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
180
181         if (imf_context) {
182                 ecore_imf_context_input_panel_hide(imf_context);
183         }
184
185         SEARCH_FUNC_END;
186 }
187
188
189 static void
190 __search_searchbar_state_event_cb(void *data, Ecore_IMF_Context *imf_context, int value)
191 {
192         SEARCH_FUNC_START;
193
194         struct appdata *ad = (struct appdata *)data;
195
196         switch (value)
197         {
198                 case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
199                         evas_object_smart_callback_add(
200                                         ad->search_gl,
201                                         "scroll,drag,start",
202                                         __search_searchbar_gl_drag_scroll_start_cb,
203                                         data);
204                 break;
205                 case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
206                         /* ISE state has changed to ISE_STATE_HIDE status */
207                         evas_object_smart_callback_del(
208                                         ad->search_gl,
209                                         "scroll,drag,start",
210                                         __search_searchbar_gl_drag_scroll_start_cb);
211                 break;
212         }
213
214         SEARCH_FUNC_END;
215 }
216
217 static void __search_searchbar_create(void *data)
218 {
219         SEARCH_FUNC_START;
220
221         struct appdata *ad = (struct appdata *)data;
222         if (!ad)
223                 return;
224
225         if (ad->search_bar) {
226                 elm_object_signal_callback_del(
227                                                                 ad->search_bar,
228                                                                 "elm,bg,clicked",
229                                                                 "elm",
230                                                                 __search_searchbar_bg_clicked_cb);
231                 elm_object_signal_callback_del(
232                                                                 ad->search_bar,
233                                                                 "elm,eraser,clicked",
234                                                                 "elm",
235                                                                 __search_searchbar_eraser_clicked_cb);
236
237                 evas_object_del(ad->search_bar);
238                 ad->search_bar = NULL;
239         }
240
241         if (ad->search_entry) {
242                 evas_object_smart_callback_del(
243                                                                 ad->search_entry,
244                                                                 "changed",
245                                                                 __search_searchbar_entry_changed_cb);
246                 evas_object_smart_callback_del(
247                                                                 ad->search_entry,
248                                                                 "preedit,changed",
249                                                                 __search_searchbar_entry_changed_cb);
250                 evas_object_smart_callback_del(
251                                                                 ad->search_entry,
252                                                                 "focused",
253                                                                 __search_searchbar_entry_focused_cb);
254                 evas_object_smart_callback_del(
255                                                                 ad->search_entry,
256                                                                 "unfocused",
257                                                                 __search_searchbar_entry_unfocused_cb);
258
259                 evas_object_del(ad->search_entry);
260                 ad->search_entry = NULL;
261         }
262
263         if (ad->search_cancel_btn) {
264                 evas_object_smart_callback_del(
265                                                                 ad->search_cancel_btn,
266                                                                 "clicked",
267                                                __search_searchbar_cancel_clicked_cb);
268                 evas_object_del(ad->search_cancel_btn);
269                 ad->search_cancel_btn = NULL;
270         }
271
272         ad->search_bar = elm_layout_add(ad->navi_bar);
273         elm_layout_theme_set(ad->search_bar , "layout", "searchbar", "cancel_button");
274
275         ad->search_cancel_btn = elm_button_add(ad->search_bar);
276         elm_object_part_content_set(ad->search_bar, "button_cancel", ad->search_cancel_btn);
277         elm_object_style_set(ad->search_cancel_btn, "searchbar/default");
278         elm_object_text_set(ad->search_cancel_btn, dgettext("sys_string", "IDS_COM_SK_CANCEL"));
279
280         ad->search_entry = elm_entry_add(ad->search_bar);
281         elm_entry_scrollable_set(ad->search_entry, EINA_TRUE);
282         elm_entry_single_line_set(ad->search_entry, EINA_TRUE);
283         elm_object_part_content_set(ad->search_bar, "elm.swallow.content", ad->search_entry);
284         elm_object_part_text_set(ad->search_bar, "elm.guidetext", dgettext("sys_string", "IDS_COM_BODY_SEARCH"));
285         elm_entry_cnp_mode_set(ad->search_entry, ELM_CNP_MODE_PLAINTEXT);
286
287         evas_object_size_hint_weight_set(ad->search_bar, EVAS_HINT_EXPAND, 0);
288         evas_object_size_hint_align_set(ad->search_bar, EVAS_HINT_FILL, 0.0);
289
290         elm_entry_input_panel_layout_set(ad->search_entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
291         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry);
292         ecore_imf_context_input_panel_event_callback_add(imf_context,
293                                                          ECORE_IMF_INPUT_PANEL_STATE_EVENT,
294                                                          __search_searchbar_state_event_cb,
295                                                          data);
296
297         /* Set Searchbar Callback */
298         elm_object_signal_callback_add(
299                                                                 ad->search_bar,
300                                                                 "elm,bg,clicked",
301                                                                 "elm",
302                                                                 __search_searchbar_bg_clicked_cb,
303                                                                 ad);
304         elm_object_signal_callback_add(
305                                                                 ad->search_bar,
306                                                                 "elm,eraser,clicked",
307                                                                 "elm",
308                                                                 __search_searchbar_eraser_clicked_cb,
309                                                                 ad);
310
311         /* Set Search-Entry Callback */
312         evas_object_smart_callback_add(
313                                                                 ad->search_entry,
314                                                                 "changed",
315                                                                 __search_searchbar_entry_changed_cb,
316                                                                 ad);
317         evas_object_smart_callback_add(
318                                                                 ad->search_entry,
319                                                                 "preedit,changed",
320                                                                 __search_searchbar_entry_changed_cb,
321                                                                 ad);
322
323         evas_object_smart_callback_add(
324                                                                 ad->search_entry,
325                                                                 "focused",
326                                                                 __search_searchbar_entry_focused_cb,
327                                                                 ad);
328         evas_object_smart_callback_add(
329                                                                 ad->search_entry,
330                                                                 "unfocused",
331                                                                 __search_searchbar_entry_unfocused_cb,
332                                                                 ad);
333         evas_object_event_callback_add(
334                                                                 ad->search_entry,
335                                                                 EVAS_CALLBACK_KEY_DOWN,
336                                                                 __search_searchbar_key_down_cb,
337                                                         ad);
338
339         /* Set Searchbar Cancel Button Callback */
340         evas_object_smart_callback_add(
341                                                                 ad->search_cancel_btn,
342                                                                 "clicked",
343                                                                 __search_searchbar_cancel_clicked_cb,
344                                                                 ad);
345
346         evas_object_show(ad->search_bar);
347
348         SEARCH_FUNC_END;
349 }
350
351 static Evas_Object *__search_init_noresult_view(void *data)
352 {
353         SEARCH_FUNC_START;
354
355         struct appdata *ad = (struct appdata *)data;
356         Evas_Object *noc;
357
358         noc = elm_layout_add(ad->navi_bar);
359         elm_layout_theme_set(noc, "layout", "nocontents", "search");
360         elm_object_part_text_set(noc, "elm.text", dgettext("sys_string", "IDS_COM_BODY_NO_SEARCH_RESULTS"));
361         elm_object_focus_allow_set(noc, EINA_TRUE);
362
363         SEARCH_FUNC_END;
364
365         return noc;
366 }
367
368 Evas_Object *search_searchbar_category_icon_add(char* img, Evas_Object *parent)
369 {
370         SEARCH_FUNC_START;
371
372         char buf[MAX_LENGTH_PER_PATH] = { 0, };
373         Evas_Object* cate_icon = NULL;
374
375         if( img != NULL ) {
376         cate_icon = elm_icon_add(parent);
377
378         snprintf(buf, sizeof(buf), SEARCH_ICON_PATH "%s", img);
379
380         SEARCH_DEBUG_LOG("buf : %s", buf);
381
382         elm_icon_file_set(cate_icon, buf, NULL);
383
384         evas_object_size_hint_aspect_set(cate_icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
385         elm_icon_resizable_set(cate_icon, EINA_FALSE, EINA_FALSE);
386         }
387
388         SEARCH_FUNC_END;
389
390         return cate_icon;
391 }
392
393 void search_searchbar_cb(void *data, Evas_Object * obj, void *event_info)
394 {
395         SEARCH_FUNC_START;
396
397         struct appdata *ad = (struct appdata *)data;
398
399         Evas_Object *cate_btn;
400         Evas_Object *cate_icon;
401         int category = 0;
402         char *imgpath = NULL;
403
404         /* create layout */
405         ad->sb_layout = elm_layout_add(ad->navi_bar);
406         elm_layout_file_set(ad->sb_layout,
407                                                 SEARCH_EDJ,
408                                                 "smartsearch/search_result");
409
410                 category = SEARCH_CATE_PHONE;
411
412         imgpath = ad->category_info[ad->search_category].btn_icon_path;
413         cate_icon = search_searchbar_category_icon_add(imgpath, ad->sb_layout);
414         cate_btn = elm_button_add(ad->sb_layout);
415         elm_object_content_set(ad->cate_btn, cate_icon);
416
417         evas_object_show(cate_btn);
418         ad->cate_btn = cate_btn;
419
420         elm_object_part_content_set(ad->sb_layout, "searchbar_area_category", cate_btn);
421
422         /* set search bar area */
423
424         __search_searchbar_create(ad);
425
426         elm_object_part_content_set(ad->sb_layout, "searchbar_area_entry", ad->search_bar);
427
428         /* set search result area */
429
430         ad->noresult_view = __search_init_noresult_view(ad);
431
432         elm_object_part_content_set(ad->sb_layout,
433                                                 "list_noresult",
434                                                 ad->noresult_view);
435
436         evas_object_size_hint_weight_set(
437                                                         ad->sb_layout,
438                                                         EVAS_HINT_EXPAND,
439                                                         EVAS_HINT_EXPAND);
440
441         SEARCH_FUNC_END;
442 }