summaryrefslogtreecommitdiff
path: root/src/scroller.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scroller.c')
-rwxr-xr-xsrc/scroller.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/src/scroller.c b/src/scroller.c
new file mode 100755
index 0000000..fa0bea4
--- /dev/null
+++ b/src/scroller.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <Elementary.h>
+
+#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;
+}