enventor/src/bin/file_tab.c

369 lines
9.5 KiB
C

#include "common.h"
typedef struct file_tab_s
{
Evas_Object *list;
Evas_Object *box;
Elm_Object_Item *selected_it; //list selected item
} file_data;
typedef struct file_tab_it_s
{
Enventor_Item *enventor_it;
Elm_Object_Item *it;
Ecore_Animator *animator;
} file_tab_it;
file_data *g_fd = NULL;
/*****************************************************************************/
/* Internal method implementation */
/*****************************************************************************/
static void
left_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
file_data *fd = data;
Elm_Object_Item *it = elm_list_selected_item_get(fd->list);
//just in case
if (!it) it = elm_list_last_item_get(fd->list);
if (!it) return;
it = elm_list_item_prev(it);
if (!it) return;
elm_list_item_selected_set(it, EINA_TRUE);
elm_list_item_bring_in(it);
}
static void
right_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
file_data *fd = data;
Elm_Object_Item *it = elm_list_selected_item_get(fd->list);
//just in case
if (!it) it = elm_list_first_item_get(fd->list);
if (!it) return;
it = elm_list_item_next(it);
if (!it) return;
elm_list_item_selected_set(it, EINA_TRUE);
elm_list_item_bring_in(it);
}
static Eina_Bool
list_item_anim_cb(void *data)
{
file_tab_it *fti = data;
elm_list_item_bring_in(fti->it);
file_mgr_file_focus(fti->enventor_it);
fti->animator = NULL;
return ECORE_CALLBACK_CANCEL;
}
static void
list_item_selected_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info)
{
file_data *fd = g_fd;
if (!fd) return;
Elm_Object_Item *it = event_info;
if (fd->selected_it == it) return;
//When list item's close button is clicked, this selection is triggered
//prior to the close button clicked callback.
//It's useless to perform this selected callback anyway this file tab
//item is gonna removed soon. But, due to the list's behavior,
//it's unavoidable so we need this tricky animator.
file_tab_it *fti = data;
ecore_animator_del(fti->animator);
fti->animator = ecore_animator_add(list_item_anim_cb, fti);
}
static void
file_tab_it_remove_internal(file_tab_it *fti)
{
Evas_Object *list = elm_object_item_widget_get(fti->it);
//FIXME: If this item is main, then it needs to close project.
//If the focused item is removed, then enable next item.
if (elm_list_selected_item_get(list) == fti->it)
{
//Next?
Elm_Object_Item *it;
it = elm_list_item_next(fti->it);
//Prev?
if (!it) it = elm_list_item_prev(fti->it);
if (it)
{
file_tab_it *next_fti = elm_object_item_data_get(it);
file_mgr_file_focus(next_fti->enventor_it);
}
}
//Remove item.
enventor_item_del(fti->enventor_it);
elm_object_item_del(fti->it);
ecore_animator_del(fti->animator);
free(fti);
elm_list_go(list);
}
static void
close_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
file_tab_it *fti = data;
file_mgr_file_del(fti->enventor_it);
}
/*****************************************************************************/
/* Externally accessible calls */
/*****************************************************************************/
void
file_tab_it_remove(Enventor_Item *enventor_it)
{
file_data *fd = g_fd;
EINA_SAFETY_ON_NULL_RETURN(fd);
Eina_List *list = (Eina_List*) elm_list_items_get(fd->list);
Eina_List *l;
Elm_Object_Item *it;
EINA_LIST_FOREACH(list, l, it)
{
file_tab_it *fti = elm_object_item_data_get(it);
if (fti->enventor_it == enventor_it)
{
file_tab_it_remove_internal(fti);
break;
}
}
}
Eina_Bool
file_tab_it_select(Enventor_Item *enventor_it)
{
file_data *fd = g_fd;
EINA_SAFETY_ON_NULL_RETURN_VAL(fd, EINA_FALSE);
Eina_List *list = (Eina_List*) elm_list_items_get(fd->list);
Eina_List *l;
Elm_Object_Item *it;
EINA_LIST_FOREACH(list, l, it)
{
file_tab_it *fti = elm_object_item_data_get(it);
if (fti->enventor_it != enventor_it) continue;
fd->selected_it = it;
elm_list_item_selected_set(it, EINA_TRUE);
elm_list_item_bring_in(it);
return EINA_TRUE;
}
fd->selected_it = NULL;
return EINA_FALSE;
}
void
file_tab_clear(void)
{
file_data *fd = g_fd;
EINA_SAFETY_ON_NULL_RETURN(fd);
Eina_List *list = (Eina_List*) elm_list_items_get(fd->list);
Eina_List *l;
Elm_Object_Item *it;
EINA_LIST_FOREACH(list, l, it)
{
file_tab_it *fti = elm_object_item_data_get(it);
ecore_animator_del(fti->animator);
free(fti);
}
elm_list_clear(fd->list);
}
Eina_Bool
file_tab_it_add(Enventor_Item *enventor_it)
{
if (!enventor_it)
{
EINA_LOG_ERR("enventor_it = NULL?");
return EINA_FALSE;
}
file_data *fd = g_fd;
if (!fd) return EINA_FALSE;
file_tab_it *fti = NULL;
fti = calloc(1, sizeof(file_tab_it));
if (!fti)
{
mem_fail_msg();
return EINA_FALSE;
}
const char *filepath = enventor_item_file_get(enventor_it);
if (!filepath)
{
EINA_LOG_ERR("No file path??");
goto err;
}
//Filter out file path and just have a file name without extension.
char *filename = ecore_file_strip_ext(ecore_file_file_get(filepath));
if (!filename)
{
EINA_LOG_ERR("no filename??");
goto err;
}
fti->enventor_it = enventor_it;
//Close Button
Evas_Object *btn = elm_button_add(fd->list);
elm_object_style_set(btn, ENVENTOR_NAME);
elm_object_focus_allow_set(btn, EINA_FALSE);
Evas_Object *img = elm_image_add(btn);
elm_image_file_set(img, EDJE_PATH, "close");
elm_object_content_set(btn, img);
fti->it = elm_list_item_append(fd->list, filename, NULL, btn,
list_item_selected_cb, fti);
elm_object_item_tooltip_text_set(fti->it, filepath);
elm_list_go(fd->list);
elm_list_item_bring_in(fti->it);
evas_object_smart_callback_add(btn, "clicked", close_btn_clicked_cb, fti);
free(filename);
return EINA_TRUE;
err:
free(fti);
return EINA_FALSE;
}
void
file_tab_disabled_set(Eina_Bool disabled)
{
file_data *fd = g_fd;
EINA_SAFETY_ON_NULL_RETURN(fd);
elm_object_disabled_set(fd->list, disabled);
if (disabled) return;
//Re-select item. This is a little tricky.
//When we disable a list, its selected item is dismissed.
//So, we manually select the item when list is enabled again.
if (!fd->selected_it) return;
elm_list_item_selected_set(fd->selected_it, EINA_FALSE);
elm_list_item_selected_set(fd->selected_it, EINA_TRUE);
}
Evas_Object *
file_tab_init(Evas_Object *parent)
{
file_data *fd = calloc(1, sizeof(file_data));
if (!fd)
{
mem_fail_msg();
return NULL;
}
g_fd = fd;
//Outer Box
Evas_Object *box = elm_box_add(parent);
elm_box_padding_set(box, ELM_SCALE_SIZE(3), 0);
elm_box_horizontal_set(box, EINA_TRUE);
//Left Button
Evas_Object *left_btn = elm_button_add(box);
elm_object_style_set(left_btn, ENVENTOR_NAME);
elm_object_focus_allow_set(left_btn, EINA_FALSE);
evas_object_size_hint_weight_set(left_btn, 0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(left_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(left_btn, "clicked", left_btn_clicked_cb, fd);
evas_object_show(left_btn);
elm_box_pack_end(box, left_btn);
//Left Button Icon
Evas_Object *img1 = elm_image_add(left_btn);
elm_image_file_set(img1, EDJE_PATH, "left_arrow");
elm_object_content_set(left_btn, img1);
//Right Button
Evas_Object *right_btn = elm_button_add(box);
elm_object_style_set(right_btn, ENVENTOR_NAME);
elm_object_focus_allow_set(right_btn, EINA_FALSE);
evas_object_size_hint_weight_set(right_btn, 0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(right_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(right_btn, "clicked",
right_btn_clicked_cb, fd);
evas_object_show(right_btn);
elm_box_pack_end(box, right_btn);
//Right Button Icon
Evas_Object *img2 = elm_image_add(right_btn);
elm_image_file_set(img2, EDJE_PATH, "right_arrow");
elm_object_content_set(right_btn, img2);
//List
Evas_Object *list = elm_list_add(box);
elm_object_style_set(list, ENVENTOR_NAME);
elm_object_focus_allow_set(list, EINA_FALSE);
elm_list_horizontal_set(list, EINA_TRUE);
elm_scroller_policy_set(list, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_OFF);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND,
EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(list);
elm_box_pack_end(box, list);
fd->box = box;
fd->list = list;
return box;
}
void
file_tab_term(void)
{
file_data *fd = g_fd;
EINA_SAFETY_ON_NULL_RETURN(fd);
file_tab_it *fti;
Eina_List *l;
Elm_Object_Item *it;
Eina_List *children = (Eina_List *)elm_list_items_get(fd->list);
EINA_LIST_FOREACH(children, l, it)
{
fti = elm_object_item_data_get(it);
ecore_animator_del(fti->animator);
free(fti);
}
evas_object_del(fd->box);
free(fd);
g_fd = NULL;
}