summaryrefslogblamecommitdiffstats
path: root/friendfinder/e_smart_tile.c
blob: 03432417fd90834f205d26dd021e3c0276fe865a (plain) (tree)







































































































































































































































































































                                                                                                                        
#include <stdio.h>
#include <string.h>

#include <Evas.h>
#include <Eet.h>
#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;
}