/* * Copyright 2012-2013 Samsung Electronics Co., Ltd/ * * Licensed under the Flora License, Version 1.1 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://floralicense.org/license/ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "smartsearch.h" #include "Elementary.h" Eina_Bool __search_entry_timer_cb(void *data) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RETV_IF(ad == NULL, ECORE_CALLBACK_CANCEL); search_set_result_list(ad); ad->search_timer = NULL; SEARCH_FUNC_END; return ECORE_CALLBACK_CANCEL; } void __search_searchbar_entry_changed_cb(void *data, Evas_Object * obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); if (elm_object_focus_get(ad->search_bar)) { if (elm_entry_is_empty(ad->search_entry)) { elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm"); } else { elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm"); } } else { if (elm_entry_is_empty(ad->search_entry)) { elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm"); } else { elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm"); } } /* Make timer for check user's input */ search_stop_search(ad); ad->search_timer = ecore_timer_add(0.4, __search_entry_timer_cb, ad); SEARCH_FUNC_END; return; } static void __search_searchbar_entry_focused_cb(void *data, Evas_Object *obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); if (!elm_entry_is_empty(ad->search_entry)) { elm_object_signal_emit(ad->search_bar, "elm,state,eraser,show", "elm"); } elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,hide", "elm"); elm_object_signal_emit(ad->search_bar, "cancel,in", ""); SEARCH_FUNC_END; } static void __search_searchbar_entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); if (elm_entry_is_empty(ad->search_entry)) { elm_object_signal_emit(ad->search_bar, "elm,state,guidetext,show", "elm"); } elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm"); SEARCH_FUNC_END; } static void __search_searchbar_bg_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); elm_object_focus_set(ad->search_entry, EINA_TRUE); SEARCH_FUNC_END; } 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. { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); elm_entry_entry_set(ad->search_entry, ""); Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry); if (imf_context) { ecore_imf_context_input_panel_show(imf_context); } SEARCH_FUNC_END; } static void __search_searchbar_key_down_cb(void *data, Evas * e, Evas_Object * obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *) event_info; SEARCH_RET_IF(ad == NULL); SEARCH_RET_IF(ev == NULL); SEARCH_DEBUG_LOG("ev->key : %s", ev->key); if (SEARCH_STRCMP(ev->key, "Return") == 0) { ecore_imf_context_input_panel_hide ((Ecore_IMF_Context *)elm_entry_imf_context_get (ad->search_entry)); } SEARCH_FUNC_END; } static void __search_searchbar_cancel_clicked_cb(void *data, Evas_Object * obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; const char* text = NULL; SEARCH_RET_IF(ad == NULL); elm_object_focus_set(ad->cate_btn, EINA_TRUE); evas_object_hide(ad->search_cancel_btn); elm_object_signal_emit(ad->search_bar, "cancel,out", ""); text = elm_entry_entry_get(ad->search_entry); if (text != NULL && strlen(text) > 0) elm_entry_entry_set(ad->search_entry, NULL); elm_object_signal_emit(ad->search_bar, "elm,state,eraser,hide", "elm"); search_set_result_list(ad); malloc_trim(0); SEARCH_FUNC_END; } static void __search_searchbar_gl_drag_scroll_start_cb(void *data, Evas_Object * obj, void *event_info) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(ad->search_entry); if (imf_context) { ecore_imf_context_input_panel_hide(imf_context); } SEARCH_FUNC_END; } static void __search_searchbar_state_event_cb(void *data, Ecore_IMF_Context *imf_context, int value) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; switch (value) { case ECORE_IMF_INPUT_PANEL_STATE_SHOW: evas_object_smart_callback_add( ad->search_gl, "scroll,drag,start", __search_searchbar_gl_drag_scroll_start_cb, data); break; case ECORE_IMF_INPUT_PANEL_STATE_HIDE: /* ISE state has changed to ISE_STATE_HIDE status */ evas_object_smart_callback_del( ad->search_gl, "scroll,drag,start", __search_searchbar_gl_drag_scroll_start_cb); break; } SEARCH_FUNC_END; } Evas_Object *__search_init_noresult_view(Evas_Object* parent) { SEARCH_FUNC_START; Evas_Object *noc = NULL; noc = elm_layout_add(parent); elm_layout_theme_set(noc, "layout", "nocontents", "search"); elm_object_part_text_set(noc, "elm.text", dgettext("sys_string", "IDS_COM_BODY_NO_SEARCH_RESULTS")); elm_object_focus_allow_set(noc, EINA_TRUE); SEARCH_FUNC_END; return noc; } Evas_Object *search_category_custom_layout_add(Evas_Object *parent) { SEARCH_FUNC_START; Evas_Object *layout = NULL; layout = elm_layout_add(parent); elm_layout_file_set(layout, SEARCH_EDJ, "smartsearch/custom_image_button"); evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(layout, 0.5, 0.5); evas_object_show(layout); SEARCH_FUNC_END; return layout; } Evas_Object *search_category_image_add(char* imgpath, Evas_Object *parent, int width, int height, bool resize) { SEARCH_FUNC_START; char buf[MAX_LENGTH_PER_PATH] = { 0, }; Evas_Object *image = NULL; image = elm_image_add(parent); elm_image_resizable_set(image,1,1); snprintf(buf, sizeof(buf), SEARCH_ICON_PATH "%s", imgpath); elm_image_file_set(image, buf, NULL); evas_object_show(image); SEARCH_FUNC_END; return image; } Evas_Object *search_searchbar_category_icon_add(char* img, Evas_Object *parent, int width, int height, bool resize) { SEARCH_FUNC_START; char buf[MAX_LENGTH_PER_PATH] = { 0, }; Evas_Object* cate_icon = NULL; double scale = elm_config_scale_get(); if (img != NULL ) { cate_icon = elm_icon_add(parent); snprintf(buf, sizeof(buf), SEARCH_ICON_PATH "%s", img); SEARCH_DEBUG_LOG("buf : %s", buf); elm_image_file_set(cate_icon, buf, NULL); evas_object_size_hint_aspect_set(cate_icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); if (resize != false) { elm_image_resizable_set(cate_icon, EINA_TRUE, EINA_TRUE); } else { elm_image_resizable_set(cate_icon, EINA_FALSE, EINA_FALSE); } evas_object_size_hint_min_set(cate_icon, width * scale, height * scale); evas_object_size_hint_max_set(cate_icon, width * scale, height * scale); } SEARCH_FUNC_END; return cate_icon; } void search_delete_searchbar(void *data) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; if (ad->search_bar) { elm_object_signal_callback_del( ad->search_bar, "elm,bg,clicked", "elm", __search_searchbar_bg_clicked_cb); elm_object_signal_callback_del( ad->search_bar, "elm,eraser,clicked", "elm", __search_searchbar_eraser_clicked_cb); evas_object_del(ad->search_bar); ad->search_bar = NULL; } if (ad->search_entry) { evas_object_smart_callback_del( ad->search_entry, "changed", __search_searchbar_entry_changed_cb); evas_object_smart_callback_del( ad->search_entry, "preedit,changed", __search_searchbar_entry_changed_cb); evas_object_smart_callback_del( ad->search_entry, "focused", __search_searchbar_entry_focused_cb); evas_object_smart_callback_del( ad->search_entry, "unfocused", __search_searchbar_entry_unfocused_cb); evas_object_del(ad->search_entry); ad->search_entry = NULL; } if (ad->search_cancel_btn) { evas_object_smart_callback_del( ad->search_cancel_btn, "clicked", __search_searchbar_cancel_clicked_cb); evas_object_del(ad->search_cancel_btn); ad->search_cancel_btn = NULL; } if (ad->cate_btn) { evas_object_del(ad->cate_btn); ad->cate_btn = NULL; } if (ad->sb_layout) { elm_object_part_content_unset(ad->sb_layout, "list"); evas_object_del(ad->sb_layout); } SEARCH_EVAS_OBJECT_FREE(ad->noresult_view); SEARCH_EVAS_OBJECT_FREE(ad->search_gl); SEARCH_FUNC_END; } void search_create_searchbar_layout(Evas_Object *parent, void *data) { SEARCH_FUNC_START; Evas_Object *genlist = NULL; struct appdata *ad = (struct appdata *)data; SEARCH_RET_IF(ad == NULL); ad->sb_layout = search_create_layout(parent, SEARCH_EDJ, SEARCH_SEARCHBAR_GROUP_NORMAL); SEARCH_RET_IF(ad->sb_layout == NULL); // Category button ad->cate_btn = search_create_category_button(ad->sb_layout, ad); SEARCH_RET_IF(ad->cate_btn == NULL); elm_object_part_content_set(ad->sb_layout, "searchbar_area_category", ad->cate_btn); // Search bar ad->search_bar = search_create_search_bar(ad->sb_layout); SEARCH_RET_IF(ad->search_bar == NULL); elm_object_signal_callback_add(ad->search_bar, "elm,bg,clicked", "elm", __search_searchbar_bg_clicked_cb, ad); elm_object_signal_callback_add(ad->search_bar, "elm,eraser,clicked", "elm", __search_searchbar_eraser_clicked_cb, ad); elm_object_part_content_set(ad->sb_layout, "searchbar_area_entry", ad->search_bar); // Search entry ad->search_entry = search_create_search_entry(ad->sb_layout, ad); SEARCH_RET_IF(ad->search_entry == NULL); elm_object_part_content_set(ad->search_bar, "elm.swallow.content", ad->search_entry); evas_object_smart_callback_add(ad->search_entry, "changed", __search_searchbar_entry_changed_cb, ad); evas_object_smart_callback_add(ad->search_entry, "preedit,changed", __search_searchbar_entry_changed_cb, ad); evas_object_smart_callback_add(ad->search_entry, "focused", __search_searchbar_entry_focused_cb, ad); evas_object_smart_callback_add(ad->search_entry, "unfocused", __search_searchbar_entry_unfocused_cb, ad); evas_object_event_callback_add(ad->search_entry, EVAS_CALLBACK_KEY_DOWN, __search_searchbar_key_down_cb, ad); // Search Cancel button ad->search_cancel_btn = search_create_search_cancel_btn(ad->sb_layout); SEARCH_RET_IF(ad->search_cancel_btn == NULL); evas_object_smart_callback_add(ad->search_cancel_btn, "clicked", __search_searchbar_cancel_clicked_cb,ad); elm_object_part_content_set(ad->search_bar, "button_cancel", ad->search_cancel_btn); // Genlist genlist = elm_genlist_add(ad->sb_layout); // To use multiline textblock/entry/editfield in genlist, set height_for_width mode // then the item's height is calculated while the item's width fits to genlist width. elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS); elm_genlist_tree_effect_enabled_set(genlist, EINA_TRUE); evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL); ad->search_gl = genlist; // Result area ad->noresult_view = __search_init_noresult_view(ad->sb_layout); SEARCH_RET_IF(ad->noresult_view == NULL); elm_object_part_content_set(ad->sb_layout, "list_noresult", ad->noresult_view); SEARCH_FUNC_END; } Evas_Object *search_create_layout(Evas_Object *parent, const char *file, const char *group) { SEARCH_FUNC_START; Evas_Object *layout = NULL; /* create layout */ layout = elm_layout_add(parent); SEARCH_RETV_IF(layout == NULL, NULL); elm_layout_file_set(layout, file, group); SEARCH_FUNC_END; return layout; } Evas_Object *search_create_category_button(Evas_Object *parent, void *data) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; Evas_Object *cate_btn; Evas_Object *cate_icon; int err = 0; char *imgpath = NULL; int category = 0; /* set search category icon area */ category = SEARCH_CATE_PHONE; ad->search_category = category; imgpath = ad->category_info[ad->search_category].btn_icon_path; cate_icon = search_searchbar_category_icon_add(imgpath, parent, SEARCH_CATEGORY_BTN_ICON_SIZE_WIDTH, SEARCH_CATEGORY_BTN_ICON_SIZE_HEIGHT, false); cate_btn = elm_button_add(parent); SEARCH_RETV_IF(cate_btn == NULL, NULL); elm_object_style_set(cate_btn, "circle/empty"); ad->cate_btn = cate_btn; elm_object_content_set(ad->cate_btn, cate_icon); evas_object_show(cate_btn); SEARCH_FUNC_END; return cate_btn; } Evas_Object *search_create_search_bar(Evas_Object *parent) { SEARCH_FUNC_START; Evas_Object *layout = NULL; layout = elm_layout_add(parent); elm_layout_theme_set(layout, "layout", "searchbar", "cancel_button"); elm_object_part_text_set(layout, "elm.guidetext", dgettext("sys_string", "IDS_COM_BODY_SEARCH")); evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(layout); SEARCH_FUNC_END; return layout; } Evas_Object *search_create_search_cancel_btn(Evas_Object *parent) { SEARCH_FUNC_START; Evas_Object *cancel_btn = NULL; cancel_btn = elm_button_add(parent); elm_object_style_set(cancel_btn, "searchbar/default"); elm_object_text_set(cancel_btn, dgettext("sys_string", "IDS_COM_SK_CANCEL")); SEARCH_FUNC_END; return cancel_btn; } Evas_Object *search_create_search_entry(Evas_Object *parent, void *data) { SEARCH_FUNC_START; struct appdata *ad = (struct appdata *)data; Evas_Object *entry = NULL; SEARCH_RETV_IF(ad == NULL, NULL); entry = elm_entry_add(parent); elm_entry_scrollable_set(entry, EINA_TRUE); elm_entry_single_line_set(entry, EINA_TRUE); elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_PLAINTEXT); elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL); elm_entry_prediction_allow_set(entry, EINA_FALSE); elm_entry_autocapital_type_set(entry, ELM_AUTOCAPITAL_TYPE_NONE); elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH); Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(entry); ecore_imf_context_input_panel_event_callback_add(imf_context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, __search_searchbar_state_event_cb, ad); SEARCH_FUNC_END; return entry; }