diff options
author | moon87.park <moon87.park@samsung.com> | 2015-12-02 11:51:31 +0900 |
---|---|---|
committer | moon87.park <moon87.park@samsung.com> | 2015-12-02 11:51:54 +0900 |
commit | 1ac14423e2821f7f25cdc01c33da29738c421221 (patch) | |
tree | 3d4f0b0b0a9551bebc10d7195a8f7f8a61bd581c /src | |
parent | 180e260cf4a37bd782735412f84fcf34c3c28f11 (diff) | |
download | share-panel-1ac14423e2821f7f25cdc01c33da29738c421221.tar.gz share-panel-1ac14423e2821f7f25cdc01c33da29738c421221.tar.bz2 share-panel-1ac14423e2821f7f25cdc01c33da29738c421221.zip |
[Share-panel] Initial Version
Change-Id: I4d3ce04e2e136bee39fa8a972c7eb405ab8297f7
Diffstat (limited to 'src')
-rw-r--r-- | src/grid.c | 302 | ||||
-rw-r--r-- | src/index.c | 91 | ||||
-rw-r--r-- | src/list.c | 395 | ||||
-rw-r--r-- | src/page.c | 87 | ||||
-rw-r--r-- | src/scroller.c | 459 | ||||
-rw-r--r-- | src/share_panel.c | 340 | ||||
-rw-r--r-- | src/ui_manager.c | 387 |
7 files changed, 2061 insertions, 0 deletions
diff --git a/src/grid.c b/src/grid.c new file mode 100644 index 0000000..5c8c80e --- /dev/null +++ b/src/grid.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2015 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 <app.h> +#include <app_manager.h> +#include <aul.h> + +#include "share_panel_internal.h" +#include "conf.h" +#include "grid.h" +#include "log.h" + +#define PRIVATE_DATA_KEY_ITEM_INFO "pdkii" + + + +static const char *const FILE_LAYOUT_EDJ = EDJEDIR"/layout.edj"; +static struct { + Elm_Gengrid_Item_Class *gic; + char *default_icon; + + int index; +} grid_info = { + .gic = NULL, + .default_icon = "/usr/share/icons/A01-1_icon_Menu.png", + + .index = 0, +}; + + + +static char *__text_get(void *data, Evas_Object *obj, const char *part) +{ + item_s *info = data; + retv_if(!info, NULL); + + retv_if(!info->name, NULL); + if (!strcmp(part, "elm.text")) { + return strdup(D_(info->name)); + } + + return NULL; +} + + + +#define FILE_ITEM_EDJ EDJEDIR"/item.edj" +static Evas_Object *__add_icon(Evas_Object *parent, const char *file) +{ + const char *real_icon_file = NULL; + Evas_Object *icon = NULL; + Evas_Object *icon_layout = NULL; + + real_icon_file = file; + if (access(real_icon_file, R_OK) != 0) { + _E("Failed to access an icon(%s)", real_icon_file); + real_icon_file = DEFAULT_ICON; + } + + icon = elm_icon_add(parent); + retv_if(!icon, NULL); + + if (elm_image_file_set(icon, real_icon_file, NULL) == EINA_FALSE) { + _E("Icon file is not accessible (%s)", real_icon_file); + evas_object_del(icon); + return NULL; + } + + evas_object_size_hint_min_set(icon, ELM_SCALE_SIZE(ITEM_ICON_WIDTH), ELM_SCALE_SIZE(ITEM_ICON_HEIGHT)); + + elm_image_preload_disabled_set(icon, EINA_TRUE); + elm_image_smooth_set(icon, EINA_TRUE); + elm_image_no_scale_set(icon, EINA_FALSE); + evas_object_show(icon); + + icon_layout = elm_layout_add(parent); + retv_if(!icon_layout, NULL); + + elm_layout_file_set(icon_layout, FILE_ITEM_EDJ, "grid,icon"); + evas_object_size_hint_weight_set(icon_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(icon_layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(icon_layout); + + elm_object_part_content_set(icon_layout, "icon", icon); + + return icon_layout; +} + + + +static Evas_Object *__content_get(void *data, Evas_Object *obj, const char *part) +{ + item_s *info = data; + + retv_if(!info, NULL); + + if (!strcmp(part, "elm.swallow.end")) { + Evas_Object *bg = evas_object_rectangle_add(evas_object_evas_get(obj)); + retv_if(!bg, NULL); + + evas_object_size_hint_min_set(bg, ELM_SCALE_SIZE(ITEM_WIDTH), ELM_SCALE_SIZE(ITEM_HEIGHT)); + evas_object_color_set(bg, 0, 0, 0, 0); + evas_object_show(bg); + return bg; + } else if (!strcmp(part, "elm.swallow.icon")) { + retv_if(!info->icon, NULL); + return __add_icon(obj, info->icon); + } else if (!strcmp(part, "selected")) { + + } + return NULL; +} + + + +static void __del(void *data, Evas_Object *obj) +{ + ret_if(NULL == data); + evas_object_data_del(obj, PRIVATE_DATA_KEY_ITEM_INFO); +} + + + +static void __item_selected(void *data, Evas_Object *obj, void *event_info) +{ + item_s *item_info = data; + Elm_Object_Item *selected_item = NULL; + + int ret = 0; + + ret_if(!item_info); + ret_if(!item_info->appid); + ret_if(!item_info->b); + ret_if(!item_info->share_panel); + _D("item clicked, launch app : %s", item_info->appid); + + selected_item = elm_gengrid_selected_item_get(obj); + ret_if(!selected_item); + elm_gengrid_item_selected_set(selected_item, EINA_FALSE); + + + ret = aul_forward_app(item_info->appid, item_info->b); + if (ret < 0) { + _E("Fail to launch app(%d)", ret); + } + + item_info->share_panel->after_launch = 1; + elm_object_signal_emit(item_info->share_panel->ui_manager, "show", "blocker"); +} + + + +static void __lang_changed_cb(void *data, Evas_Object *grid, void *event_info) +{ + Elm_Object_Item *it = NULL; + int ret = 0; + ret_if(!grid); + + it = elm_gengrid_first_item_get(grid); + while (it) { + app_info_h app_info = NULL; + item_s *item_info = NULL; + char *name = NULL; + + item_info = evas_object_data_get(it, PRIVATE_DATA_KEY_ITEM_INFO); + goto_if(!item_info, next); + + ret = app_info_create(item_info->appid, &app_info); + goto_if(ret != APP_MANAGER_ERROR_NONE && !app_info, next); + + ret = app_info_get_label(app_info, &name); + if (ret == APP_MANAGER_ERROR_NONE && name) { + free(item_info->name); + item_info->name = name; + elm_object_item_part_text_set(it, "elm.text", item_info->name); + elm_gengrid_item_update(it); + } else { + _E("fail to create the app_name from app_info"); + } + + app_info_destroy(app_info); + +next: + it = elm_gengrid_item_next_get(it); + } +} + + + +Evas_Object *_grid_create(Evas_Object *page) +{ + Evas_Object *grid = NULL; + + retv_if(!page, NULL); + + grid = elm_gengrid_add(page); + goto_if(!grid, ERROR); + + evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL); + + elm_gengrid_item_size_set(grid, ELM_SCALE_SIZE(ITEM_WIDTH), ELM_SCALE_SIZE(ITEM_HEIGHT)); + elm_gengrid_align_set(grid, 0.0, 0.0); + elm_gengrid_horizontal_set(grid, EINA_FALSE); + elm_gengrid_multi_select_set(grid, EINA_FALSE); + + grid_info.gic = elm_gengrid_item_class_new(); + goto_if(!grid_info.gic, ERROR); + grid_info.gic->func.text_get = __text_get; + grid_info.gic->func.content_get = __content_get; + grid_info.gic->func.state_get = NULL; + grid_info.gic->func.del = __del; + grid_info.gic->item_style = "type2"; + + evas_object_smart_callback_add(grid, "language,changed", __lang_changed_cb, NULL); + + elm_scroller_movement_block_set(grid, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL); + evas_object_show(grid); + + return grid; + +ERROR: + _grid_destroy(grid); + return NULL; +} + + + +void _grid_destroy(Evas_Object *grid) +{ + ret_if(!grid); + + evas_object_del(grid); +} + + + +Elm_Object_Item *_grid_append_item(Evas_Object *grid, item_s *item_info) +{ + Elm_Object_Item *item = NULL; + + retv_if(!grid, NULL); + retv_if(!item_info, NULL); + + retv_if(!grid_info.gic, NULL); + + item = elm_gengrid_item_append(grid, grid_info.gic, item_info, __item_selected, item_info); + retv_if(!item, NULL); + evas_object_data_set(item, PRIVATE_DATA_KEY_ITEM_INFO, item_info); + if (item_info->name) { + _D("grid append item : %s", item_info->name); + } + item_info->grid_item = item; + elm_gengrid_item_show(item, ELM_GENGRID_ITEM_SCROLLTO_NONE); + elm_gengrid_item_update(item); + + return item; +} + + + +void _grid_remove_item(Evas_Object *grid, item_s *item_info) +{ + Elm_Object_Item *item = NULL; + + ret_if(!grid); + ret_if(!item_info); + + item = item_info->grid_item; + + ret_if(!item); + evas_object_data_del(item, PRIVATE_DATA_KEY_ITEM_INFO); + elm_object_item_del(item); + item_info->grid_item = NULL; +} + + + +int _grid_count_item(Evas_Object *grid) +{ + int count = 0; + + retv_if(!grid, 0); + + count = elm_gengrid_items_count(grid); + + return count; +} diff --git a/src/index.c b/src/index.c new file mode 100644 index 0000000..a731e6f --- /dev/null +++ b/src/index.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 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 "log.h" +#include "index.h" + +#define PRIVATE_DATA_KEY_CUR "pdkc" + + + +void _index_destroy(Evas_Object *index) +{ + ret_if(NULL == index); + + evas_object_data_del(index, PRIVATE_DATA_KEY_CUR); + elm_index_item_clear(index); + evas_object_del(index); +} + + + +Evas_Object *_index_create(Evas_Object *ui_manager, unsigned int count) +{ + Evas_Object *index = NULL; + register int i = 0; + + retv_if(NULL == ui_manager, NULL); + + index = elm_index_add(ui_manager); + retv_if(NULL == index, NULL); + elm_object_style_set(index, "pagecontrol"); + + elm_index_horizontal_set(index, EINA_TRUE); + elm_index_autohide_disabled_set(index, EINA_TRUE); + + for (; i < count; i++) { + elm_index_item_append(index, NULL, NULL, (void *) i); + } + elm_index_level_go(index, 0); + evas_object_data_set(index, PRIVATE_DATA_KEY_CUR, NULL); + evas_object_show(index); + + return index; +} + + + +void _index_update(Evas_Object *index, unsigned int count) +{ + register int i = 0; + int cur_index = 0; + + elm_index_item_clear(index); + + for (; i < count; i++) { + elm_index_item_append(index, NULL, NULL, (void *) i); + } + elm_index_level_go(index, 0); + evas_object_show(index); + + cur_index = (int) evas_object_data_get(index, PRIVATE_DATA_KEY_CUR); + _index_bring_in(index, cur_index); +} + + + +void _index_bring_in(Evas_Object *index, int idx) +{ + Elm_Object_Item *idx_it; + + idx_it = elm_index_item_find(index, (void *) idx); + ret_if(NULL == idx_it); + elm_index_item_selected_set(idx_it, EINA_TRUE); + + evas_object_data_set(index, PRIVATE_DATA_KEY_CUR, (void *) idx); +} diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..4378ee6 --- /dev/null +++ b/src/list.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2015 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 <app_control.h> +#include <app_manager.h> +#include <glib.h> +#include <mime_type.h> + +#include "share_panel.h" +#include "share_panel_internal.h" +#include "log.h" + + + +static bool __app_control_matched_cb(app_control_h service, const char *appid, void *user_data) +{ + Eina_List **list = user_data; + char *caller = NULL; + char *tmp = NULL; + + retv_if(!list, false); + retv_if(!appid, false); + + app_control_get_caller(service, &caller); + + _SD("matched app : [%s]", appid); + if (caller && !strcmp(appid, caller)) { + _D("caller and callee is same"); + return true; + } + + tmp = strdup(appid); + retv_if(!tmp, false); + *list = eina_list_append(*list, tmp); + return true; +} + + + +static void __create_single_share_list(app_control_h control, Eina_List **list) +{ + app_control_foreach_app_matched(control, __app_control_matched_cb, list); +} + + + +static int __get_file_ext(const char *filepath, char **file_ext) +{ + const char *filename = NULL; + char *pdot = NULL; + + retv_if(!filepath, -1); + retv_if(!file_ext, -1); + + filename = ecore_file_file_get(filepath); + + retv_if(!filename, -1); + + pdot = strrchr(filename, '.'); + + if (!pdot) { + return -1; + } else if (pdot != filepath) { + *file_ext = pdot + 1; + return 0; + } else { + return -1; + } +} + + + +static inline void __get_mime(const char *file_path, char **mime) +{ + char *ext = NULL; + int res; + + ret_if(!file_path); + + if (strncmp(file_path, "/", 1) == 0) { + res = __get_file_ext(file_path, &ext); + if (0 != res) { + _D("__get_file_ext error.."); + } else { + mime_type_get_mime_type(ext, mime); + _D("mime type: [%s]", *mime); + } + } else if (strncmp(file_path, "file:/", 6) == 0) { + res = __get_file_ext(&file_path[5], &ext); + if (0 != res) { + _D("__get_file_ext error.."); + } else { + mime_type_get_mime_type(ext, mime); + _D("mime type: [%s]", *mime); + } + } else if (strncmp(file_path, "file:///", 8) == 0) { + res = __get_file_ext(&file_path[7], &ext); + if (0 != res) { + _D("__get_file_ext error.."); + } else { + mime_type_get_mime_type(ext, mime); + _D("mime type: [%s]", *mime); + } + } +} + + + +static bool __app_control_file_matched_cb(app_control_h service, const char *appid, void *user_data) +{ + Eina_List **sublist = user_data; + + *sublist = eina_list_append(*sublist, strdup(appid)); + return true; +} + + + +static void __intersect_match_list_with_mime(Eina_List **matchlist, const char *mime, const char *uri) +{ + app_control_h control; + Eina_List *l = NULL; + Eina_List *ln = NULL; + Eina_List *sublist = NULL; + Eina_List *sub_ln = NULL; + + void *m_list_data = NULL; + void *s_list_data = NULL; + bool exist; + + app_control_create(&control); + app_control_set_operation(control, TIZEN_MULTI_SHARE); + app_control_set_mime(control, mime); + app_control_set_uri(control, uri); + app_control_foreach_app_matched(control, __app_control_file_matched_cb, &sublist); + app_control_destroy(control); + + if (!*matchlist) { + *matchlist = sublist; + return; + } + + EINA_LIST_FOREACH_SAFE(*matchlist, l, ln, m_list_data) { + exist = false; + EINA_LIST_FOREACH(sublist, sub_ln, s_list_data) { + if (!strcmp(m_list_data, s_list_data)) { + _SD("[%s] is inlcude!", m_list_data); + exist = true; + break; + } + } + if (!exist) { + _SD("[%s] is not include!", m_list_data); + *matchlist = eina_list_remove(*matchlist, m_list_data); + } + } + + if (sublist) { + EINA_LIST_FREE(sublist, m_list_data) { + free(m_list_data); + } + } +} + + + +static void __trim_uri(app_control_h control) +{ + char *uri = NULL; + char *tmp = NULL; + + app_control_get_uri(control, &uri); + _SD("uri : [[[%s]]]", uri); + if (!uri) { + return; + } + + if (!strncmp(uri, "/", 1)) { + tmp = uri; + } else if (!strncmp(uri, "file:///", 8)) { + tmp = &uri[7]; + } else { + _E("file uri scheme is wrong"); + free(uri); + return; + } + + _D("set uri is [[[%s]]]", tmp); + + app_control_set_uri(control, tmp); + free(uri); +} + + + +#define CONTACT_MIME "application/vnd.tizen.contact" +static void __create_multi_share_list(app_control_h control, Eina_List **matchlist) +{ + char **data_array = NULL; + char *mime = NULL; + char *contact_mime = NULL; + char *uri = NULL; + Eina_List *mime_list = NULL; + + int i; + int length = 0; + int res; + + app_control_get_mime(control, &contact_mime); + + if (contact_mime && !strcmp(contact_mime, CONTACT_MIME)) { + _D("caller is contact"); + __intersect_match_list_with_mime(matchlist, contact_mime, uri); + return; + } else { + res = app_control_get_extra_data_array(control, TIZEN_DATA_PATH, &data_array, &length); + if (res != APP_CONTROL_ERROR_NONE) { + _E("app_control_get_extra_data_array failed..[%d]", res); + } + } + for (i = 0; i < length; i++) { + Eina_List *l = NULL; + char *tmp = NULL; + + _SD("data_array[%d]= %s", i, data_array[i]); + + __get_mime(data_array[i], &mime); + if (!mime) { + _E("no mime"); + goto out; + } + + EINA_LIST_FOREACH(mime_list, l, tmp) { + if (!strcmp(tmp, mime)) { + free(mime); + goto out; + } + } + + mime_list = eina_list_prepend(mime_list, mime); + _SD("data_array[%d]= %s", i, data_array[i]); + +out: + free(data_array[i]); + } + + free(data_array); + + app_control_get_uri(control, &uri); + + EINA_LIST_FREE(mime_list, mime) { + __intersect_match_list_with_mime(matchlist, mime, uri); + free(mime); + mime = NULL; + } +} + + + +static int __applist_compare(const void *com1, const void *com2) +{ + item_s *c1 = (item_s *)com1, *c2 = (item_s *)com2; + int res = 0; + + res = strcasecmp(c1->name, c2->name); + + return res; +} + + + +static void __make_applist(share_panel_h share_panel, Eina_List *matchlist, Eina_List **applist) +{ + Eina_List *l; + char *data = NULL; + int ret = 0; + + ret_if(!share_panel); + ret_if(!share_panel->b); + + EINA_LIST_FOREACH(matchlist, l, data) { + item_s *app_s = NULL; + app_info_h app_info = NULL; + + app_s = (item_s *) malloc(sizeof(item_s)); + continue_if(!app_s); + + app_s->appid = strdup(data); + if (!app_s->appid) { + _E("strdup error"); + free(app_s); + continue; + } + app_s->b = share_panel->b; + app_s->share_panel = share_panel; + + ret = app_info_create(data, &app_info); + if (ret != APP_MANAGER_ERROR_NONE || !app_info) { + _E("fail to create the app_info"); + free(app_s->appid); + free(app_s); + continue; + } + + ret = app_info_get_label(app_info, &app_s->name); + if (ret != APP_MANAGER_ERROR_NONE || !app_s->name) { + _E("fail to create the app_name from app_info"); + free(app_s->appid); + free(app_s); + app_info_destroy(app_info); + continue; + } + _SD("icon_name : [%s]", app_s->name); + + ret = app_info_get_icon(app_info, &app_s->icon); + if (ret != APP_MANAGER_ERROR_NONE) { + free(app_s->appid); + free(app_s->name); + free(app_s); + app_info_destroy(app_info); + continue; + } + + app_info_destroy(app_info); + + if (!app_s->icon) { + app_s->icon = strdup(DEFAULT_ICON); + } + _SD("icon_path : [%s]", app_s->icon); + + *applist = eina_list_sorted_insert(*applist, __applist_compare, app_s); + } +} + + + +Eina_List *_list_create(share_panel_h share_panel) +{ + Eina_List *matchlist = NULL; + Eina_List *applist = NULL; + char *operation_type = NULL; + char *data = NULL; + + retv_if(!share_panel, NULL); + retv_if(!share_panel->control, NULL); + retv_if(!share_panel->b, NULL); + + app_control_get_operation(share_panel->control, &operation_type); + retv_if(!operation_type, NULL); + + __trim_uri(share_panel->control); + + if (!strcmp(operation_type, TIZEN_SHARE) + || !strcmp(operation_type, TIZEN_SHARE_TEXT)) { + _D("single share operation"); + __create_single_share_list(share_panel->control, &matchlist); + } else if (!strcmp(operation_type, TIZEN_MULTI_SHARE)) { + _D("multi share operation"); + __create_multi_share_list(share_panel->control, &matchlist); + } else { + _D("Wrong operation"); + return NULL; + } + + __make_applist(share_panel, matchlist, &applist); + + EINA_LIST_FREE(matchlist, data) { + free(data); + } + + return applist; +} + + + +void _list_destroy(Eina_List *list) +{ + ret_if(!list); + eina_list_free(list); +} + diff --git a/src/page.c b/src/page.c new file mode 100644 index 0000000..029b58c --- /dev/null +++ b/src/page.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015 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_internal.h" +#include "conf.h" +#include "log.h" +#include "page.h" + + + +#define PAGE_EDJE_FILE EDJEDIR"/page.edj" +Evas_Object *_page_create(Evas_Object *scroller, int page_width, int page_height) +{ + Evas_Object *page = NULL; + Evas_Object *page_bg = NULL; + Evas *e = NULL; + + page = elm_layout_add(scroller); + retv_if(!page, NULL); + elm_layout_file_set(page, PAGE_EDJE_FILE, "page"); + + e = evas_object_evas_get(scroller); + goto_if(!e, ERROR); + + page_bg = evas_object_rectangle_add(e); + goto_if(!page_bg, ERROR); + evas_object_size_hint_weight_set(page_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_min_set(page_bg, page_width, page_height); + evas_object_size_hint_max_set(page_bg, page_width, page_height); + evas_object_color_set(page_bg, 0, 0, 0, 0); + evas_object_repeat_events_set(page_bg, EINA_TRUE); + evas_object_show(page_bg); + elm_object_part_content_set(page, "bg", page_bg); + + evas_object_show(page); + return page; + +ERROR: + _page_destroy(page); + return NULL; +} + + + +void _page_destroy(Evas_Object *page) +{ + Evas_Object *bg = NULL; + + ret_if(!page); + + bg = elm_object_part_content_unset(page, "bg"); + if (bg) { + evas_object_del(bg); + } + + evas_object_del(page); +} + + + +void _page_resize(Evas_Object *page, int width, int height) +{ + Evas_Object *bg = NULL; + + ret_if(!page); + + bg = elm_object_part_content_get(page, "bg"); + ret_if(!bg); + + evas_object_size_hint_min_set(bg, width, height); + evas_object_size_hint_max_set(bg, width, height); +} diff --git a/src/scroller.c b/src/scroller.c new file mode 100644 index 0000000..4e7a28f --- /dev/null +++ b/src/scroller.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2015 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; + + + +int _scroller_is_scrolling(Evas_Object *scroller) +{ + retv_if(!scroller, 0); + return (int)evas_object_data_get(scroller, PRIVATE_SCROLLER_IS_SCROLLING); +} + + + +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_remove_page(Evas_Object *scroller, Evas_Object *page) +{ + Evas_Object *box = NULL; + Evas_Object *tmp = NULL; + Eina_List *list = NULL; + Eina_List *event_cb_list = NULL; + const Eina_List *l = NULL; + const Eina_List *ln = NULL; + event_cb_s *event_cb_info = NULL; + + int is_page_exist = 0; + + box = elm_object_content_get(scroller); + ret_if(!box); + + list = elm_box_children_get(box); + EINA_LIST_FREE(list, tmp) { + continue_if(!tmp); + if (page == tmp) { + is_page_exist = 1; + } + } + + if (!is_page_exist) { + _D("No page to remove"); + return; + } + + elm_box_unpack(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_REMOVE_PAGE == event_cb_info->event_type) { + if (event_cb_info->event_cb) { + event_cb_info->event_cb(scroller, SCROLLER_EVENT_TYPE_REMOVE_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; +} + + + +void _scroller_bring_in_page(Evas_Object *scroller, Evas_Object *page) +{ + Evas_Object *box = NULL; + Evas_Object *tmp = NULL; + Eina_List *list = NULL; + int index = 0; + int exist = 1; + + ret_if(!scroller); + ret_if(!page); + + box = elm_object_content_get(scroller); + ret_if(!box); + + list = elm_box_children_get(box); + ret_if(!list); + + EINA_LIST_FREE(list, tmp) { + continue_if(!tmp); + if (page == tmp) { + exist = 0; + } + index += exist; + } + + if (exist) { + index = 0; + } + + elm_scroller_page_bring_in(scroller, index, 0); +} + + + +void _scroller_resize(Evas_Object *scroller, int width, int height) +{ + Evas_Object *box = NULL; + Evas_Object *page = NULL; + Eina_List *list = NULL; + + ret_if(!scroller); + + elm_scroller_page_size_set(scroller, width, height); + evas_object_size_hint_min_set(scroller, width, height); + evas_object_size_hint_max_set(scroller, width, height); + + box = elm_object_content_get(scroller); + ret_if(!box); + + evas_object_size_hint_min_set(box, width, height); + evas_object_size_hint_max_set(box, width, height); + + list = elm_box_children_get(box); + ret_if(!list); + + EINA_LIST_FREE(list, page) { + _page_resize(page, width, height); + } +} + + + +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; +} diff --git a/src/share_panel.c b/src/share_panel.c new file mode 100644 index 0000000..5007744 --- /dev/null +++ b/src/share_panel.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2015 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 <app.h> +#include <app_control.h> +#include <app_control_internal.h> +#include <aul.h> +#include <bundle.h> +#include <bundle_internal.h> +#include <efl_util.h> +#include <Elementary.h> +#include <isf_control.h> +#include <system_settings.h> + +#include "share_panel.h" +#include "share_panel_internal.h" +#include "conf.h" +#include "ui_manager.h" +#include "log.h" +#include "scroller.h" + +#ifdef EAPI +#undef EAPI +#define EAPI __attribute__ ((visibility("default"))) +#endif + +#define SHARE_PANEL_DOMAIN "share-panel" +#define TRANSIT_DURATION 0.5f + + + +typedef struct custom_effect { + Evas_Coord from_h; + Evas_Coord to_h; +} custom_effect_s; + + + +static Eina_Bool _back_key_pressed(void *data, Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + share_panel_h share_panel = data; + + retv_if(!share_panel, EINA_FALSE); + + _D("KEY PRESSED: %s", ev->key); + if (type == EVAS_CALLBACK_KEY_DOWN && !strncmp(KEY_BACK, ev->key, strlen(KEY_BACK))) { + _D("KEY PRESSED: %s", ev->key); + + _ui_manager_reply_to_cancellation(share_panel); + ui_app_exit(); + return EINA_TRUE; + } else { + return EINA_FALSE; + } +} + + + +static void _rotate_cb(void *data, Evas_Object *obj, void *event) +{ + int angle = 0; + share_panel_h share_panel = data; + + ret_if(!obj); + ret_if(!share_panel); + ret_if(!share_panel->list_count); + ret_if(!share_panel->ui_manager); + + angle = elm_win_rotation_get(obj); + _D("Angle is %d degree", angle); + + if (share_panel->list_count > SHARE_PANEL_LINE_MAX) { + return; + } + + switch(angle) { + case 0: + case 180: + elm_object_signal_emit(share_panel->ui_manager, "1line", "fixed_bg"); + break; + case 90: + case 270: + elm_object_signal_emit(share_panel->ui_manager, "1line,land", "fixed_bg"); + break; + default: + _E("cannot reach here"); + } +} + + + +static Evas_Object *__create_win(share_panel_h share_panel) +{ + Evas_Object *win = NULL; + Evas *e = NULL; + Ecore_Evas *ee = NULL; + + win = elm_win_add(NULL, "Share Panel", ELM_WIN_BASIC); + retv_if(!win, NULL); + elm_win_alpha_set(win, EINA_TRUE); + + e = evas_object_evas_get(win); + goto_if(!e, error); + + ee = ecore_evas_ecore_evas_get(e); + goto_if(!ee, error); + + ecore_evas_name_class_set(ee, "SYSTEM_POPUP", "SYSTEM_POPUP"); + + if (elm_win_wm_rotation_supported_get(win)) { + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(win, rots, (sizeof(rots) / sizeof(int))); + } + elm_win_screen_size_get(win, NULL, NULL, &share_panel->root_width, &share_panel->root_height); + _D("screen size is (%d, %d)", share_panel->root_width, share_panel->root_height); + + elm_object_event_callback_add(win, _back_key_pressed, share_panel); + evas_object_smart_callback_add(win, "wm,rotation,changed", _rotate_cb, share_panel); + + efl_util_set_window_opaque_state(win, 1); + + elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_HIDE); + elm_win_borderless_set(win, EINA_TRUE); + evas_object_show(win); + + share_panel->win = win; + + return win; + +error: + if (win) + evas_object_del(win); + + return NULL; +} + + + +static void __destroy_win(Evas_Object *win) +{ + evas_object_del(win); +} + + + +EAPI int share_panel_create(app_control_h control, share_panel_h *share_panel) +{ + share_panel_h panel = NULL; + + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + retv_if(!control, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + bindtextdomain(SHARE_PANEL_DOMAIN, LOCALEDIR); + + panel = calloc(1, sizeof(share_panel_s)); + retv_if(!panel, SHARE_PANEL_ERROR_NOT_INITIALIZED); + + app_control_export_as_bundle(control, &(panel->b)); + + goto_if(!__create_win(panel), ERROR); + + if (panel->root_width > panel->root_height) { + panel->page_width = panel->root_height; + } else { + panel->page_width = panel->root_width; + } + panel->page_height = ELM_SCALE_SIZE(SCROLLER_HEIGHT); + + panel->control = control; + panel->after_launch = 0; + + panel->ui_manager = _ui_manager_create(panel); + goto_if(!panel->ui_manager, ERROR); + + elm_win_resize_object_add(panel->win, panel->ui_manager); + share_panel_hide(panel); + + *share_panel = panel; + + return SHARE_PANEL_ERROR_NONE; + +ERROR: + if (panel->ui_manager) { + _ui_manager_destroy(panel->ui_manager); + } + free(panel); + + return SHARE_PANEL_ERROR_NOT_INITIALIZED; +} + + + +EAPI int share_panel_destroy(share_panel_h share_panel) +{ + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + if (share_panel->b) { + bundle_free(share_panel->b); + } + _ui_manager_destroy(share_panel->ui_manager); + + if (share_panel->win) { + __destroy_win(share_panel->win); + } + + free(share_panel); + + return SHARE_PANEL_ERROR_NONE; +} + + + +EAPI int share_panel_show(share_panel_h share_panel) +{ + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + return _ui_manager_show(share_panel); +} + + + +EAPI int share_panel_hide(share_panel_h share_panel) +{ + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + return _ui_manager_hide(share_panel); +} + + + +static bool _create_cb(void *data) +{ + elm_app_base_scale_set(1.7); + + return true; +} + + + +static void _terminate_cb(void *data) +{ + share_panel_h *share_panel = data; + + ret_if(!share_panel); + + share_panel_hide(*share_panel); + share_panel_destroy(*share_panel); +} + + + +static void _app_control(app_control_h control, void *data) +{ + share_panel_h *share_panel = data; + int ret = SHARE_PANEL_ERROR_NONE; + + ret_if(!share_panel); + + ret_if(!control); + + ret = share_panel_create(control, share_panel); + if (SHARE_PANEL_ERROR_NONE != ret) { + _E("Fail to create the share panel"); + return; + } + + share_panel_show(*share_panel); +} + + + +static void _pause_cb(void *data) +{ + share_panel_h *share_panel = data; + _D("share_panel is paused"); + + if ((*share_panel)->after_launch) + ui_app_exit(); +} + + + +static void _language_changed(app_event_info_h event_info, void *data) +{ + char *lang = NULL; + int ret = SYSTEM_SETTINGS_ERROR_NONE; + + _D("language changed"); + + ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &lang); + if (ret != SYSTEM_SETTINGS_ERROR_NONE) { + _E("Fail to get string value (%d", ret); + return; + } + ret_if(!lang); + elm_language_set(lang); + + free(lang); + +} + + + +int main(int argc, char **argv) +{ + int ret; + ui_app_lifecycle_callback_s lifecycle_callback = {0, }; + app_event_handler_h event_handlers[5] = {NULL, }; + share_panel_h share_panel = NULL; + + lifecycle_callback.create = _create_cb; + lifecycle_callback.terminate = _terminate_cb; + lifecycle_callback.pause = _pause_cb; + lifecycle_callback.resume = NULL; + lifecycle_callback.app_control = _app_control; + + ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, NULL, NULL); + ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, NULL, NULL); + ui_app_add_event_handler(&event_handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, NULL, NULL); + ui_app_add_event_handler(&event_handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, _language_changed, NULL); + ui_app_add_event_handler(&event_handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, NULL, NULL); + + ret = ui_app_main(argc, argv, &lifecycle_callback, &share_panel); + + return ret; +} diff --git a/src/ui_manager.c b/src/ui_manager.c new file mode 100644 index 0000000..5c135e9 --- /dev/null +++ b/src/ui_manager.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2015 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 <app.h> +#include <app_control_internal.h> +#include <aul.h> +#include <bundle.h> +#include <bundle_internal.h> +#include <Elementary.h> +#include <launch/app_sock.h> +#include <notification.h> + +#include "share_panel_internal.h" +#include "share_panel.h" +#include "log.h" +#include "list.h" +#include "page.h" +#include "index.h" +#include "scroller.h" +#include "conf.h" +#include "ui_manager.h" + +#define FILE_LAYOUT_EDJ EDJEDIR"/layout.edj" +#define GROUP_LAYOUT "layout" + + + +static void __resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Object *ui_manager = obj; + + int x, y, w, h; + + ret_if(!ui_manager); + + evas_object_geometry_get(ui_manager, &x, &y, &w, &h); + _D("%s resize(%d, %d, %d, %d)", data, x, y, w, h); +} + + + +static void _scroll_cb(Evas_Object *scroller, int event_type, void *event_info, void *data) +{ + Evas_Object *index = data; + int region_index = 0; + + ret_if(!index); + + region_index = _scroller_get_region_index(scroller); + _index_bring_in(index, region_index); + + _D("Scroller region index is %d", region_index); +} + + + +static void _append_page_cb(Evas_Object *scroller, int event_type, void *event_info, void *data) +{ + Evas_Object *index = data; + unsigned int count = 0; + + ret_if(!index); + + count = _scroller_count(scroller); + _index_update(index, count); + + _D("Index was updated as %d", count); +} + + + +static void _remove_page_cb(Evas_Object *scroller, int event_type, void *event_info, void *data) +{ + Evas_Object *index = data; + unsigned int count = 0; + + ret_if(!index); + + count = _scroller_count(scroller); + _index_update(index, count); + + _D("Index was updated as %d", count); +} + + + +static void __click_back_btn_cb(void *data, Evas_Object *obj, void *event_info) +{ + share_panel_s *share_panel = data; + + ret_if(!share_panel); + + _D("back button clicked, destroy the share-panel"); + _ui_manager_reply_to_cancellation(share_panel); + share_panel_destroy(share_panel); +} + + + +Evas_Object *__create_back_btn(Evas_Object *ui_manager, share_panel_s *share_panel) +{ + Evas_Object *button = NULL; + + retv_if(!share_panel, NULL); + retv_if(!ui_manager, NULL); + + button = elm_button_add(ui_manager); + retv_if(!button, NULL); + + elm_object_style_set(button, "focus"); + elm_object_part_content_set(ui_manager, "event", button); + evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(button); + evas_object_smart_callback_add(button, "clicked", __click_back_btn_cb, share_panel); + + return button; +} + + + +void __destroy_back_btn(Evas_Object *button) +{ + ret_if(!button); + + evas_object_del(button); +} + + + +Evas_Object *__create_bg_rect(Evas_Object *ui_manager, int width, int height) +{ + Evas_Object *ui_bg = NULL; + + ui_bg = evas_object_rectangle_add(evas_object_evas_get(ui_manager)); + retv_if(!ui_bg, NULL); + + evas_object_size_hint_weight_set(ui_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_min_set(ui_bg, ELM_SCALE_SIZE(BASE_WIDTH), ELM_SCALE_SIZE(BASE_HEIGHT)); + evas_object_size_hint_max_set(ui_bg, ELM_SCALE_SIZE(BASE_WIDTH), ELM_SCALE_SIZE(BASE_HEIGHT)); + evas_object_color_set(ui_bg, 0, 0, 0, 0); + evas_object_show(ui_bg); + elm_object_part_content_set(ui_manager, "fixed_bg", ui_bg); + + return ui_bg; +} + + + +void __destroy_bg_rect(Evas_Object *bg) +{ + ret_if(!bg); + + evas_object_del(bg); +} + + + +Evas_Object *_ui_manager_create(share_panel_s *share_panel) +{ + Evas_Object *ui_manager = NULL; + Evas_Object *edje = NULL; + + retv_if(!share_panel, NULL); + + ui_manager = elm_layout_add(share_panel->win); + retv_if(!ui_manager, NULL); + + elm_layout_file_set(ui_manager, FILE_LAYOUT_EDJ, GROUP_LAYOUT); + evas_object_size_hint_weight_set(ui_manager, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ui_manager, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(ui_manager); + + evas_object_event_callback_add(ui_manager, EVAS_CALLBACK_RESIZE, __resize_cb, "ui_manager"); + + evas_object_data_set(ui_manager, DATA_KEY_SHARE_PANEL_INFO, share_panel); + + goto_if(!__create_bg_rect(ui_manager, share_panel->root_width, share_panel->root_height), ERROR); + + goto_if(!__create_back_btn(ui_manager, share_panel), ERROR); + + elm_object_part_text_set(ui_manager, "title", _("IDS_AM_HEADER_SHARE")); + elm_object_domain_translatable_part_text_set(ui_manager, "title", PROJECT, "IDS_AM_HEADER_SHARE"); + + share_panel->index = _index_create(ui_manager, 0); + goto_if(!share_panel->index, ERROR); + elm_object_part_content_set(ui_manager, "index", share_panel->index); + + share_panel->scroller = _scroller_create(ui_manager, share_panel); + goto_if(!share_panel->scroller, ERROR); + elm_object_part_content_set(ui_manager, "scroller", share_panel->scroller); + + if (SHARE_PANEL_ERROR_NONE != _scroller_register_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_SCROLL, _scroll_cb, share_panel->index)) { + _E("cannot register the scroller event"); + } + if (SHARE_PANEL_ERROR_NONE != _scroller_register_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_APPEND_PAGE, _append_page_cb, share_panel->index)) { + _E("cannot register the scroller event"); + } + if (SHARE_PANEL_ERROR_NONE != _scroller_register_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_REMOVE_PAGE, _remove_page_cb, share_panel->index)) { + _E("cannot register the scroller event"); + } + + share_panel->list = _list_create(share_panel); + if (!share_panel->list) { + notification_status_message_post(_("IDS_BT_POP_NO_APPLICATIONS_AVAILABLE_TO_OPEN_FILES")); + ui_app_exit(); + } + + share_panel->list_count = eina_list_count(share_panel->list); + + if (1 == share_panel->list_count) { + item_s *item_info = NULL; + int ret = 0; + + _D("item list is 1, launch app right"); + + item_info = eina_list_nth(share_panel->list, 0); + goto_if(!item_info, ERROR); + + ret = aul_forward_app(item_info->appid, item_info->b); + if (ret < 0) { + _E("Fail to launch app(%d)", ret); + } + ui_app_exit(); + } + + _scroller_append_list(share_panel->scroller + , share_panel->list + , share_panel->page_width + , share_panel->page_height); + + edje = elm_layout_edje_get(ui_manager); + goto_if(!edje, ERROR); + + if (share_panel->list_count <= SHARE_PANEL_LINE_MAX) { + if (share_panel->root_width < share_panel->root_height) { + edje_object_signal_emit(edje, "1line", "fixed_bg"); + } else { + edje_object_signal_emit(edje, "1line,land", "fixed_bg"); + } + } + + edje_object_message_signal_process(edje); + + return ui_manager; + +ERROR: + _ui_manager_destroy(ui_manager); + return NULL; +} + + + +void _ui_manager_destroy(Evas_Object *ui_manager) +{ + Evas_Object *button = NULL; + Evas_Object *bg = NULL; + share_panel_s *share_panel = NULL; + ret_if(!ui_manager); + + share_panel = evas_object_data_del(ui_manager, DATA_KEY_SHARE_PANEL_INFO); + ret_if(!share_panel); + + if (share_panel->list) { + _list_destroy(share_panel->list); + } + + if (share_panel->scroller) { + _scroller_unregister_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_SCROLL, _scroll_cb); + _scroller_unregister_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_APPEND_PAGE, _append_page_cb); + _scroller_unregister_event_cb(share_panel->scroller, SCROLLER_EVENT_TYPE_REMOVE_PAGE, _remove_page_cb); + _scroller_destroy(share_panel->scroller); + } + + if (share_panel->index) { + _index_destroy(share_panel->index); + } + + button = elm_object_part_content_unset(ui_manager, "effect"); + if(button) { + __destroy_back_btn(button); + } + + bg = elm_object_part_content_unset(ui_manager, "fixed_bg"); + if(bg) { + __destroy_bg_rect(bg); + } + + evas_object_del(ui_manager); +} + + + +void _ui_manager_resize(Evas_Object *ui_manager, int width, int height) +{ + ret_if(!ui_manager); + + evas_object_size_hint_min_set(ui_manager, width, height); + evas_object_size_hint_max_set(ui_manager, width, height); + evas_object_resize(ui_manager, width, height); + evas_object_move(ui_manager, 0, 0); + edje_object_message_signal_process(elm_layout_edje_get(ui_manager)); +} + + + +int _ui_manager_show(share_panel_h share_panel) +{ + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + retv_if(!share_panel->ui_manager, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + evas_object_show(share_panel->ui_manager); + + share_panel->show_state = SHARE_PANEL_SHOW_STATE_HALF; + + return SHARE_PANEL_ERROR_NONE; +} + + + +int _ui_manager_hide(share_panel_h share_panel) +{ + retv_if(!share_panel, SHARE_PANEL_ERROR_INVALID_PARAMETER); + retv_if(!share_panel->ui_manager, SHARE_PANEL_ERROR_INVALID_PARAMETER); + + share_panel->show_state = SHARE_PANEL_SHOW_STATE_HIDE; + evas_object_hide(share_panel->ui_manager); + + return SHARE_PANEL_ERROR_NONE; +} + + + +void _ui_manager_reply_to_cancellation(share_panel_h share_panel) +{ + bundle *kb = NULL; + const char *pid = NULL; + char callee_pid[20] = {0, }; + int ret; + + ret_if(!share_panel); + ret_if(!share_panel->b); + pid = bundle_get_val(share_panel->b, AUL_K_CALLER_PID); + ret_if(!pid); + + kb = bundle_create(); + ret_if(!kb); + + ret = bundle_add(kb, AUL_K_SEND_RESULT, "1"); + if (ret != BUNDLE_ERROR_NONE) { + _E("Fail to bundle add (%d)", ret); + goto OUT; + } + + ret = bundle_add(kb, AUL_K_CALLER_PID, pid); + if (ret != BUNDLE_ERROR_NONE) { + _E("Fail to bundle add (%d)", ret); + goto OUT; + } + + snprintf(callee_pid, sizeof(callee_pid), "%d", getpid()); + ret = bundle_add(kb, AUL_K_CALLEE_PID, (const char *) callee_pid); + if (ret != BUNDLE_ERROR_NONE) { + _E("Fail to bundle add (%d)", ret); + goto OUT; + } + + ret = app_send_cmd_with_noreply(-2, APP_CANCEL, kb); + if (ret != AUL_R_OK) { + _E("app_send_cmd error(%d)", ret); + } + +OUT: + bundle_free(kb); +} |