/* * Copyright 2016 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 "share_panel.h" #include "share_panel_internal.h" #include "conf.h" #include "grid.h" #include "log.h" #include "page.h" #include "scroller.h" #define PRIVATE_SCROLLER_IS_SCROLLING "p_is_sc" #define PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST "pdkec" struct _event_cb { int event_type; void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data); void *user_data; }; typedef struct _event_cb event_cb_s; static void __anim_start_cb(void *data, Evas_Object *scroller, void *event_info) { _D("start the scroller(%p) animation", scroller); evas_object_data_set(scroller, PRIVATE_SCROLLER_IS_SCROLLING, (void *)1); } static void __anim_stop_cb(void *data, Evas_Object *scroller, void *event_info) { _D("stop the scroller(%p) animation", scroller); evas_object_data_del(scroller, PRIVATE_SCROLLER_IS_SCROLLING); } static void __drag_start_cb(void *data, Evas_Object *scroller, void *event_info) { _D("start to drag the scroller(%p)", scroller); } static void __drag_stop_cb(void *data, Evas_Object *scroller, void *event_info) { _D("stop to drag the scroller(%p) animation", scroller); } static void __scroll_cb(void *data, Evas_Object *scroller, void *event_info) { share_panel_h share_panel = data; Eina_List *event_cb_list = NULL; const Eina_List *l = NULL; const Eina_List *ln = NULL; event_cb_s *event_cb_info = NULL; ret_if(!share_panel); ret_if(!scroller); event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST); ret_if(!event_cb_list); EINA_LIST_FOREACH_SAFE(event_cb_list, l, ln, event_cb_info) { if (SCROLLER_EVENT_TYPE_SCROLL == event_cb_info->event_type) { if (event_cb_info->event_cb) { event_cb_info->event_cb(scroller, SCROLLER_EVENT_TYPE_SCROLL, NULL, event_cb_info->user_data); } } } } Evas_Object *_scroller_create(Evas_Object *ui_manager, share_panel_h share_panel) { Evas_Object *box = NULL; Evas_Object *scroller = NULL; retv_if(!ui_manager, NULL); retv_if(!share_panel, NULL); scroller = elm_scroller_add(ui_manager); retv_if(!scroller, NULL); elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_FALSE); elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); elm_scroller_page_scroll_limit_set(scroller, 1, 1); elm_scroller_content_min_limit(scroller, EINA_FALSE, EINA_TRUE); elm_scroller_single_direction_set(scroller, ELM_SCROLLER_SINGLE_DIRECTION_HARD); elm_scroller_page_size_set(scroller, share_panel->page_width, -1); elm_object_style_set(scroller, "effect"); evas_object_show(scroller); elm_object_scroll_lock_y_set(scroller, EINA_TRUE); evas_object_smart_callback_add(scroller, "scroll,anim,start", __anim_start_cb, NULL); evas_object_smart_callback_add(scroller, "scroll,anim,stop", __anim_stop_cb, NULL); evas_object_smart_callback_add(scroller, "scroll,drag,start", __drag_start_cb, NULL); evas_object_smart_callback_add(scroller, "scroll,drag,stop", __drag_stop_cb, share_panel); evas_object_smart_callback_add(scroller, "scroll", __scroll_cb, share_panel); box = elm_box_add(scroller); goto_if(!box, ERROR); elm_box_horizontal_set(box, EINA_TRUE); elm_box_align_set(box, 0.5, 0.5); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(box); elm_object_content_set(scroller, box); return scroller; ERROR: if (scroller) { evas_object_del(scroller); } return NULL; } void _scroller_destroy(Evas_Object *scroller) { Evas_Object *box = NULL; Eina_List *list = NULL; ret_if(!scroller); box = elm_object_content_unset(scroller); if (box) { list = elm_box_children_get(box); if (list) { _scroller_remove_list(scroller, list); eina_list_free(list); } evas_object_del(box); } evas_object_del(scroller); } void _scroller_append_page(Evas_Object *scroller, Evas_Object *page) { Evas_Object *box = NULL; Eina_List *event_cb_list = NULL; const Eina_List *l = NULL; const Eina_List *ln = NULL; event_cb_s *event_cb_info = NULL; box = elm_object_content_get(scroller); ret_if(!box); elm_box_pack_end(box, page); event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST); ret_if(!event_cb_list); EINA_LIST_FOREACH_SAFE(event_cb_list, l, ln, event_cb_info) { if (SCROLLER_EVENT_TYPE_APPEND_PAGE == event_cb_info->event_type) { if (event_cb_info->event_cb) { event_cb_info->event_cb(scroller, SCROLLER_EVENT_TYPE_APPEND_PAGE, NULL, event_cb_info->user_data); } } } } void _scroller_append_list(Evas_Object *scroller, Eina_List *list, int page_width, int page_height) { Evas_Object *page = NULL; Evas_Object *grid = NULL; int count = 0; int i; ret_if(!scroller); ret_if(!list); /* We'll implement this part */ count = eina_list_count(list); if (!count) { _D("no apps"); return; } _D("list count is %d", count); for (i = 0; i < count; i++) { Evas_Object *item = NULL; if (i % 8 == 0) { page = _page_create(scroller, page_width, page_height); ret_if(!page); _scroller_append_page(scroller, page); grid = _grid_create(page); ret_if(!grid); elm_object_part_content_set(page, "grid", grid); } item = _grid_append_item(grid, eina_list_nth(list, i)); ret_if(!item); } } void _scroller_remove_list(Evas_Object *scroller, Eina_List *list) { Evas_Object *page = NULL; Evas_Object *grid = NULL; const Eina_List *l, *ln; ret_if(!scroller); ret_if(!list); EINA_LIST_FOREACH_SAFE(list, l, ln, page) { grid = elm_object_part_content_unset(page, "grid"); continue_if(!grid); _grid_destroy(grid); _page_destroy(page); } } int _scroller_get_region_index(Evas_Object *scroller) { int index = 0; int x = 0; int page_w = 0; retv_if(!scroller, 0); elm_scroller_region_get(scroller, &x, NULL, NULL, NULL); elm_scroller_page_size_get(scroller, &page_w, NULL); index = x / page_w; x = x % page_w; if (x > (page_w / 2)) { index++; } return index; } unsigned int _scroller_count(Evas_Object *scroller) { Evas_Object *box = NULL; Eina_List *list = NULL; int count = 0; retv_if(!scroller, 0); box = elm_object_content_get(scroller); retv_if(!box, 0); list = elm_box_children_get(box); retv_if(!list, 0); count = eina_list_count(list); eina_list_free(list); return count; } int _scroller_register_event_cb(Evas_Object *scroller, int event_type, void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data), void *user_data) { Eina_List *event_cb_list = NULL; event_cb_s *event_cb_info = NULL; retv_if(!scroller, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(event_type <= SCROLLER_EVENT_TYPE_INVALID, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(event_type >= SCROLLER_EVENT_TYPE_MAX, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(!event_cb, SHARE_PANEL_ERROR_INVALID_PARAMETER); event_cb_info = calloc(1, sizeof(event_cb_s)); retv_if(!event_cb_info, SHARE_PANEL_ERROR_OUT_OF_MEMORY); event_cb_info->event_type = event_type; event_cb_info->event_cb = event_cb; event_cb_info->user_data = user_data; event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST); event_cb_list = eina_list_append(event_cb_list, event_cb_info); evas_object_data_set(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST, event_cb_list); return SHARE_PANEL_ERROR_NONE; } int _scroller_unregister_event_cb(Evas_Object *scroller, int event_type, void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data)) { Eina_List *event_cb_list = NULL; const Eina_List *l = NULL; const Eina_List *ln = NULL; event_cb_s *event_cb_info = NULL; retv_if(!scroller, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(event_type <= SCROLLER_EVENT_TYPE_INVALID, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(event_type >= SCROLLER_EVENT_TYPE_MAX, SHARE_PANEL_ERROR_INVALID_PARAMETER); retv_if(!event_cb, SHARE_PANEL_ERROR_INVALID_PARAMETER); event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST); retv_if(!event_cb_list, SHARE_PANEL_ERROR_NOT_INITIALIZED); EINA_LIST_FOREACH_SAFE(event_cb_list, l, ln, event_cb_info) { if (event_cb_info->event_type == event_type && event_cb_info->event_cb == event_cb) { event_cb_list = eina_list_remove(event_cb_list, event_cb_info); break; } } evas_object_data_set(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST, event_cb_list); return SHARE_PANEL_ERROR_NONE; }