forked from enlightenment/enventor
369 lines
9.5 KiB
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;
|
|
}
|
|
|