summaryrefslogtreecommitdiff
path: root/src/search_bar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/search_bar.cpp')
-rwxr-xr-xsrc/search_bar.cpp572
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;
+}
+
+