diff options
Diffstat (limited to 'src/search_bar.cpp')
-rwxr-xr-x | src/search_bar.cpp | 572 |
1 files changed, 572 insertions, 0 deletions
diff --git a/src/search_bar.cpp b/src/search_bar.cpp new file mode 100755 index 0000000..a56ed2a --- /dev/null +++ b/src/search_bar.cpp @@ -0,0 +1,572 @@ +/* + * Copyright 2012-2013 Samsung Electronics Co., Ltd/ + * + * Licensed under the Flora License, Version 1.0 (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 <string.h> +#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; +} + + |