Taskmanager / src /
view.c
- /*
- * Copyright (c) 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 <efl_extension.h>
- #include "view.h"
- #include "item.h"
- #include "$(appName).h"
- #include "defines.h"
- static struct view_info {
- Evas_Object *win;
- Evas_Object *layout;
- Evas_Object *conform;
- Evas_Object *genlist;
- Elm_Genlist_Item_Class *item_class;
- view_item_callback_t item_clicked_callback;
- view_item_callback_t item_deleted_callback;
- } s_info = {
- .win = NULL,
- .layout = NULL,
- .conform = NULL,
- .genlist = NULL,
- .item_class = NULL,
- .item_clicked_callback = NULL,
- .item_deleted_callback = NULL,
- };
- static void _delete_win_request_cb(void *data, Evas_Object *obj, void *event_info);
- static void _layout_back_cb(void *data, Evas_Object *obj, void *event_info);
- static void _get_app_resource(const char *edj_file_in, char *edj_path_out);
- static Evas_Object *_create_icon(Evas_Object *parent, char *image_path);
- static void _item_layout_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
- static Evas_Object *_create_item_layout(Evas_Object *parent, char *app_id, char *icon_path);
- static Evas_Object *_get_item_content(void *data, Evas_Object *obj, const char *part);
- static Evas_Object *_create_genlist(void);
- static void _delete_item(Elm_Object_Item *genlist_item);
- static void _view_display_no_applications(void);
- static Eina_Bool _view_display_application_list(Eina_List *app_list);
- /**
- * @brief Creates essential objects: window, conformant and layout.
- */
- Eina_Bool view_create(void *user_data)
- {
- char edj_path[PATH_MAX] = {0, };
- /* Create the window */
- s_info.win = view_create_win(PACKAGE);
- if (s_info.win == NULL) {
- dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a window.");
- return EINA_FALSE;
- }
- /* Create the conformant */
- s_info.conform = view_create_conformant_without_indicator(s_info.win);
- if (s_info.conform == NULL) {
- dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a conformant");
- return EINA_FALSE;
- }
- /* Base Layout */
- _get_app_resource(MAIN_EDJ, edj_path);
- s_info.layout = view_create_layout(s_info.win, edj_path, TASKMGR_MAIN_GROUP);
- if (!s_info.layout) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create layout");
- evas_object_del(s_info.win);
- return EINA_FALSE;
- }
- elm_object_content_set(s_info.conform, s_info.layout);
- /* Genlist */
- s_info.genlist = _create_genlist();
- if (!s_info.genlist) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create genlist");
- evas_object_del(s_info.win);
- return EINA_FALSE;
- }
- /* Show window after base gui is set up */
- evas_object_show(s_info.win);
- return EINA_TRUE;
- }
- /**
- * @brief Creates a basic window named package.
- * @param[in] pkg_name Name of the window
- */
- Evas_Object *view_create_win(const char *pkg_name)
- {
- Evas_Object *win = NULL;
- /*
- * Window
- * Create and initialize elm_win.
- * elm_win is mandatory to manipulate the window.
- */
- win = elm_win_util_standard_add(pkg_name, pkg_name);
- elm_win_conformant_set(win, EINA_TRUE);
- elm_win_autodel_set(win, EINA_TRUE);
- elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_SHOW);
- elm_win_indicator_opacity_set(win, ELM_WIN_INDICATOR_OPAQUE);
- evas_object_smart_callback_add(win, "delete,request", _delete_win_request_cb, NULL);
- return win;
- }
- /**
- * @brief Creates a layout to target parent object with edje file
- * @param[in] parent The object to which you want to add this layout
- * @param[in] file_path File path of EDJ file will be used
- * @param[in] group_name Name of group in EDJ you want to set to
- * @param[in] cb_function The function will be called when back event is detected
- * @param[in] user_data The user data to be passed to the callback functions
- */
- Evas_Object *view_create_layout(Evas_Object *parent, const char *file_path, const char *group_name)
- {
- Evas_Object *layout = NULL;
- if (parent == NULL) {
- dlog_print(DLOG_ERROR, LOG_TAG, "parent is NULL.");
- return NULL;
- }
- /* Create layout using EDC(an edje file) */
- layout = elm_layout_add(parent);
- elm_layout_file_set(layout, file_path, group_name);
- /* Layout size setting */
- evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- eext_object_event_callback_add(layout, EEXT_CALLBACK_BACK, _layout_back_cb, NULL);
- evas_object_show(layout);
- return layout;
- }
- /**
- * @brief Creates a conformant without indicator for wearable app.
- * @param[in] win The object to which you want to set this conformant
- * Conformant is mandatory for base GUI to have proper size
- */
- Evas_Object *view_create_conformant_without_indicator(Evas_Object *win)
- {
- /*
- * Conformant
- * Create and initialize elm_conformant.
- * elm_conformant is mandatory for base GUI to have proper size
- * when indicator or virtual keypad is visible.
- */
- Evas_Object *conform = NULL;
- if (win == NULL) {
- dlog_print(DLOG_ERROR, LOG_TAG, "window is NULL.");
- return NULL;
- }
- conform = elm_conformant_add(win);
- evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- elm_win_resize_object_add(win, conform);
- evas_object_show(conform);
- return conform;
- }
- /**
- * @brief The applications list is displayed or 'No applications' label if the
- * provided list is empty.
- * @param[in] app_list The list of application ids and paths to its icons.
- */
- void view_update_application_list(Eina_List *app_list)
- {
- if (!app_list) {
- dlog_print(DLOG_ERROR, LOG_TAG, "No running applications");
- _view_display_no_applications();
- } else {
- _view_display_application_list(app_list);
- }
- }
- /**
- * @brief The view callback functions are set.
- * @param[in] item_clicked_callback The callback function to be invoked on application's icon click.
- * @param[in] item_deleted_callback The callback function to be invoked on application's icon removal.
- */
- void view_set_callbacks(view_item_callback_t item_clicked_callback, view_item_callback_t item_deleted_callback)
- {
- s_info.item_clicked_callback = item_clicked_callback;
- s_info.item_deleted_callback = item_deleted_callback;
- }
- /**
- * @brief Destroys window and frees its resources.
- */
- void view_destroy(void)
- {
- if (s_info.win == NULL)
- return;
- evas_object_del(s_info.win);
- }
- /**
- * @brief Internal function which displays the 'No applications' label in place
- * of application icons.
- */
- static void _view_display_no_applications(void)
- {
- if (s_info.layout)
- elm_layout_signal_emit(s_info.layout, TASKMGR_PROGRAM_NO_APPS_SHOW_SIGNAL, TASKMGR_PROGRAM_NO_APPS_SHOW_SOURCE);
- if (s_info.genlist)
- elm_genlist_clear(s_info.genlist);
- }
- /**
- * @brief Internal function responsible for application's list display.
- * @param[in] app_list The list of application ids and paths to its icons.
- * @return Function returns 'EINA_TRUE' if the applications list was displayed
- * successfully, otherwise 'EINA_FALSE' is returned.
- */
- static Eina_Bool _view_display_application_list(Eina_List *app_list)
- {
- Eina_List *it = NULL;
- app_item_t *item = NULL;
- if (!app_list) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Invalid argument");
- return false;
- }
- if (s_info.layout)
- elm_layout_signal_emit(s_info.layout, TASKMGR_PROGRAM_NO_APPS_HIDE_SIGNAL, TASKMGR_PROGRAM_NO_APPS_HIDE_SOURCE);
- if (elm_genlist_items_count(s_info.genlist) != 0)
- elm_genlist_clear(s_info.genlist);
- EINA_LIST_FOREACH(app_list, it, item)
- elm_genlist_item_append(s_info.genlist, s_info.item_class, (void *)item, NULL,
- ELM_GENLIST_ITEM_NONE, NULL, NULL);
- return true;
- }
- /**
- * @brief Internal callback function invoked when the main window needs to be destroyed.
- * @param[in] data The user data passed to the evas_object_smart_callback_add() function.
- * @param[in] obj The object invoking this callback function.
- * @param[in] event_info The structure containing the information on this event.
- */
- static void _delete_win_request_cb(void *data, Evas_Object *obj, void *event_info)
- {
- ui_app_exit();
- }
- /**
- * @brief Internal callback function invoked on HW Back button press.
- * @param[in] data The user data passed to the eext_object_event_callback_add() function.
- * @param[in] obj The object invoking this callback function.
- * @param[in] event_info The structure containing the information on this event.
- */
- static void _layout_back_cb(void *data, Evas_Object *obj, void *event_info)
- {
- /* Let window go to hide state. */
- elm_win_lower(s_info.win);
- }
- /**
- * @brief Internal function which creates fully qualified path to the provided resource file.
- * @param[in] edj_file_in The file name.
- * @param[out] edj_path_out The fully qualified path to the edj_file_in file.
- */
- static void _get_app_resource(const char *edj_file_in, char *edj_path_out)
- {
- char *res_path = app_get_resource_path();
- if (res_path) {
- snprintf(edj_path_out, PATH_MAX, "%s%s", res_path, edj_file_in);
- free(res_path);
- }
- }
- /**
- * @brief Internal function creates an application's icons based on provided icon's path.
- * @param[in] parent The parent object for an icon to be created.
- * @param[in] image_path The fully qualified path to the application's icon to be displayed.
- * @return This function returns an icon if it was successfully created,
- * otherwise NULL is returned.
- */
- static Evas_Object *_create_icon(Evas_Object *parent, char *image_path)
- {
- Evas_Object *icon = elm_image_add(parent);
- if (!icon) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create an image");
- return NULL;
- }
- elm_image_file_set(icon, image_path, NULL);
- evas_object_show(icon);
- return icon;
- }
- /**
- * @brief Internal function handling user gestures over an applications icon.
- * The following gestures are supported:
- * - tap - item clicked callback function is invoked.
- * - swipe left/right - removes the swiped application form the list.
- * @param[in] data The user data passed to the callback attachment function evas_object_event_callback_add().
- * @param[in] e The evas surface where the event took place.
- * @param[in] obj The object invoking this callback function.
- * @param[in] event_info The structure containing the information on this event.
- */
- static void _item_layout_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
- {
- Evas_Object *edje = NULL;
- Elm_Object_Item *genlist_item = NULL;
- double dx = 0;
- Evas_Event_Mouse_Up *mouse_up_ev = (Evas_Event_Mouse_Up *)event_info;
- edje = elm_layout_edje_get(obj);
- edje_object_part_drag_value_get(edje, ITEM_PART_BASE, &dx, NULL);
- if ((int)dx == 0) {
- /* Item was not dragged left/right - item was clicked, resume application */
- genlist_item = elm_genlist_at_xy_item_get(s_info.genlist, mouse_up_ev->canvas.x, mouse_up_ev->canvas.y, NULL);
- if (!genlist_item) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get item at %d, %d", mouse_up_ev->canvas.x, mouse_up_ev->canvas.y);
- return;
- }
- app_item_t *item = (app_item_t *)elm_object_item_data_get(genlist_item);
- if (!item) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get item data");
- return;
- }
- if (s_info.item_clicked_callback)
- s_info.item_clicked_callback(item->app_id);
- } else if (dx < ITEM_DRAG_OUTSIDE_VAL && dx > -ITEM_DRAG_OUTSIDE_VAL) {
- /* Item was dragged, but not far enough to terminate application */
- elm_layout_signal_emit(obj, ITEM_PROGRAM_RESET_POSITION_SIGNAL, ITEM_PROGRAM_RESET_POSITION_SOURCE);
- } else {
- /* Item was dragged to left/right edge of the screen - terminate application */
- elm_layout_signal_emit(obj, ITEM_PROGRAM_HIDE_SIGNAL, ITEM_PROGRAM_HIDE_SOURCE);
- genlist_item = elm_genlist_at_xy_item_get(s_info.genlist, mouse_up_ev->canvas.x, mouse_up_ev->canvas.y, NULL);
- if (!genlist_item) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get item at %d, %d", mouse_up_ev->canvas.x, mouse_up_ev->canvas.y);
- return;
- }
- _delete_item(genlist_item);
- if (elm_genlist_items_count(s_info.genlist) == 0)
- _view_display_no_applications();
- }
- }
- /**
- * @brief Internal function which creates the list item's layout where the
- * information is displayed (application's icon and identifier).
- * @param[in] parent The parent object for a layout to be created.
- * @param[in] app_id The application identifier to be displayed.
- * @param[in] icon_path The application's icon to be displayed.
- * @return This function returns a layout object if it was successfully created,
- * otherwise NULL is returned.
- */
- static Evas_Object *_create_item_layout(Evas_Object *parent, char *app_id, char *icon_path)
- {
- Evas_Object *icon = NULL;
- Evas_Object *layout = NULL;
- char edj_path[PATH_MAX] = {0, };
- _get_app_resource(ITEM_EDJ, edj_path);
- layout = elm_layout_add(parent);
- if (!layout) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create layout");
- return NULL;
- }
- elm_layout_file_set(layout, edj_path, GENLIST_CUSTOM_ITEM_GROUP);
- evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, _item_layout_mouse_up_cb, NULL);
- icon = _create_icon(parent, icon_path);
- elm_object_part_content_set(layout, ITEM_PART_CONTENT, icon);
- elm_object_part_text_set(layout, ITEM_PART_TEXT, app_id);
- evas_object_show(layout);
- return layout;
- }
- /**
- * @brief Internal callback function invoked on list's item display.
- * This function is responsible for non-text objects handling and it is assigned
- * to the func.content_get handler of genlist item's class structure.
- * In the content area of an genlist item, the application's icon is displayed.
- * @param[in] data The user data passed to the elm_genlist_item_append() function.
- * @param[in] obj The object invoking this callback function.
- * @param[in] part The name of the item's part being rendered.
- * @return The list's item layout is returned if it was successfully created,
- * otherwise NULL is returned.
- */
- static Evas_Object *_get_item_content(void *data, Evas_Object *obj, const char *part)
- {
- if (!data)
- return NULL;
- app_item_t *item = (app_item_t *)data;
- return _create_item_layout(obj, item->app_id, item->icon_path);
- }
- /**
- * @brief Internal function which creates a genlist object and related item class.
- * The newly created genlist is set to the window object.
- * @return The function returns genlist object if it was created successfully,
- * otherwise 'NULL' is returned.
- */
- static Evas_Object *_create_genlist(void)
- {
- Evas_Object *genlist = elm_genlist_add(s_info.win);
- if (!genlist) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create genlist");
- return NULL;
- }
- s_info.item_class = elm_genlist_item_class_new();
- if (!s_info.item_class) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create item class");
- evas_object_del(genlist);
- return NULL;
- }
- s_info.item_class->item_style = "full";
- s_info.item_class->func.text_get = NULL;
- s_info.item_class->func.content_get = _get_item_content;
- s_info.item_class->func.state_get = NULL;
- s_info.item_class->func.del = NULL;
- elm_genlist_mode_set(genlist, ELM_LIST_SCROLL);
- elm_genlist_select_mode_set(genlist, ELM_OBJECT_SELECT_MODE_NONE);
- elm_object_part_content_set(s_info.layout, TASKMGR_PART_CONTENT, genlist);
- return genlist;
- }
- /**
- * @brief Internal function responsible for list's item removal and item
- * delete callback invocation.
- */
- static void _delete_item(Elm_Object_Item *genlist_item)
- {
- app_item_t *item = (app_item_t *)elm_object_item_data_get(genlist_item);
- if (!item) {
- dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get item data");
- return;
- }
- if (s_info.item_deleted_callback)
- s_info.item_deleted_callback(item->app_id);
- elm_object_item_del(genlist_item);
- }