#include #include "config.h" #include "e_mod_main.h" #include "e_mod_config.h" #define SPEED_SLOW 6 #define SPEED_MED 4 #define SPEED_FAST 2 static int MAX_FRAMES = SPEED_SLOW * SPEED_MED * SPEED_FAST; /* module private routines */ static Snow *_snow_init(E_Module *m); static void _snow_shutdown(Snow *snow); static Eina_Bool _snow_cb_animator(void *data); static void _snow_trees_load(Snow *snow); static void _snow_flakes_load(char type, Snow *snow); EAPI E_Module *snow_module = NULL; /* public module routines. all modules must have these */ EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Snow" }; EAPI void * e_modapi_init(E_Module *m) { Snow *snow; char buf[PATH_MAX]; /* Set up module's message catalogue */ snprintf(buf, sizeof(buf), "%s/locale", e_module_dir_get(m)); bindtextdomain(PACKAGE, buf); bind_textdomain_codeset(PACKAGE, "UTF-8"); snprintf(buf, sizeof(buf), "%s/e-module-snow.edj", e_module_dir_get(m)); e_configure_registry_category_add("appearance", 10, D_("Look"), NULL, "preferences-look"); e_configure_registry_item_add("appearance/snow", 150, D_("Snow"), NULL, buf, e_int_config_snow_module); snow = _snow_init(m); snow_module = m; return snow; } EAPI int e_modapi_shutdown(E_Module *m) { Snow *snow; e_configure_registry_item_del("appearance/snow"); e_configure_registry_category_del("appearance"); snow = m->data; if (snow) { if (snow->config_dialog) { e_object_del(E_OBJECT(snow->config_dialog)); snow->config_dialog = NULL; } _snow_shutdown(snow); } return 1; } EAPI int e_modapi_save(E_Module *m) { Snow *snow; if (!(snow = m->data)) return 1; e_config_domain_save("module.snow", snow->conf_edd, snow->conf); return 1; } /* module private routines */ static Snow * _snow_init(E_Module *m) { Snow *snow; E_Zone *zone; Eina_List *zones = NULL, *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); #if E_VERSION_MAJOR >= 20 EINA_LIST_FOREACH(e_comp->zones, l2, zone) { zones = eina_list_append(zones, zone); } #else E_Comp *comp; Eina_List *l; EINA_LIST_FOREACH((Eina_List*)e_comp_list(), l, comp) { EINA_LIST_FOREACH(comp->zones, l2, zone) { zones = eina_list_append(zones, zone); } } #endif // TODO snw->canvas #if E_VERSION_MAJOR >= 20 snow->canvas = e_comp->evas; #else snow->canvas = eina_list_nth(zones, 0)->comp->evas; #endif 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 = eina_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 = eina_list_remove_list(snow->flakes, snow->flakes); free(flake); flake = NULL; } } static void _snow_shutdown(Snow *snow) { free(snow->conf); snow->conf = NULL; E_CONFIG_DD_FREE(snow->conf_edd); _snow_trees_free(snow); _snow_flakes_free(snow); if (snow->animator) ecore_animator_del(snow->animator); free(snow); snow = NULL; } 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_trees_load(Snow *snow) { Evas_Object *o; int tw, th, i; char buf[PATH_MAX]; o = evas_object_image_add(snow->canvas); snprintf(buf, sizeof(buf), "%s/tree.png", e_module_dir_get(snow->module)); 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); snprintf(buf, sizeof(buf), "%s/tree.png", e_module_dir_get(snow->module)); 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_pass_events_set(o, 1); evas_object_show(o); snow->trees = eina_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[PATH_MAX]; 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 * 25)) / (double)th; switch (type) { case 's': flake->speed = SPEED_SLOW; break; case 'm': flake->speed = SPEED_MED; break; case 'l': flake->speed = SPEED_FAST; break; } snow->flakes = eina_list_append(snow->flakes, flake); } } static Eina_Bool _snow_cb_animator(void *data) { Snow *snow; Eina_List *next; Evas_Coord ww; double time; snow = data; evas_output_viewport_get(snow->canvas, NULL, NULL, &ww, NULL); time = ecore_time_get(); next = snow->flakes; while (next) { Snow_Flake *flake; Evas_Coord x, y; int drift; flake = next->data; next = eina_list_next(next); if (snow->frame % flake->speed != 0) continue; switch (rand() % 50) { case 0: drift = -1; break; case 1: case 2: drift = 1; break; default: drift = 0; } evas_object_geometry_get(flake->flake, &x, &y, NULL, NULL); if (++y > snow->height) y = -1 * rand() % 100; if (x + drift >= ww) x = 0; evas_object_move(flake->flake, x + drift, y); } snow->frame++; if (snow->frame > MAX_FRAMES) snow->frame = 0; return EINA_TRUE; } void _snow_cb_config_updated(void *data) { Snow *s; if (!(s = data)) return; _snow_canvas_reset(s); }