File Manager / src / view /
genlist-widget.c
/*
* Copyright 2014 - 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 "view/genlist-widget.h"
#include "view/navi-path-widget.h"
#include "view/list-view.h"
#include "utils/ui-utils.h"
#include "utils/logger.h"
#include "utils/model-utils.h"
#include "utils/config.h"
#include "utils/common-utils.h"
#include "utils/app-types.h"
#include "main-app.h"
#define MIN_FILE_TYPE_ICON_SIZE ELM_SCALE_SIZE(80)
static const char *const LABEL_TEXT_SELECT_ALL = "Select All";
static void _genlist_widget_destroy(genlist_widget *widget);
static void _genlist_widget_set_items_style(genlist_widget *widget);
static void _genlist_widget_reset_all_checkboxes(genlist_widget *widget);
static void _genlist_widget_check_state_sel_all(genlist_widget *widget);
static void _genlist_widget_item_edit_sel(genlist_widget *widget, Evas_Object *checkbox);
static void _genlist_widget_sel_all_item_sel(genlist_widget *widget);
static void _genlist_widget_delete_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _genlist_widget_item_sel_cb(void *data, Evas_Object *obj, void *event_info);
static void _genlist_widget_sel_all_checkbox_change_cb(void *data, Evas_Object *obj, void *event_info);
static void _genlist_widget_sel_all_layout_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _genlist_widget_item_checkbox_sel_cb(void *data, Evas_Object *obj, void *event_info);
static Evas_Object *_genlist_widget_edit_icon_get(void *data, Evas_Object *obj, const char *part);
static Evas_Object *_genlist_widget_main_icon_get(const char *icon_name, Evas_Object *parent);
static Evas_Object *_genlist_widget_default_node_icon_get(void *data, Evas_Object *obj, const char *part);
static Evas_Object *_genlist_widget_default_storage_icon_get(void *data, Evas_Object *obj, const char *part);
static char *_genlist_widget_node_label_get(void *data, Evas_Object *obj, const char *part);
static char *_genlist_widget_storage_label_get(void *data, Evas_Object *obj, const char *part);
genlist_widget *genlist_widget_add(view_data *view)
{
RETVM_IF(!view, NULL, "View object is NULL");
genlist_widget *widget = calloc(1, sizeof(genlist_widget));
RETVM_IF(!widget, NULL, "Fail allocate memory");
widget->view = view;
widget->box = elm_box_add(widget->view->navi_layout);
if (!widget->box) {
ERR("Fail to create box");
_genlist_widget_destroy(widget);
return NULL;
}
evas_object_size_hint_weight_set(widget->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
widget->sel_all_layout = elm_layout_add(widget->box);
if (!widget->sel_all_layout) {
ERR("Fail to create select all layout object");
evas_object_del(widget->box);
_genlist_widget_destroy(widget);
return NULL;
}
elm_layout_theme_set(widget->sel_all_layout, "genlist", "item", "select_all/default");
evas_object_size_hint_weight_set(widget->sel_all_layout, EVAS_HINT_EXPAND, EVAS_HINT_FILL);
evas_object_size_hint_align_set(widget->sel_all_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_event_callback_add(widget->sel_all_layout, EVAS_CALLBACK_MOUSE_DOWN,
_genlist_widget_sel_all_layout_down_cb, widget);
evas_object_show(widget->sel_all_layout);
widget->sel_all_checkbox = elm_check_add(widget->sel_all_layout);
if (!widget->sel_all_checkbox) {
ERR("Fail to create select all checkbox object");
evas_object_del(widget->box);
_genlist_widget_destroy(widget);
return NULL;
}
evas_object_propagate_events_set(widget->sel_all_checkbox, EINA_FALSE);
elm_check_state_pointer_set(widget->sel_all_checkbox, &widget->view->edit.is_all_selected);
evas_object_smart_callback_add(widget->sel_all_checkbox, "changed",
_genlist_widget_sel_all_checkbox_change_cb, widget);
elm_object_part_content_set(widget->sel_all_layout, "elm.icon", widget->sel_all_checkbox);
elm_object_part_text_set(widget->sel_all_layout, "elm.text.main", LABEL_TEXT_SELECT_ALL);
evas_object_show(widget->sel_all_layout);
widget->genlist = ui_utils_genlist_add(widget->view->navi_layout, _genlist_widget_delete_cb, widget);
if (!widget->genlist) {
ERR("Fail to create genlist");
evas_object_del(widget->box);
_genlist_widget_destroy(widget);
return NULL;
}
_genlist_widget_set_items_style(widget);
elm_box_pack_end(widget->box, widget->genlist);
evas_object_show(widget->box);
elm_object_part_content_set(widget->view->navi_layout, "content", widget->box);
evas_object_data_set(widget->genlist, "data_list", widget);
return widget;
}
void genlist_widget_content_set(genlist_widget *widget, const Eina_List *file_list)
{
RETM_IF(!widget, "Widget is NULL");
const Eina_List *list = NULL;
void *item = NULL;
_genlist_widget_set_items_style(widget);
EINA_LIST_FOREACH(file_list, list, item)
{
Elm_Object_Item *node_item = elm_genlist_item_append(widget->genlist, &itc, item, NULL,
ELM_GENLIST_ITEM_NONE, _genlist_widget_item_sel_cb, widget);
elm_object_item_data_set(node_item, item);
}
}
int genlist_widget_update(genlist_widget *widget)
{
RETVM_IF(!widget->view, RESULT_TYPE_INVALID_ARG, "View object is NULL");
app_data *app = widget->view->app;
_genlist_widget_set_items_style(widget);
_genlist_widget_reset_all_checkboxes(widget);
if (app->status.curr_mode == MODE_EDIT) {
evas_object_show(widget->sel_all_layout);
elm_box_pack_start(widget->box, widget->sel_all_layout);
} else {
evas_object_hide(widget->sel_all_layout);
elm_box_unpack(widget->box, widget->sel_all_layout);
}
return RESULT_TYPE_OK;
}
void genlist_widget_clear(genlist_widget *widget)
{
elm_genlist_clear(widget->genlist);
}
static void _genlist_widget_destroy(genlist_widget *widget)
{
free(widget);
}
static void _genlist_widget_set_items_style(genlist_widget *widget)
{
app_data *app = widget->view->app;
itc.item_style = "type1";
itc.func.text_get = (app->status.is_mainview)
? _genlist_widget_storage_label_get
: _genlist_widget_node_label_get;
if (app->status.curr_mode == MODE_EDIT) {
itc.func.content_get = _genlist_widget_edit_icon_get;
} else {
itc.func.content_get = (app->status.is_mainview)
? _genlist_widget_default_storage_icon_get
: _genlist_widget_default_node_icon_get;
}
elm_genlist_realized_items_update(widget->genlist);
}
static void _genlist_widget_reset_all_checkboxes(genlist_widget *widget)
{
Elm_Object_Item *item = elm_genlist_first_item_get(widget->genlist);
while (item) {
node_info *node = elm_object_item_data_get(item);
node->is_selected = EINA_FALSE;
Evas_Object *checkbox = elm_object_item_part_content_get(item, "elm.swallow.end");
elm_check_state_set(checkbox, EINA_FALSE);
item = elm_genlist_item_next_get(item);
}
elm_check_state_set(widget->sel_all_checkbox, EINA_FALSE);
widget->view->edit.checked_count = 0;
}
static void _genlist_widget_check_state_sel_all(genlist_widget *widget)
{
Eina_Bool check_sel_all = EINA_FALSE;
if (widget->view->edit.checked_count == list_view_items_count_get(widget->view)) {
check_sel_all = EINA_TRUE;
}
elm_check_state_set(widget->sel_all_checkbox, check_sel_all);
}
static void _genlist_widget_item_edit_sel(genlist_widget *widget, Evas_Object *checkbox)
{
Eina_Bool checked = elm_check_state_get(checkbox);
(checked) ? ++widget->view->edit.checked_count
: --widget->view->edit.checked_count;
}
static void _genlist_widget_sel_all_item_sel(genlist_widget *widget)
{
Eina_Bool checked = elm_check_state_get(widget->sel_all_checkbox);
Elm_Object_Item *item = elm_genlist_first_item_get(widget->genlist);
while (item) {
node_info *node = elm_object_item_data_get(item);
if (node->is_selected != checked) {
node->is_selected = checked;
(checked) ? ++widget->view->edit.checked_count
: --widget->view->edit.checked_count;
Evas_Object *checkbox = elm_object_item_part_content_get(item, "elm.swallow.end");
elm_check_state_set(checkbox, checked);
}
item = elm_genlist_item_next_get(item);
}
int res = list_view_select_all(widget->view, checked);
RETM_IF(res != RESULT_TYPE_OK, "Failed to %s all files", (checked ? "select" : "unselect"));
}
static void _genlist_widget_delete_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
_genlist_widget_destroy(data);
}
static void _genlist_widget_item_sel_cb(void *data, Evas_Object *obj, void *event_info)
{
RETM_IF(!data, "Data is NULL");
genlist_widget *widget = data;
app_data *app = widget->view->app;
elm_genlist_item_selected_set(event_info, EINA_FALSE);
if (app->status.curr_mode != MODE_EDIT) {
if (app->status.is_mainview) {
storage_info *storage = elm_object_item_data_get(event_info);
list_view_add(app, widget->view->navi, storage->root_path, NULL);
} else {
node_info *pNode = elm_object_item_data_get(event_info);
if (pNode->type == FILE_TYPE_DIR) {
list_view_add(app, widget->view->navi, widget->view->curr_path, pNode->name);
} else {
model_utils_launch_file(pNode);
}
}
} else {
Evas_Object *checkbox = elm_object_item_part_content_get(event_info, "elm.swallow.end");
Eina_Bool checked = elm_check_state_get(checkbox);
elm_check_state_set(checkbox, !checked);
_genlist_widget_item_edit_sel(widget, checkbox);
_genlist_widget_check_state_sel_all(widget);
int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
}
}
static void _genlist_widget_sel_all_layout_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
RETM_IF(!data, "Data is NULL");
genlist_widget *widget = data;
Eina_Bool checked = elm_check_state_get(widget->sel_all_checkbox);
elm_check_state_set(widget->sel_all_checkbox, !checked);
_genlist_widget_sel_all_checkbox_change_cb(data, widget->sel_all_checkbox, NULL);
}
static void _genlist_widget_sel_all_checkbox_change_cb(void *data, Evas_Object *obj, void *event_info)
{
RETM_IF(!data, "Data is NULL");
genlist_widget *widget = data;
_genlist_widget_sel_all_item_sel(widget);
int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
}
static void _genlist_widget_item_checkbox_sel_cb(void *data, Evas_Object *obj, void *event_info)
{
RETM_IF(!data, "Data is NULL");
genlist_widget *widget = data;
_genlist_widget_item_edit_sel(widget, obj);
_genlist_widget_check_state_sel_all(widget);
int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
}
static Evas_Object *_genlist_widget_edit_icon_get(void *data, Evas_Object *obj, const char *part)
{
RETVM_IF(!data, NULL, "Data is NULL");
Evas_Object *eo = NULL;
genlist_widget *widget = evas_object_data_get(obj, "data_list");
node_info *pNode = data;
if (!strcmp(part, "elm.swallow.icon")) {
eo = _genlist_widget_default_node_icon_get(data, obj, part);
RETVM_IF(!eo, NULL, "Failed to create icon");
} else if (!strcmp(part, "elm.swallow.end")) {
eo = elm_check_add(obj);
elm_check_state_set(eo, pNode->is_selected);
elm_check_state_pointer_set(eo, &pNode->is_selected);
elm_object_focus_set(eo, EINA_FALSE);
evas_object_propagate_events_set(eo, EINA_FALSE);
evas_object_smart_callback_add(eo, "changed", _genlist_widget_item_checkbox_sel_cb, widget);
}
return eo;
}
static Evas_Object *_genlist_widget_main_icon_get(const char *icon_name, Evas_Object *parent)
{
Evas_Object *icon = elm_image_add(parent);
elm_object_focus_set(icon, EINA_FALSE);
elm_image_file_set(icon, ui_utils_get_resource(icon_name), NULL);
evas_object_size_hint_min_set(icon, MIN_FILE_TYPE_ICON_SIZE, MIN_FILE_TYPE_ICON_SIZE);
evas_object_show(icon);
return icon;
}
static Evas_Object *_genlist_widget_default_node_icon_get(void *data, Evas_Object *obj, const char *part)
{
RETVM_IF(!data, NULL, "Data is NULL");
node_info *pNode = data;
Evas_Object *eo = NULL;
const char *icon_name = model_utils_get_default_icon_name(pNode->type);
if (!strcmp(part, "elm.swallow.icon")) {
eo = _genlist_widget_main_icon_get(icon_name, obj);
RETVM_IF(!eo, NULL, "Failed to create icon");
}
return eo;
}
static Evas_Object *_genlist_widget_default_storage_icon_get(void *data, Evas_Object *obj, const char *part)
{
RETVM_IF(!data, NULL, "Data is NULL");
Evas_Object *eo = NULL;
if (!strcmp(part, "elm.swallow.icon")) {
eo = _genlist_widget_main_icon_get(FM_ICON_FOLDER, obj);
RETVM_IF(!eo, NULL, "Failed to create icon");
}
return eo;
}
static char *_genlist_widget_node_label_get(void *data, Evas_Object *obj, const char *part)
{
RETVM_IF(!data, NULL, "Data is NULL");
node_info *pNode = data;
if (!strcmp(part, "elm.text")) {
return elm_entry_utf8_to_markup(pNode->name);
}
return NULL;
}
static char *_genlist_widget_storage_label_get(void *data, Evas_Object *obj, const char *part)
{
RETVM_IF(!data, NULL, "Data is NULL");
storage_info *pStorage = data;
if (!strcmp(part, "elm.text")) {
return elm_entry_utf8_to_markup(pStorage->root_name);
}
return NULL;
}