#include "e.h" #include "e_mod_main.h" /* TODO List: * * */ /* module private routines */ static Snow *_snow_init(E_Module *m); static void _snow_shutdown(Snow *snow); static E_Menu *_snow_config_menu_new(Snow *snow); static int _snow_cb_animator(void *data); static void _snow_trees_load(Snow *snow); static void _snow_flakes_load(char type, Snow *snow); static void _snow_cb_density_sparse(void *data, E_Menu *m, E_Menu_Item *mi); static void _snow_cb_density_medium(void *data, E_Menu *m, E_Menu_Item * i); static void _snow_cb_density_dense(void *data, E_Menu *m, E_Menu_Item *mi); static void _snow_cb_show_trees(void *data, E_Menu *m, E_Menu_Item *mi); /* public module routines. all modules must have these */ void * init(E_Module *m) { Snow *snow; if (m->api->version < E_MODULE_API_VERSION) { e_error_dialog_show("Module API Error", "Error initializing Module: Snow\n" "It requires a minimum module API version of: %i.\n" "The module API advertized by Enlightenment is: %i.\n" "Aborting module.", E_MODULE_API_VERSION, m->api->version); return NULL; } snow = _snow_init(m); m->config_menu = _snow_config_menu_new(snow); return snow; } int shutdown(E_Module *m) { Snow *snow; snow = m->data; if (snow) { if (m->config_menu) { e_menu_deactivate(m->config_menu); e_object_del(E_OBJECT(m->config_menu)); m->config_menu = NULL; } _snow_shutdown(snow); } return 1; } int save(E_Module *m) { Snow *snow; snow = m->data; if (!snow) return 1; e_config_domain_save("module.snow", snow->conf_edd, snow->conf); return 1; } int info(E_Module *m) { char buf[4096]; m->label = strdup("Snow"); snprintf(buf, sizeof(buf), "%s/module_icon.png", e_module_dir_get(m)); m->icon_file = strdup(buf); return 1; } int about(E_Module *m) { e_error_dialog_show("Enlightenment Snow Module", "This is a snow module that may replace xsnow."); return 1; } /* module private routines */ static Snow * _snow_init(E_Module *m) { Snow *snow; Evas_List *managers, *l, *l2; snow = calloc(1, sizeof(Snow)); if (!snow) return NULL; snow->module = m; snow->conf_edd = E_CONFIG_DD_NEW("Snow_Config", Config); #undef T #undef D #define T Config #define D snow->conf_edd E_CONFIG_VAL(D, T, tree_count, INT); E_CONFIG_VAL(D, T, flake_count, INT); E_CONFIG_VAL(D, T, show_trees, INT); snow->conf = e_config_domain_load("module.snow", snow->conf_edd); if (!snow->conf) { snow->conf = E_NEW(Config, 1); snow->conf->tree_count = 10; snow->conf->flake_count = 60; snow->conf->show_trees = 1; } E_CONFIG_LIMIT(snow->conf->show_trees, 0, 1); managers = e_manager_list(); for (l = managers; l; l = l->next) { E_Manager *man; man = l->data; for (l2 = man->containers; l2; l2 = l2->next) { E_Container *con; con = l2->data; snow->cons = evas_list_append(snow->cons, con); snow->canvas = con->bg_evas; } } evas_output_viewport_get(snow->canvas, NULL, NULL, &snow->width, &snow->height); if (snow->conf->show_trees) _snow_trees_load(snow); _snow_flakes_load('s', snow); _snow_flakes_load('m', snow); _snow_flakes_load('l', snow); snow->animator = ecore_animator_add(_snow_cb_animator, snow); return snow; } static void _snow_trees_free(Snow *snow) { while (snow->trees) { Evas_Object *tree; tree = snow->trees->data; evas_object_del(tree); snow->trees = evas_list_remove_list(snow->trees, snow->trees); } } static void _snow_flakes_free(Snow *snow) { while (snow->flakes) { Snow_Flake *flake; flake = snow->flakes->data; evas_object_del(flake->flake); snow->flakes = evas_list_remove_list(snow->flakes, snow->flakes); free(flake); } } static void _snow_shutdown(Snow *snow) { free(snow->conf); E_CONFIG_DD_FREE(snow->conf_edd); while (snow->cons) { E_Container *con; con = snow->cons->data; snow->cons = evas_list_remove_list(snow->cons, snow->cons); } _snow_trees_free(snow); _snow_flakes_free(snow); if (snow->animator) ecore_animator_del(snow->animator); free(snow); } static E_Menu * _snow_config_menu_new(Snow *snow) { E_Menu *mn; E_Menu_Item *mi; mn = e_menu_new(); mi = e_menu_item_new(mn); e_menu_item_label_set(mi, "Sparse"); e_menu_item_radio_set(mi, 1); e_menu_item_radio_group_set(mi, 2); if (snow->conf->tree_count == 5) e_menu_item_toggle_set(mi, 1); e_menu_item_callback_set(mi, _snow_cb_density_sparse, snow); mi = e_menu_item_new(mn); e_menu_item_label_set(mi, "Medium"); e_menu_item_radio_set(mi, 1); e_menu_item_radio_group_set(mi, 2); if (snow->conf->tree_count == 10) e_menu_item_toggle_set(mi, 1); e_menu_item_callback_set(mi, _snow_cb_density_medium, snow); mi = e_menu_item_new(mn); e_menu_item_label_set(mi, "Dense"); e_menu_item_radio_set(mi, 1); e_menu_item_radio_group_set(mi, 2); if (snow->conf->tree_count == 20) e_menu_item_toggle_set(mi, 1); e_menu_item_callback_set(mi, _snow_cb_density_dense, snow); mi = e_menu_item_new(mn); e_menu_item_separator_set(mi, 1); mi = e_menu_item_new(mn); e_menu_item_label_set(mi, "Show Trees"); e_menu_item_check_set(mi, 1); e_menu_item_toggle_set(mi, snow->conf->show_trees); e_menu_item_callback_set(mi, _snow_cb_show_trees, snow); return mn; } static void _snow_canvas_reset(Snow *snow) { _snow_trees_free(snow); _snow_flakes_free(snow); if (snow->conf->show_trees) _snow_trees_load(snow); _snow_flakes_load('s', snow); _snow_flakes_load('m', snow); _snow_flakes_load('l', snow); } static void _snow_cb_density_sparse(void *data, E_Menu *m, E_Menu_Item *mi) { Snow *snow; snow = data; snow->conf->tree_count = 5; snow->conf->flake_count = 20; _snow_canvas_reset(snow); } static void _snow_cb_density_medium(void *data, E_Menu *m, E_Menu_Item *mi) { Snow *snow; snow = data; snow->conf->tree_count = 10; snow->conf->flake_count = 60; _snow_canvas_reset(snow); } static void _snow_cb_density_dense(void *data, E_Menu *m, E_Menu_Item *mi) { Snow *snow; snow = data; snow->conf->tree_count = 20; snow->conf->flake_count = 100; _snow_canvas_reset(snow); } static void _snow_cb_show_trees(void *data, E_Menu *m, E_Menu_Item *mi) { Snow *snow; snow = data; snow->conf->show_trees = e_menu_item_toggle_get(mi); _snow_canvas_reset(snow); } static void _snow_trees_load(Snow *snow) { Evas_Object *o; char buf[4096]; int tw, th, i; snprintf(buf, sizeof(buf), "%s/tree.png", e_module_dir_get(snow->module)); o = evas_object_image_add(snow->canvas); evas_object_image_file_set(o, buf, ""); evas_object_image_size_get(o, &tw, &th); for (i = 0; i < snow->conf->tree_count; i++) { Evas_Coord tx, ty; if (i != 0) { o = evas_object_image_add(snow->canvas); evas_object_image_file_set(o, buf, ""); } evas_object_resize(o, tw, th); evas_object_image_alpha_set(o, 1); evas_object_image_fill_set(o, 0, 0, tw, th); tx = random() % (snow->width - tw); ty = random() % (snow->height - th); evas_object_move(o, tx, ty); evas_object_show(o); snow->trees = evas_list_append(snow->trees, o); } } static void _snow_flakes_load(char type, Snow *snow) { Evas_Object *o; Evas_Coord xx, yy, ww, hh; char buf[4096]; int tw, th, i; Snow_Flake *flake; evas_output_viewport_get(snow->canvas, &xx, &yy, &ww, &hh); snprintf(buf, sizeof(buf), "%s/flake-%c.png", e_module_dir_get(snow->module), type); o = evas_object_image_add(snow->canvas); evas_object_image_file_set(o, buf, ""); evas_object_image_size_get(o, &tw, &th); for (i = 0; i < snow->conf->flake_count / 3; i++) { Evas_Coord tx, ty; flake = malloc(sizeof(Snow_Flake)); if (i != 0) { o = evas_object_image_add(snow->canvas); evas_object_image_file_set(o, buf, ""); } evas_object_resize(o, tw, th); evas_object_image_alpha_set(o, 1); evas_object_image_fill_set(o, 0, 0, tw, th); tx = random() % ww; ty = random() % hh; evas_object_move(o, tx, ty); evas_object_show(o); flake->flake = o; flake->start_time = ecore_time_get() + (double)(random() % (th * 10)) / (double) th; switch (type) { case 's': flake->speed = 1; break; case 'm': flake->speed = 2; break; case 'l': flake->speed = 3; break; } snow->flakes = evas_list_append(snow->flakes, flake); } } static int _snow_cb_animator(void *data) { Snow *snow; Evas_List *next; double d; snow = data; next = snow->flakes; while (next) { Snow_Flake *flake; Evas_Coord x, y; flake = next->data; d = ecore_time_get() - flake->start_time; y = 30 * d * flake->speed; evas_object_geometry_get(flake->flake, &x, NULL, NULL, NULL); if (y > snow->height) flake->start_time = ecore_time_get() + (double) (random() % 100) / (double) 100; evas_object_move(flake->flake, x, y); next = evas_list_next(next); } return 1; }