#include #include #include #include #include "e_smart_tile.h" static Evas_Smart *get_smart(); static void _tile_object_add(Evas_Object *o); static void _tile_object_del(Evas_Object *o); static void _tile_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y); static void _tile_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h); static void _tile_object_show(Evas_Object *o); static void _tile_object_hide(Evas_Object *o); static void _tile_object_color_set(Evas_Object *o, int r, int g, int b, int a); static void _tile_object_clip_set(Evas_Object *o, Evas_Object *clip); static void _tile_object_clip_unset(Evas_Object *o); #define SMART_TILE_NAME "e_smart_tile" struct smart_tile_data { Evas_Object *obj; Evas_Coord x, y, w, h; Evas_Object *clip; Evas_Object *img; Evas_Object *bg; int offset_x; int offset_y; int scale; struct osm_data osm; }; Evas_Object *e_smart_tile_add(Evas *e) { Evas_Object *o; struct smart_tile_data *smart; o = evas_object_smart_add(e, get_smart()); smart = evas_object_smart_data_get(o); if(smart == NULL) { evas_object_del(o); return NULL; } return o; } struct osm_data *e_smart_tile_unload(Evas_Object *tile) { struct smart_tile_data *data; data = evas_object_smart_data_get(tile); evas_object_hide(data->img); evas_object_show(data->bg); return &(data->osm); } struct osm_data *e_smart_tile_needs_update(Evas_Object *tile, int z, int x, int y) { struct smart_tile_data *data; data = evas_object_smart_data_get(tile); if(data->osm.x == x && data->osm.y == y && data->osm.z == z) return NULL; return &(data->osm); } #define E_LOAD_TRY_AGAIN -1 #define E_LOAD_ERR -2 int load_subtile(struct smart_tile_data *data, const char *path, int x, int y, int z) { char key[512]; int err, _x = x, _y = y; int level; for(level = --z; level > 1; level--) { int __x, __y; data->offset_x += 256 * (_x % 2); data->offset_y += 256 * (_y % 2); __x = _x / 2; __y = _y / 2; data->scale = 2; snprintf(key, 512, "%i/%i/%i", level, __x, __y); evas_object_image_file_set(data->img, path, key); err = evas_object_image_load_error_get(data->img); if (err == EVAS_LOAD_ERROR_NONE) { // printf("fallback image %i,%i,%i of %i,%i\n\n", level, __x, __y, data->offset_x, data->offset_y); return level; } // printf("loading %s failed\n", key); _x = __x; _y = __y; } return -1; } struct osm_data* e_smart_tile_load(Evas_Object *tile, const char *path, int z, int x, int y) { char key[512]; struct smart_tile_data *data; int err; data = evas_object_smart_data_get(tile); if(data->osm.x == x && data->osm.y == y && data->osm.z == z) return &(data->osm); evas_object_hide(data->bg); evas_object_hide(data->img);//XXX data->osm.x = x; data->osm.y = y; data->osm.z = z; data->offset_x = 0; data->offset_y = 0; data->scale = 1; data->x = 0; data->y = 0; snprintf(key, 512, "%i/%i/%i", z, x, y); evas_object_image_file_set(data->img, path, key); err = evas_object_image_load_error_get(data->img); if (err != EVAS_LOAD_ERROR_NONE) { // printf("loading %s failed\n", key); if(load_subtile(data, path, x, y, z) < 0) { // evas_object_show(data->bg); printf("loading %s failed\n", key); return NULL; } } evas_object_image_fill_set(data->img, -data->offset_x, -data->offset_y, 256 * data->scale, 256 * data->scale); evas_object_show(data->img); return &(data->osm); } static void _tile_object_add(Evas_Object *o) { struct smart_tile_data *smart; smart = calloc(1, sizeof(struct smart_tile_data)); if (smart == NULL) return; smart->obj = o; smart->x = 0; smart->y = 0; smart->w = 0; smart->h = 0; smart->osm.x = -1; smart->osm.y = -1; smart->osm.z = -1; smart->scale = 1; smart->offset_x = 0; smart->offset_y = 0; smart->clip = evas_object_rectangle_add(evas_object_evas_get(o)); evas_object_smart_member_add(smart->clip, o); evas_object_color_set(smart->clip, 255, 255, 255, 255); evas_object_move(smart->clip, smart->x, smart->y); evas_object_resize(smart->clip, smart->w, smart->h); smart->bg = evas_object_rectangle_add(evas_object_evas_get(o)); evas_object_smart_member_add(smart->bg, o); evas_object_color_set(smart->bg, 255, 255, 255, 255); evas_object_move(smart->bg, smart->x, smart->y); evas_object_resize(smart->bg, smart->w, smart->h); evas_object_clip_set(smart->bg, smart->clip); smart->img = evas_object_image_add(evas_object_evas_get(o)); evas_object_image_smooth_scale_set(smart->img, 0); evas_object_smart_member_add(smart->img, o); evas_object_clip_set(smart->img, smart->clip); evas_object_move(smart->img, smart->x, smart->y); evas_object_resize(smart->img, smart->w, smart->h); evas_object_image_smooth_scale_set(smart->img, 1); evas_object_show(smart->img); evas_object_smart_data_set(o, smart); } static void _tile_object_del(Evas_Object *o) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); if (smart->img) evas_object_del(smart->img); evas_object_del(smart->clip); evas_object_del(smart->bg); free(smart); } static void _tile_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); smart->x = x; smart->y = y; evas_object_move(smart->clip, smart->x, smart->y); evas_object_move(smart->img, smart->x, smart->y); // evas_object_move(smart->bg, smart->x, smart->y); } static void _tile_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); w *= smart->scale; h *= smart->scale; smart->w = w; smart->h = h; evas_object_resize(smart->clip, smart->w, smart->h); evas_object_resize(smart->img, smart->w, smart->h); evas_object_resize(smart->bg, smart->w, smart->h); evas_object_image_fill_set(smart->img, -smart->offset_x, -smart->offset_y, w, h); } static void _tile_object_show(Evas_Object *o) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); evas_object_show(smart->clip); } static void _tile_object_hide(Evas_Object *o) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); evas_object_hide(smart->clip); } static void _tile_object_color_set(Evas_Object *o, int r, int g, int b, int a) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); evas_object_color_set(smart->clip, r, g, b, a); } static void _tile_object_clip_set(Evas_Object *o, Evas_Object *clip) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); evas_object_clip_set(smart->clip, clip); } static void _tile_object_clip_unset(Evas_Object *o) { struct smart_tile_data *smart; smart = evas_object_smart_data_get(o); evas_object_clip_unset(smart->clip); } static Evas_Smart *get_smart() { static Evas_Smart *e_smart_tile = NULL; if(e_smart_tile != NULL) return e_smart_tile; e_smart_tile = evas_smart_new(SMART_TILE_NAME, _tile_object_add, _tile_object_del, NULL, NULL, NULL, NULL, NULL, _tile_object_move, _tile_object_resize, _tile_object_show, _tile_object_hide, _tile_object_color_set, _tile_object_clip_set, _tile_object_clip_unset, NULL); return e_smart_tile; }