#include "private.h" #include #include #include "config.h" #include "termio.h" #include "media.h" #include "options.h" #include "options_background.h" #include "extns.h" #include "media.h" #include "main.h" #include typedef struct tag_Background_Ctx { Config *config; Evas_Object *frame; Evas_Object *flip; Evas_Object *bg_grid; Evas_Object *term; Evas_Object *entry; Evas_Object *bubble; Evas_Object *op_trans; Evas_Object *op_opacity; Evas_Object *op_shine_slider; Eina_Stringshare *system_path; Eina_Stringshare *user_path; Eina_List *background_list; Ecore_Timer *bubble_disappear; } Background_Ctx; typedef struct tag_Background_Item { const char *path; Eina_Bool selected; Elm_Object_Item *item; } Background_Item; typedef struct tag_Insert_Gen_Grid_Item_Notify { Elm_Gengrid_Item_Class *class; Background_Item *item; } Insert_Gen_Grid_Item_Notify; static void _cb_op_shine_sel(void *data, Evas_Object *obj, void *_event EINA_UNUSED) { Background_Ctx *ctx = data; Config *config = ctx->config; Term *term = termio_term_get(ctx->term); Win *wn = term_win_get(term); int shine = elm_slider_value_get(obj); Eina_List *l, *wn_list; if (config->shine == shine) return; wn_list = win_terms_get(wn); EINA_LIST_FOREACH(wn_list, l, term) { term_apply_shine(term, shine); } } static void _cb_op_video_trans_chg(void *data, Evas_Object *obj, void *_event EINA_UNUSED) { Background_Ctx *ctx = data; Config *config = ctx->config; config->translucent = elm_check_state_get(obj); elm_object_disabled_set(ctx->op_opacity, !config->translucent); config_save(config); main_trans_update(); } static void _cb_op_video_opacity_chg(void *data, Evas_Object *obj, void *_event EINA_UNUSED) { Background_Ctx *ctx = data; Config *config = ctx->config; config->opacity = elm_slider_value_get(obj); if (!config->translucent) return; config_save(config); main_trans_update(); } static void _cb_fileselector(void *data, Evas_Object *obj, void *event) { Background_Ctx *ctx = data; if (event) { elm_object_text_set(ctx->entry, elm_fileselector_path_get(obj)); elm_flip_go_to(ctx->flip, EINA_TRUE, ELM_FLIP_PAGE_LEFT); } else { elm_flip_go_to(ctx->flip, EINA_TRUE, ELM_FLIP_PAGE_LEFT); } } static Eina_Bool _cb_timer_bubble_disappear(void *data) { Background_Ctx *ctx = data; evas_object_del(ctx->bubble); ctx->bubble = NULL; ctx->bubble_disappear = NULL; return ECORE_CALLBACK_CANCEL; } static void _bubble_show(Background_Ctx *ctx, char *text) { Evas_Object *opbox = elm_object_top_widget_get(ctx->bg_grid); Evas_Object *o; int x = 0, y = 0, w , h; evas_object_geometry_get(ctx->bg_grid, &x, &y, &w ,&h); if (ctx->bubble_disappear) { ecore_timer_del(ctx->bubble_disappear); _cb_timer_bubble_disappear(ctx); } ctx->bubble = elm_bubble_add(opbox); elm_bubble_pos_set(ctx->bubble, ELM_BUBBLE_POS_BOTTOM_RIGHT); evas_object_resize(ctx->bubble, 200, 50); evas_object_move(ctx->bubble, (x + w - 200), (y + h - 50)); evas_object_show(ctx->bubble); o = elm_label_add(ctx->bubble); elm_object_text_set(o, text); elm_object_content_set(ctx->bubble, o); ctx->bubble_disappear = ecore_timer_add(2.0, _cb_timer_bubble_disappear, ctx); } static char * _grid_text_get(void *data, Evas_Object *_obj EINA_UNUSED, const char *_part EINA_UNUSED) { Background_Item *item = data; const char *s; if (!item->path) return strdup(_("None")); s = ecore_file_file_get(item->path); if (s) return strdup(s); return NULL; } static Evas_Object * _grid_content_get(void *data, Evas_Object *obj, const char *part) { Background_Ctx *ctx = evas_object_data_get(obj, "ctx"); assert(ctx); Background_Item *item = data; Config *config = ctx->config; if (strcmp(part, "elm.swallow.icon")) return NULL; if (item->path) { Media_Type type; size_t len = strlen(item->path); if (extn_matches(item->path, len, extn_edj)) return media_add(obj, item->path, config, MEDIA_BG, MEDIA_TYPE_EDJE); type = media_src_type_get(item->path, len); return media_add(obj, item->path, config, MEDIA_THUMB, type); } else { Evas_Object *o, *oe; char path[PATH_MAX]; if (!config->theme) return NULL; snprintf(path, PATH_MAX, "%s/themes/%s", elm_app_data_dir_get(), config->theme); o = elm_layout_add(obj); oe = elm_layout_edje_get(o); if (!edje_object_file_set(oe, path, "terminology/background")) { evas_object_del(o); return NULL; } evas_object_show(o); return o; } return NULL; /* unreached */ } static void _item_selected(void *data, Evas_Object *obj, void *_event EINA_UNUSED) { Background_Ctx *ctx = evas_object_data_get(obj, "ctx"); Background_Item *item = data; Config *config = ctx->config; if (!config) return; if (!item->path) { // no background eina_stringshare_del(config->background); config->background = NULL; config_save(config); main_media_update(config); } else if (eina_stringshare_replace(&(config->background), item->path)) { config_save(config); main_media_update(config); } } static void _insert_gengrid_item(Background_Ctx *ctx, Insert_Gen_Grid_Item_Notify *msg_data) { Insert_Gen_Grid_Item_Notify *insert_msg = msg_data; Config *config = ctx->config; if (insert_msg && insert_msg->item && insert_msg->class && config) { Background_Item *item = insert_msg->item; Elm_Gengrid_Item_Class *item_class = insert_msg->class; item->item = elm_gengrid_item_append(ctx->bg_grid, item_class, item, _item_selected, item); if ((!item->path) && (!config->background)) { elm_gengrid_item_selected_set(item->item, EINA_TRUE); elm_gengrid_item_bring_in(item->item, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE); } else if ((item->path) && (config->background)) { if (strcmp(item->path, config->background) == 0) { elm_gengrid_item_selected_set(item->item, EINA_TRUE); elm_gengrid_item_bring_in(item->item, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE); } } } free(msg_data); } static Eina_List* _rec_read_directorys(Background_Ctx *ctx, Eina_List *list, const char *root_path, Elm_Gengrid_Item_Class *class) { Eina_List *childs = ecore_file_ls(root_path); char *file_name, path[PATH_MAX]; Background_Item *item; const char **extns[5] = { extn_img, extn_scale, extn_edj, extn_mov, NULL }; Insert_Gen_Grid_Item_Notify *notify; if (!childs) return list; EINA_LIST_FREE(childs, file_name) { snprintf(path, PATH_MAX, "%s/%s", root_path, file_name); if ((!ecore_file_is_dir(path)) && (file_name[0] != '.')) { int i; size_t len = strlen(file_name); //file is found, search for correct file endings ! for (i = 0; extns[i]; i++) { if (extn_matches(file_name, len, extns[i])) { //File is found and valid item = calloc(1, sizeof(Background_Item)); if (item) { item->path = eina_stringshare_add(path); list = eina_list_append(list, item); notify = calloc(1, sizeof(Insert_Gen_Grid_Item_Notify)); if (notify) { //insert item to gengrid notify->class = class; notify->item = item; //ecore_thread_feedback(th, notify); _insert_gengrid_item(ctx, notify); } } break; } } } free(file_name); } return list; } static void _refresh_directory(Background_Ctx *ctx, const char* data) { Background_Item *item; Elm_Gengrid_Item_Class *item_class; elm_gengrid_clear(ctx->bg_grid); if (ctx->background_list) { EINA_LIST_FREE(ctx->background_list, item) { if (item->path) eina_stringshare_del(item->path); free(item); } ctx->background_list = NULL; } item_class = elm_gengrid_item_class_new(); item_class->func.text_get = _grid_text_get; item_class->func.content_get = _grid_content_get; item = calloc(1, sizeof(Background_Item)); if (!item) { elm_gengrid_item_class_free(item_class); return; } ctx->background_list = eina_list_append(ctx->background_list, item); //Insert None Item Insert_Gen_Grid_Item_Notify *notify = calloc(1, sizeof(Insert_Gen_Grid_Item_Notify)); if (notify) { notify->class = item_class; notify->item = item; _insert_gengrid_item(ctx, notify); } ctx->background_list = _rec_read_directorys(ctx, ctx->background_list, data, item_class); elm_gengrid_item_class_free(item_class); } static void _gengrid_refresh_samples(Background_Ctx *ctx, const char *path) { if(!ecore_file_exists(path)) return; _refresh_directory(ctx, path); } static void _cb_entry_changed(void *data, Evas_Object *parent, void *_event EINA_UNUSED) { Background_Ctx *ctx = data; const char *path = elm_object_text_get(parent); _gengrid_refresh_samples(ctx, path); } static void _cb_hoversel_select(Background_Ctx *ctx, const Eina_Stringshare *path) { if (path) { elm_flip_go_to(ctx->flip, EINA_TRUE, ELM_FLIP_PAGE_LEFT); elm_object_text_set(ctx->entry, path); } else { Evas_Object *o = elm_object_part_content_get(ctx->flip, "back"); elm_fileselector_path_set(o, elm_object_text_get(ctx->entry)); elm_flip_go_to(ctx->flip, EINA_FALSE, ELM_FLIP_PAGE_RIGHT); } } static void _cb_hoversel_select_system(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Background_Ctx *ctx = data; _cb_hoversel_select(ctx, ctx->system_path); } static void _cb_hoversel_select_user(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Background_Ctx *ctx = data; _cb_hoversel_select(ctx, ctx->user_path); } static void _cb_hoversel_select_none(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Background_Ctx *ctx = data; _cb_hoversel_select(ctx, NULL); } static void _system_background_dir_init(Background_Ctx *ctx) { char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/backgrounds/", elm_app_data_dir_get()); if (ctx->system_path) eina_stringshare_replace(&ctx->system_path, path); else ctx->system_path = eina_stringshare_add(path); } static const char* _user_background_dir_init(Background_Ctx *ctx) { char path[PATH_MAX], *user; user = getenv("HOME"); if(!user) return NULL; snprintf(path, PATH_MAX, "%s/.config/terminology/background/", user); if (!ecore_file_exists(path)) ecore_file_mkpath(path); if (!ctx->user_path) ctx->user_path = eina_stringshare_add(path); else eina_stringshare_replace(&ctx->user_path, path); return ctx->user_path; } static const char* _import_background(Background_Ctx *ctx, const char* background) { char path[PATH_MAX]; const char *filename = ecore_file_file_get(background); if (!filename) return NULL; if (!_user_background_dir_init(ctx)) return NULL; snprintf(path, PATH_MAX, "%s/%s", ctx->user_path, filename); if (!ecore_file_cp(background, path)) return NULL; return eina_stringshare_add(path); } static void _cb_grid_doubleclick(void *data, Evas_Object *_obj EINA_UNUSED, void *_event EINA_UNUSED) { Background_Ctx *ctx = data; Config *config = ctx->config; char *config_background_dir = ecore_file_dir_get(config->background); if (!ctx->user_path) { if (!_user_background_dir_init(ctx)) return; } if (!config->background) return; if (strncmp(config_background_dir, ctx->user_path, strlen(config_background_dir)) == 0) { _bubble_show(ctx, _("Source file is target file")); free(config_background_dir); return; } const char *newfile = _import_background(ctx, config->background); if (newfile) { eina_stringshare_replace(&(config->background), newfile); config_save(config); main_media_update(config); eina_stringshare_del(newfile); _bubble_show(ctx, _("Picture imported")); elm_object_text_set(ctx->entry, config_background_dir); } else { _bubble_show(ctx, _("Failed")); } free(config_background_dir); } static void _parent_del_cb(void *data, Evas *_e EINA_UNUSED, Evas_Object *_obj EINA_UNUSED, void *_event_info EINA_UNUSED) { Background_Ctx *ctx = data; Background_Item *item; EINA_LIST_FREE(ctx->background_list, item) { if (item->path) eina_stringshare_del(item->path); free(item); } ctx->background_list = NULL; if (ctx->user_path) { eina_stringshare_del(ctx->user_path); ctx->user_path = NULL; } if (ctx->system_path) { eina_stringshare_del(ctx->system_path); ctx->system_path = NULL; } free(ctx); } void options_background(Evas_Object *opbox, Evas_Object *term) { Evas_Object *o, *bx, *bx_front; Config *config = termio_config_get(term); char path[PATH_MAX]; Background_Ctx *ctx; ctx = calloc(1, sizeof(*ctx)); assert(ctx); ctx->config = config; ctx->term = term; ctx->frame = o = elm_frame_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(o, _("Background")); evas_object_show(o); elm_box_pack_end(opbox, o); evas_object_event_callback_add(ctx->frame, EVAS_CALLBACK_DEL, _parent_del_cb, ctx); bx = o = elm_box_add(ctx->frame); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_content_set(ctx->frame, bx); evas_object_show(o); o = elm_label_add(opbox); evas_object_size_hint_weight_set(o, 0.0, 0.0); evas_object_size_hint_align_set(o, 0.0, 0.5); elm_object_text_set(o, _("Shine:")); elm_box_pack_end(bx, o); evas_object_show(o); ctx->op_shine_slider = o = elm_slider_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); elm_slider_span_size_set(o, 40); elm_slider_unit_format_set(o, "%1.0f"); elm_slider_indicator_format_set(o, "%1.0f"); elm_slider_min_max_set(o, 0, 255); elm_slider_step_set(o, 1); elm_slider_value_set(o, config->shine); elm_box_pack_end(bx, o); evas_object_show(o); evas_object_smart_callback_add(o, "delay,changed", _cb_op_shine_sel, ctx); ctx->op_trans = o = elm_check_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); elm_object_text_set(o, _("Translucent")); elm_check_state_set(o, config->translucent); elm_box_pack_end(bx, o); evas_object_show(o); evas_object_smart_callback_add(o, "changed", _cb_op_video_trans_chg, ctx); ctx->op_opacity = o = elm_slider_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); elm_slider_span_size_set(o, 40); elm_slider_unit_format_set(o, _("%1.0f%%")); elm_slider_indicator_format_set(o, _("%1.0f%%")); elm_slider_min_max_set(o, 0, 100); elm_slider_value_set(o, config->opacity); elm_object_disabled_set(o, !config->translucent); elm_box_pack_end(bx, o); evas_object_show(o); evas_object_smart_callback_add(o, "changed", _cb_op_video_opacity_chg, ctx); o = elm_separator_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); elm_separator_horizontal_set(o, EINA_TRUE); elm_box_pack_end(bx, o); evas_object_show(o); o = elm_hoversel_add(opbox); evas_object_size_hint_weight_set(o, 0.0, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0); elm_object_text_set(o, _("Select Path")); elm_box_pack_end(bx, o); evas_object_show(o); snprintf(path, PATH_MAX, "%s/backgrounds/", elm_app_data_dir_get()); _system_background_dir_init(ctx); elm_hoversel_item_add(o, _("System"), NULL, ELM_ICON_NONE, _cb_hoversel_select_system, ctx); if (_user_background_dir_init(ctx)) elm_hoversel_item_add(o, _("User"), NULL, ELM_ICON_NONE, _cb_hoversel_select_user, ctx); //In the other case it has failed, so dont show the user item elm_hoversel_item_add(o, _("Other"), NULL, ELM_ICON_NONE, _cb_hoversel_select_none, ctx); ctx->flip = o = elm_flip_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_box_pack_end(bx, o); evas_object_show(o); bx_front = o = elm_box_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0); elm_box_horizontal_set(o, EINA_FALSE); elm_object_part_content_set(ctx->flip, "front", o); evas_object_show(o); ctx->entry = o = elm_entry_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0); elm_entry_single_line_set(o, EINA_TRUE); elm_entry_scrollable_set(o, EINA_TRUE); elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); evas_object_smart_callback_add(ctx->entry, "changed", _cb_entry_changed, ctx); elm_box_pack_end(bx_front, o); evas_object_show(o); ctx->bg_grid = o = elm_gengrid_add(opbox); evas_object_data_set(ctx->bg_grid, "ctx", ctx); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_smart_callback_add(o, "clicked,double", _cb_grid_doubleclick, ctx); elm_gengrid_item_size_set(o, elm_config_scale_get() * 100, elm_config_scale_get() * 80); elm_box_pack_end(bx_front, o); evas_object_show(o); o = elm_label_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0); elm_object_text_set(o, _("Click on a picture to use it as background")); elm_label_line_wrap_set(o, ELM_WRAP_WORD); elm_box_pack_end(bx_front, o); evas_object_show(o); o = elm_fileselector_add(opbox); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_part_content_set(ctx->flip, "back", o); elm_fileselector_folder_only_set(o, EINA_TRUE); evas_object_smart_callback_add(o, "done", _cb_fileselector, ctx); evas_object_show(o); if (config->background) { char *config_background_dir; config_background_dir = ecore_file_dir_get(config->background); elm_object_text_set(ctx->entry, config_background_dir); free(config_background_dir); } else { elm_object_text_set(ctx->entry, ctx->system_path); } }