2009-11-13 07:22:23 -08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
|
|
|
#include <Elementary.h>
|
|
|
|
#include "elm_priv.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup Map Map
|
|
|
|
*
|
|
|
|
* This is a widget specifically for displaying the free map OpenStreetMap.
|
|
|
|
*
|
|
|
|
* Signals that you can add callbacks for are:
|
|
|
|
*
|
|
|
|
* clicked - This is called when a user has clicked the map without dragging
|
|
|
|
* around.
|
|
|
|
*
|
|
|
|
* press - This is called when a user has pressed down on the map.
|
|
|
|
*
|
|
|
|
* longpressed - This is called when a user has pressed down on the map for
|
|
|
|
* a long time without dragging around.
|
|
|
|
*
|
|
|
|
* clicked,double - This is called when a user has double-clicked the photo.
|
|
|
|
*
|
|
|
|
* load,details - Map detailed data load begins.
|
|
|
|
*
|
|
|
|
* loaded,details - This is called when all parts of the map are loaded.
|
|
|
|
*
|
|
|
|
* zoom,start - Zoom animation started.
|
|
|
|
*
|
|
|
|
* zoom,stop - Zoom animation stopped.
|
|
|
|
*
|
|
|
|
* zoom,change - Zoom changed when using an auto zoom mode.
|
|
|
|
*
|
|
|
|
* scroll - the content has been scrolled (moved)
|
|
|
|
*
|
|
|
|
* scroll,anim,start - scrolling animation has started
|
|
|
|
*
|
|
|
|
* scroll,anim,stop - scrolling animation has stopped
|
|
|
|
*
|
|
|
|
* scroll,drag,start - dragging the contents around has started
|
|
|
|
*
|
|
|
|
* scroll,drag,stop - dragging the contents around has stopped
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct _Widget_Data Widget_Data;
|
|
|
|
typedef struct _Pan Pan;
|
|
|
|
typedef struct _Grid Grid;
|
|
|
|
typedef struct _Grid_Item Grid_Item;
|
2009-11-15 07:53:37 -08:00
|
|
|
typedef struct _Marker_Group Marker_Group;
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
#define SOURCE_PATH "http://tile.openstreetmap.org/%d/%d/%d.png"
|
|
|
|
#define DEST_DIR_ZOOM_PATH "/tmp/elm_map/%d/"
|
|
|
|
#define DEST_DIR_PATH DEST_DIR_ZOOM_PATH"%d/"
|
|
|
|
#define DEST_FILE_PATH "%s%d.png"
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
struct _Elm_Map_Marker
|
|
|
|
{
|
|
|
|
Widget_Data *wd;
|
2009-11-18 02:59:17 -08:00
|
|
|
Elm_Map_Marker_Class *clas;
|
2009-11-15 07:53:37 -08:00
|
|
|
double longitude, latitude;
|
|
|
|
|
|
|
|
Evas_Coord map_size;
|
|
|
|
Evas_Coord x[19], y[19];
|
|
|
|
void *data;
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
Marker_Group *groups[19];
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Object *content;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _Marker_Group
|
|
|
|
{
|
|
|
|
Widget_Data *wd;
|
2009-12-18 06:28:36 -08:00
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
Eina_List *markers;
|
2009-11-17 07:44:11 -08:00
|
|
|
long long sum_x, sum_y;
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Coord x, y;
|
|
|
|
Evas_Coord w, h;
|
2009-11-15 08:24:02 -08:00
|
|
|
Evas_Object *obj, *bubble, *sc, *bx, *rect;
|
2009-11-15 07:53:37 -08:00
|
|
|
Eina_Bool open : 1;
|
2009-11-15 11:52:07 -08:00
|
|
|
Eina_Bool bringin : 1;
|
2009-12-18 12:16:37 -08:00
|
|
|
Eina_Bool update_nbelems : 1;
|
2009-11-15 07:53:37 -08:00
|
|
|
};
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
struct _Grid_Item
|
|
|
|
{
|
|
|
|
Widget_Data *wd;
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Object *img;
|
|
|
|
//Evas_Object *txt;
|
2009-11-14 05:58:22 -08:00
|
|
|
const char *file;
|
2009-11-13 07:22:23 -08:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
int x, y, w, h;
|
|
|
|
} src, out;
|
|
|
|
Eina_Bool want : 1;
|
|
|
|
Eina_Bool download : 1;
|
|
|
|
Eina_Bool have : 1;
|
2009-11-13 09:34:20 -08:00
|
|
|
Ecore_File_Download_Job *job;
|
2009-11-14 05:58:22 -08:00
|
|
|
int try_num;
|
2009-11-13 07:22:23 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _Grid
|
|
|
|
{
|
|
|
|
Widget_Data *wd;
|
|
|
|
int tsize; // size of tile (tsize x tsize pixels)
|
|
|
|
int zoom; // zoom level tiles want for optimal display (1, 2, 4, 8)
|
|
|
|
int iw, ih; // size of image in pixels
|
|
|
|
int w, h; // size of grid image in pixels (represented by grid)
|
|
|
|
int gw, gh; // size of grid in tiles
|
|
|
|
Eina_Matrixsparse *grid;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _Widget_Data
|
|
|
|
{
|
|
|
|
Evas_Object *obj;
|
|
|
|
Evas_Object *scr;
|
|
|
|
Evas_Object *pan_smart;
|
|
|
|
Evas_Object *rect;
|
|
|
|
Pan *pan;
|
|
|
|
Evas_Coord pan_x, pan_y, minw, minh;
|
|
|
|
|
|
|
|
int zoom;
|
|
|
|
Elm_Map_Zoom_Mode mode;
|
|
|
|
|
|
|
|
Ecore_Job *calc_job;
|
|
|
|
Ecore_Timer *scr_timer;
|
|
|
|
Ecore_Timer *long_timer;
|
|
|
|
Ecore_Animator *zoom_animator;
|
|
|
|
double t_start, t_end;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
int ow, oh, nw, nh;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
double x, y;
|
|
|
|
} spos;
|
|
|
|
} size;
|
2009-11-17 07:44:11 -08:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
Eina_Bool show : 1;
|
|
|
|
Evas_Coord x, y ,w ,h;
|
|
|
|
} show;
|
2009-11-13 07:22:23 -08:00
|
|
|
int tsize;
|
|
|
|
int nosmooth;
|
|
|
|
int preload_num;
|
|
|
|
Eina_List *grids;
|
|
|
|
Eina_Bool resized : 1;
|
|
|
|
Eina_Bool longpressed : 1;
|
|
|
|
Eina_Bool on_hold : 1;
|
|
|
|
Eina_Bool paused : 1;
|
2009-12-18 13:28:06 -08:00
|
|
|
Eina_Bool paused_markers : 1;
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-15 13:36:44 -08:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
Eina_Bool enabled;
|
|
|
|
double lon, lat;
|
|
|
|
} center_on;
|
|
|
|
|
2009-11-16 13:32:33 -08:00
|
|
|
Ecore_Job *markers_place_job;
|
2009-12-18 06:28:36 -08:00
|
|
|
Eina_Matrixsparse *markers[19];
|
2009-12-18 09:45:47 -08:00
|
|
|
Eina_List *cells_displayed; // list of Eina_Matrixsparse_Cell
|
2009-11-18 13:07:01 -08:00
|
|
|
Evas_Coord markers_max_num;
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Coord marker_w, marker_h;
|
|
|
|
Evas_Coord marker_max_w, marker_max_h;
|
|
|
|
int marker_zoom;
|
2009-11-21 14:38:07 -08:00
|
|
|
Eina_List *opened_bubbles; //opened bubbles, list of Map_Group *
|
2009-12-18 09:00:01 -08:00
|
|
|
Eina_List *group_objs_used;
|
|
|
|
Eina_List *group_objs_notused;
|
2009-11-13 07:22:23 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _Pan
|
|
|
|
{
|
|
|
|
Evas_Object_Smart_Clipped_Data __clipped_data;
|
|
|
|
Widget_Data *wd;
|
|
|
|
};
|
|
|
|
|
2009-11-17 07:44:11 -08:00
|
|
|
|
|
|
|
static void _pan_calculate(Evas_Object *obj);
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
static void _del_hook(Evas_Object *obj);
|
|
|
|
static void _theme_hook(Evas_Object *obj);
|
|
|
|
static void _sizing_eval(Evas_Object *obj);
|
|
|
|
static void _calc_job(void *data);
|
|
|
|
static void grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
|
|
|
|
static void grid_clear(Evas_Object *obj, Grid *g);
|
|
|
|
static Grid *grid_create(Evas_Object *obj);
|
|
|
|
static void grid_load(Evas_Object *obj, Grid *g);
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-21 14:38:07 -08:00
|
|
|
static void _group_object_create(Marker_Group *group);
|
|
|
|
static void _group_object_free(Marker_Group *group);
|
2009-11-15 07:53:37 -08:00
|
|
|
static void _group_open_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
|
2009-11-15 11:52:07 -08:00
|
|
|
static void _group_bringin_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
|
2009-11-15 07:53:37 -08:00
|
|
|
static void _group_bubble_create(Marker_Group *group);
|
|
|
|
static void _group_bubble_free(Marker_Group *group);
|
|
|
|
static void _group_bubble_place(Marker_Group *group);
|
|
|
|
|
|
|
|
static void _group_bubble_content_update(Marker_Group *group);
|
|
|
|
static void _group_bubble_content_free(Marker_Group *group);
|
|
|
|
static void marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
|
2009-11-16 13:32:33 -08:00
|
|
|
static void _bubble_sc_hits_changed_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-11-17 07:44:11 -08:00
|
|
|
Evas_Coord ax, ay, gw, gh, hh, ww;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-11-17 07:44:11 -08:00
|
|
|
evas_object_geometry_get(wd->rect, NULL, NULL, &ww, &hh);
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
ax = 0;
|
|
|
|
ay = 0;
|
|
|
|
gw = wd->size.w;
|
|
|
|
gh = wd->size.h;
|
2009-11-17 07:44:11 -08:00
|
|
|
|
|
|
|
if(ww == gw && hh == gh) return ;
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
if (ow > gw) ax = (ow - gw) / 2;
|
|
|
|
if (oh > gh) ay = (oh - gh) / 2;
|
|
|
|
evas_object_move(wd->rect,
|
|
|
|
ox + 0 - px + ax,
|
|
|
|
oy + 0 - py + ay);
|
|
|
|
evas_object_resize(wd->rect, gw, gh);
|
2009-11-17 07:44:11 -08:00
|
|
|
|
|
|
|
if(wd->show.show)
|
|
|
|
{
|
|
|
|
wd->show.show = EINA_FALSE;
|
|
|
|
elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
|
|
|
|
}
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord ax, ay, gw, gh, tx, ty;
|
2009-12-18 12:16:37 -08:00
|
|
|
Eina_List *l, *markers;
|
2009-12-18 09:45:47 -08:00
|
|
|
Eina_Matrixsparse_Cell *cell;
|
2009-11-15 07:53:37 -08:00
|
|
|
Marker_Group *group;
|
|
|
|
int xx, yy, ww, hh;
|
|
|
|
char buf[PATH_MAX];
|
2009-12-18 06:28:36 -08:00
|
|
|
int y, x;
|
|
|
|
int g_xx, g_yy, g_hh, g_ww;
|
|
|
|
int mi_start, mj_start, mi_end, mj_end;
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
if(g != eina_list_data_get(wd->grids)) return ;
|
|
|
|
|
|
|
|
ax = 0;
|
|
|
|
ay = 0;
|
|
|
|
gw = wd->size.w;
|
|
|
|
gh = wd->size.h;
|
|
|
|
if (ow > gw) ax = (ow - gw) / 2;
|
|
|
|
if (oh > gh) ay = (oh - gh) / 2;
|
|
|
|
|
|
|
|
if(wd->zoom != wd->marker_zoom)
|
|
|
|
{
|
2009-12-18 09:45:47 -08:00
|
|
|
EINA_LIST_FREE(wd->cells_displayed, cell)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 12:16:37 -08:00
|
|
|
EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 09:45:47 -08:00
|
|
|
if(group->obj)
|
|
|
|
_group_object_free(group);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wd->marker_zoom = wd->zoom;
|
|
|
|
|
2009-12-18 13:28:06 -08:00
|
|
|
if(wd->paused_markers
|
|
|
|
&& (wd->size.nw != wd->size.w || wd->size.nh != wd->size.h) )
|
|
|
|
return ;
|
2009-12-18 09:45:47 -08:00
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
g_xx = wd->pan_x / wd->tsize;
|
|
|
|
if(g_xx < 0) g_xx = 0;
|
|
|
|
|
|
|
|
g_yy = wd->pan_y / wd->tsize;
|
|
|
|
if(g_yy < 0) g_yy = 0;
|
|
|
|
|
|
|
|
g_ww = ow / wd->tsize + 1;
|
|
|
|
if(g_xx + g_ww >= g->gw) g_ww = g->gw - g_xx - 1;
|
|
|
|
|
|
|
|
g_hh = oh / wd->tsize + 1;
|
|
|
|
if(g_yy + g_hh >= g->gh) g_hh = g->gh - g_yy - 1;
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
//hide groups no more displayed
|
|
|
|
EINA_LIST_FREE(wd->cells_displayed, cell)
|
|
|
|
{
|
|
|
|
eina_matrixsparse_cell_position_get(cell, (unsigned long *)&y, (unsigned long *)&x);
|
|
|
|
if(y < g_yy || y > g_yy + g_hh || x < g_xx || x > g_xx + g_ww)
|
|
|
|
{
|
2009-12-18 12:16:37 -08:00
|
|
|
EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
|
2009-12-18 09:45:47 -08:00
|
|
|
{
|
|
|
|
if(group->obj)
|
|
|
|
_group_object_free(group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
for (y = g_yy; y <= g_yy + g_hh; y++)
|
|
|
|
{
|
|
|
|
for (x = g_xx; x <= g_xx + g_ww; x++)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 10:30:28 -08:00
|
|
|
if(!wd->markers[wd->zoom])
|
|
|
|
continue ;
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
eina_matrixsparse_cell_idx_get(wd->markers[wd->zoom], y, x, &cell);
|
|
|
|
if(!cell)
|
|
|
|
continue ;
|
|
|
|
wd->cells_displayed = eina_list_append(wd->cells_displayed, cell);
|
|
|
|
|
2009-12-18 12:16:37 -08:00
|
|
|
markers = eina_matrixsparse_cell_data_get(cell);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
int i = 0;
|
|
|
|
EINA_LIST_FOREACH(markers, l, group)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
if(!group->markers) continue ;
|
|
|
|
|
|
|
|
xx = group->x;
|
|
|
|
yy = group->y;
|
|
|
|
ww = group->w;
|
|
|
|
hh = group->h;
|
|
|
|
|
|
|
|
if(ww<=0) ww = 1;
|
|
|
|
if(hh<=0) hh = 1;
|
|
|
|
|
|
|
|
if ((gw != g->w) && (g->w > 0))
|
|
|
|
{
|
|
|
|
tx = xx;
|
|
|
|
xx = ((long long )gw * xx) / g->w;
|
|
|
|
ww = (((long long)gw * (tx + ww)) / g->w) - xx;
|
|
|
|
}
|
|
|
|
if ((gh != g->h) && (g->h > 0))
|
|
|
|
{
|
|
|
|
ty = yy;
|
|
|
|
yy = ((long long)gh * yy) / g->h;
|
|
|
|
hh = (((long long)gh * (ty + hh)) / g->h) - yy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(xx-px+ax+ox >= ox && xx-px+ax+ox<= ox+ow
|
|
|
|
&& yy-py+ay+oy >= oy && yy-py+ay+oy<= oy+oh)
|
|
|
|
{
|
|
|
|
if(!group->obj)
|
|
|
|
_group_object_create(group);
|
|
|
|
|
2009-12-18 12:16:37 -08:00
|
|
|
if(group->update_nbelems)
|
2009-12-18 06:28:36 -08:00
|
|
|
{
|
2009-12-18 12:16:37 -08:00
|
|
|
group->update_nbelems = EINA_FALSE;
|
|
|
|
if(eina_list_count(group->markers) > 1)
|
|
|
|
{
|
|
|
|
snprintf(buf, PATH_MAX, "%d", eina_list_count(group->markers));
|
|
|
|
edje_object_part_text_set(group->obj, "elm.text", buf);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
edje_object_part_text_set(group->obj, "elm.text", "");
|
2009-12-18 06:28:36 -08:00
|
|
|
}
|
2009-12-18 09:00:01 -08:00
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
evas_object_move(group->obj,
|
|
|
|
xx - px + ax + ox - ww/2,
|
|
|
|
yy - py + ay + oy - hh/2);
|
|
|
|
evas_object_resize(group->obj, ww, hh);
|
|
|
|
evas_object_raise(group->obj);
|
|
|
|
evas_object_show(group->obj);
|
|
|
|
|
|
|
|
if(group->bubble)
|
|
|
|
_group_bubble_place(group);
|
|
|
|
}
|
|
|
|
else if(group->obj)
|
|
|
|
{
|
|
|
|
_group_object_free(group);
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord ax, ay, gw, gh, tx, ty;
|
|
|
|
int xx, yy, ww, hh;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
ax = 0;
|
|
|
|
ay = 0;
|
|
|
|
gw = wd->size.w;
|
|
|
|
gh = wd->size.h;
|
|
|
|
if (ow > gw) ax = (ow - gw) / 2;
|
|
|
|
if (oh > gh) ay = (oh - gh) / 2;
|
|
|
|
|
|
|
|
Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
|
|
|
|
xx = gi->out.x;
|
|
|
|
yy = gi->out.y;
|
|
|
|
ww = gi->out.w;
|
|
|
|
hh = gi->out.h;
|
|
|
|
if ((gw != g->w) && (g->w > 0))
|
|
|
|
{
|
|
|
|
tx = xx;
|
|
|
|
xx = ((long long )gw * xx) / g->w;
|
|
|
|
ww = (((long long)gw * (tx + ww)) / g->w) - xx;
|
|
|
|
}
|
|
|
|
if ((gh != g->h) && (g->h > 0))
|
|
|
|
{
|
|
|
|
ty = yy;
|
|
|
|
yy = ((long long)gh * yy) / g->h;
|
|
|
|
hh = (((long long)gh * (ty + hh)) / g->h) - yy;
|
|
|
|
}
|
|
|
|
evas_object_move(gi->img,
|
|
|
|
xx - px + ax + ox,
|
|
|
|
yy - py + ay + oy);
|
|
|
|
|
|
|
|
evas_object_resize(gi->img, ww, hh);
|
2009-11-14 07:30:03 -08:00
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
/*evas_object_move(gi->txt,
|
|
|
|
xx - px + ax + ox,
|
|
|
|
yy - py + ay + oy);
|
2009-11-14 07:30:03 -08:00
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
evas_object_resize(gi->txt, ww, hh);
|
|
|
|
*/
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
eina_iterator_free(it);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
grid_clear(Evas_Object *obj, Grid *g)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
|
|
|
if (!g->grid) return;
|
|
|
|
|
|
|
|
Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
|
|
|
snprintf(buf, PATH_MAX, DEST_DIR_ZOOM_PATH, g->zoom);
|
|
|
|
ecore_file_recursive_rm(buf);
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
evas_object_del(gi->img);
|
2009-11-15 07:53:37 -08:00
|
|
|
//evas_object_del(gi->txt);
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
if (gi->want)
|
|
|
|
{
|
|
|
|
gi->want = EINA_FALSE;
|
|
|
|
wd->preload_num--;
|
|
|
|
if (wd->preload_num == 0)
|
|
|
|
{
|
|
|
|
edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
|
|
|
|
"elm,state,busy,stop", "elm");
|
|
|
|
evas_object_smart_callback_call(obj, "loaded,detail", NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-13 09:34:20 -08:00
|
|
|
if(gi->job)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
2009-11-14 05:58:22 -08:00
|
|
|
DBG("DOWNLOAD abort %s", gi->file);
|
2009-11-13 09:34:20 -08:00
|
|
|
ecore_file_download_abort(gi->job);
|
2009-12-19 11:12:08 -08:00
|
|
|
ecore_file_remove(gi->file);
|
2009-11-13 10:42:58 -08:00
|
|
|
gi->job = NULL;
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
2009-11-14 05:58:22 -08:00
|
|
|
if(gi->file)
|
|
|
|
eina_stringshare_del(gi->file);
|
|
|
|
|
2009-11-13 09:34:20 -08:00
|
|
|
free(gi);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
eina_matrixsparse_free(g->grid);
|
2009-11-15 07:53:37 -08:00
|
|
|
eina_iterator_free(it);
|
2009-11-13 07:22:23 -08:00
|
|
|
g->grid = NULL;
|
|
|
|
g->gw = 0;
|
|
|
|
g->gh = 0;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-14 07:30:03 -08:00
|
|
|
_tile_update(Grid_Item *gi)
|
|
|
|
{
|
|
|
|
gi->want = EINA_FALSE;
|
2009-11-15 07:53:37 -08:00
|
|
|
gi->download = EINA_FALSE;
|
2009-11-14 07:30:03 -08:00
|
|
|
evas_object_image_file_set(gi->img, gi->file, NULL);
|
2009-11-15 11:52:07 -08:00
|
|
|
if( evas_object_image_load_error_get(gi->img) != EVAS_LOAD_ERROR_NONE )
|
2009-12-19 11:12:08 -08:00
|
|
|
ecore_file_remove(gi->file);
|
2009-11-15 11:52:07 -08:00
|
|
|
|
2009-11-14 07:30:03 -08:00
|
|
|
evas_object_show(gi->img);
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
//evas_object_text_text_set(gi->txt, gi->file);
|
|
|
|
//evas_object_show(gi->txt);
|
2009-11-14 07:30:03 -08:00
|
|
|
|
|
|
|
gi->have = EINA_TRUE;
|
|
|
|
gi->wd->preload_num--;
|
|
|
|
if (gi->wd->preload_num == 0)
|
|
|
|
{
|
|
|
|
edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr),
|
|
|
|
"elm,state,busy,stop", "elm");
|
|
|
|
evas_object_smart_callback_call(gi->wd->obj, "loaded,detail", NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_tile_downloaded(void *data, const char *file, int status)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = data;
|
|
|
|
|
|
|
|
gi->download = EINA_FALSE;
|
2009-11-13 09:34:20 -08:00
|
|
|
gi->job = NULL;
|
|
|
|
|
2009-11-14 05:58:22 -08:00
|
|
|
DBG("DOWNLOAD done %s", gi->file);
|
|
|
|
if (gi->want && !status)
|
2009-11-15 07:53:37 -08:00
|
|
|
_tile_update(gi);
|
2009-11-14 05:58:22 -08:00
|
|
|
|
|
|
|
if(status)
|
2009-11-15 11:52:07 -08:00
|
|
|
{
|
2009-11-25 12:51:28 -08:00
|
|
|
DBG("Download failed %s (%d) ", gi->file, status);
|
2009-12-19 11:12:08 -08:00
|
|
|
ecore_file_remove(gi->file);
|
2009-11-15 11:52:07 -08:00
|
|
|
}
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Grid *
|
|
|
|
grid_create(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Grid *g;
|
|
|
|
|
|
|
|
g = calloc(1, sizeof(Grid));
|
|
|
|
|
|
|
|
g->zoom = wd->zoom;
|
|
|
|
g->tsize = wd->tsize;
|
|
|
|
g->wd = wd;
|
|
|
|
|
|
|
|
if (g->zoom > 18) return NULL;
|
|
|
|
|
|
|
|
int size = pow(2.0, wd->zoom);
|
|
|
|
g->gw = size;
|
|
|
|
g->gh = size;
|
|
|
|
|
|
|
|
g->w = g->tsize * g->gw;
|
|
|
|
g->h = g->tsize * g->gh;
|
|
|
|
|
|
|
|
g->grid = eina_matrixsparse_new(g->gh, g->gw, NULL, NULL);
|
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
grid_load(Evas_Object *obj, Grid *g)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
int x, y;
|
|
|
|
int size;
|
|
|
|
Evas_Coord ow, oh, tx, ty, gw, gh, xx, yy, ww, hh;
|
|
|
|
Eina_Iterator *it;
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
Grid_Item *gi;
|
|
|
|
|
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &ow, &oh);
|
|
|
|
|
|
|
|
gw = wd->size.w;
|
|
|
|
gh = wd->size.h;
|
|
|
|
|
|
|
|
if(gw <= 0 || gh <= 0) return ;
|
|
|
|
|
|
|
|
size = g->tsize;
|
|
|
|
if ((gw != g->w) && (g->w > 0))
|
|
|
|
size = ((long long)gw * size) / g->w;
|
2009-11-14 05:58:22 -08:00
|
|
|
if(size < g->tsize / 2) return; // else we will load to much tiles
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
|
|
|
|
it = eina_matrixsparse_iterator_new(g->grid);
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
|
|
|
|
xx = gi->out.x;
|
|
|
|
yy = gi->out.y;
|
|
|
|
ww = gi->out.w;
|
|
|
|
hh = gi->out.h;
|
|
|
|
|
|
|
|
if ((gw != g->w) && (g->w > 0))
|
|
|
|
{
|
|
|
|
tx = xx;
|
|
|
|
xx = ((long long )gw * xx) / g->w;
|
|
|
|
ww = (((long long)gw * (tx + ww)) / g->w) - xx;
|
|
|
|
}
|
|
|
|
if ((gh != g->h) && (g->h > 0))
|
|
|
|
{
|
|
|
|
ty = yy;
|
|
|
|
yy = ((long long)gh * yy) / g->h;
|
|
|
|
hh = (((long long)gh * (ty + hh)) / g->h) - yy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(! ELM_RECTS_INTERSECT( wd->pan_x, wd->pan_y, ow, oh,
|
|
|
|
xx, yy, ww, hh) )
|
|
|
|
{
|
|
|
|
if (gi->want)
|
|
|
|
{
|
|
|
|
wd->preload_num--;
|
|
|
|
if (wd->preload_num == 0)
|
|
|
|
{
|
|
|
|
edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
|
|
|
|
"elm,state,busy,stop", "elm");
|
|
|
|
evas_object_smart_callback_call(obj, "loaded,detail", NULL);
|
|
|
|
}
|
|
|
|
evas_object_hide(gi->img);
|
2009-11-14 07:30:03 -08:00
|
|
|
//evas_object_hide(gi->txt);
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_image_file_set(gi->img, NULL, NULL);
|
|
|
|
gi->want = EINA_FALSE;
|
|
|
|
gi->have = EINA_FALSE;
|
2009-11-13 10:42:58 -08:00
|
|
|
|
|
|
|
if(gi->job)
|
|
|
|
{
|
2009-11-14 05:58:22 -08:00
|
|
|
DBG("DOWNLOAD abort %s", gi->file);
|
2009-11-13 10:42:58 -08:00
|
|
|
ecore_file_download_abort(gi->job);
|
2009-12-19 11:12:08 -08:00
|
|
|
ecore_file_remove(gi->file);
|
2009-11-13 10:42:58 -08:00
|
|
|
gi->job = NULL;
|
|
|
|
}
|
2009-11-14 05:58:22 -08:00
|
|
|
gi->download = EINA_FALSE;
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
else if (gi->have)
|
|
|
|
{
|
|
|
|
evas_object_hide(gi->img);
|
2009-11-14 07:30:03 -08:00
|
|
|
//evas_object_hide(gi->txt);
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_image_preload(gi->img, 1);
|
|
|
|
evas_object_image_file_set(gi->img, NULL, NULL);
|
|
|
|
gi->have = EINA_FALSE;
|
|
|
|
gi->want = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
eina_iterator_free(it);
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
xx = wd->pan_x / size;
|
2009-11-13 07:22:23 -08:00
|
|
|
if(xx < 0) xx = 0;
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
yy = wd->pan_y / size;
|
2009-11-13 07:22:23 -08:00
|
|
|
if(yy < 0) yy = 0;
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
ww = ow / size + 1;
|
|
|
|
if(xx + ww >= g->gw) ww = g->gw - xx - 1;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
hh = oh / size + 1;
|
|
|
|
if(yy + hh >= g->gh) hh = g->gh - yy - 1;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-11-17 07:44:11 -08:00
|
|
|
for (y = yy; y <= yy + hh; y++)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
2009-11-17 07:44:11 -08:00
|
|
|
for (x = xx; x <= xx + ww; x++)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
|
|
|
|
|
|
|
|
if(!gi && g != eina_list_data_get(wd->grids))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if(!gi)
|
|
|
|
{
|
|
|
|
gi = calloc(1, sizeof(Grid_Item));
|
|
|
|
gi->src.x = x * g->tsize;
|
|
|
|
gi->src.y = y * g->tsize;
|
|
|
|
gi->src.w = g->tsize;
|
|
|
|
gi->src.h = g->tsize;
|
|
|
|
|
|
|
|
gi->out.x = gi->src.x;
|
|
|
|
gi->out.y = gi->src.y;
|
|
|
|
gi->out.w = gi->src.w;
|
|
|
|
gi->out.h = gi->src.h;
|
|
|
|
|
|
|
|
gi->wd = wd;
|
2009-11-14 07:30:03 -08:00
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
gi->img = evas_object_image_add(evas_object_evas_get(obj));
|
|
|
|
evas_object_image_scale_hint_set
|
|
|
|
(gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
|
|
|
|
evas_object_image_filled_set(gi->img, 1);
|
|
|
|
|
|
|
|
evas_object_smart_member_add(gi->img,
|
|
|
|
wd->pan_smart);
|
|
|
|
elm_widget_sub_object_add(obj, gi->img);
|
|
|
|
evas_object_pass_events_set(gi->img, 1);
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
/*gi->txt = evas_object_text_add(evas_object_evas_get(obj));
|
|
|
|
evas_object_text_font_set(gi->txt, "Vera", 12);
|
|
|
|
evas_object_color_set(gi->txt, 100, 100, 100, 255);
|
|
|
|
evas_object_smart_member_add(gi->txt,
|
|
|
|
wd->pan_smart);
|
|
|
|
elm_widget_sub_object_add(obj, gi->txt);
|
|
|
|
evas_object_pass_events_set(gi->txt, 1);
|
|
|
|
*/
|
2009-11-13 07:22:23 -08:00
|
|
|
eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gi->have && !gi->download)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX], buf2[PATH_MAX];
|
|
|
|
|
|
|
|
gi->want = EINA_TRUE;
|
|
|
|
|
|
|
|
snprintf(buf, PATH_MAX, DEST_DIR_PATH, g->zoom, x);
|
|
|
|
if(!ecore_file_exists(buf))
|
|
|
|
ecore_file_mkpath(buf);
|
|
|
|
|
|
|
|
snprintf(buf2, PATH_MAX, DEST_FILE_PATH, buf, y);
|
|
|
|
|
|
|
|
snprintf(buf, PATH_MAX, SOURCE_PATH,
|
2009-11-13 10:42:58 -08:00
|
|
|
g->zoom, x, y);
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-11-14 05:58:22 -08:00
|
|
|
if(gi->file)
|
|
|
|
eina_stringshare_del(gi->file);
|
|
|
|
gi->file = eina_stringshare_add(buf2);
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
if(ecore_file_exists(buf2) || g == eina_list_data_get(wd->grids))
|
|
|
|
{
|
2009-11-13 10:42:58 -08:00
|
|
|
gi->download = EINA_TRUE;
|
2009-11-13 07:22:23 -08:00
|
|
|
wd->preload_num++;
|
|
|
|
if (wd->preload_num == 1)
|
|
|
|
{
|
|
|
|
edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
|
|
|
|
"elm,state,busy,start", "elm");
|
|
|
|
evas_object_smart_callback_call(obj, "load,detail", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ecore_file_exists(buf2))
|
2009-11-14 07:30:03 -08:00
|
|
|
_tile_update(gi);
|
2009-11-13 07:22:23 -08:00
|
|
|
else
|
2009-11-13 09:34:20 -08:00
|
|
|
{
|
2009-11-15 07:53:37 -08:00
|
|
|
DBG("DOWNLOAD %s \t in %s", buf, buf2);
|
2009-11-14 05:58:22 -08:00
|
|
|
ecore_file_download(buf, buf2, _tile_downloaded, NULL, gi, &(gi->job));
|
2009-11-13 10:42:58 -08:00
|
|
|
if(!gi->job)
|
|
|
|
DBG("Can't start to download %s", buf);
|
2009-11-13 09:34:20 -08:00
|
|
|
}
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(gi->have)
|
|
|
|
evas_object_show(gi->img);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
grid_clearall(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Grid *g;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(wd->grids, g)
|
|
|
|
{
|
|
|
|
grid_clear(obj, g);
|
|
|
|
free(g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_smooth_update(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Eina_List *l;
|
|
|
|
Grid *g;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(wd->grids, l, g)
|
|
|
|
{
|
|
|
|
Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
evas_object_image_smooth_scale_set(gi->img, (wd->nosmooth == 0));
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
eina_iterator_free(it);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_grid_raise(Grid *g)
|
|
|
|
{
|
|
|
|
Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
|
|
|
g->wd->size.w = g->w;
|
|
|
|
g->wd->size.h = g->h;
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
|
|
|
{
|
|
|
|
Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
evas_object_raise(gi->img);
|
2009-11-15 07:53:37 -08:00
|
|
|
//evas_object_raise(gi->txt);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
eina_iterator_free(it);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static int
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_timeout(void *data)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
wd->nosmooth--;
|
|
|
|
if (wd->nosmooth == 0) _smooth_update(data);
|
|
|
|
wd->scr_timer = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
if (!wd->scr_timer)
|
|
|
|
{
|
|
|
|
wd->nosmooth++;
|
|
|
|
if (wd->nosmooth == 1) _smooth_update(data);
|
|
|
|
}
|
|
|
|
if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
|
|
|
|
wd->scr_timer = ecore_timer_add(0.5, _scr_timeout, data);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static int
|
2009-11-13 07:22:23 -08:00
|
|
|
zoom_do(Evas_Object *obj, double t)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord xx, yy, ow, oh;
|
|
|
|
|
2009-11-15 15:10:31 -08:00
|
|
|
if(t>1.0) t = 1.0;
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
wd->size.w = (wd->size.ow * (1.0 - t)) + (wd->size.nw * t);
|
|
|
|
wd->size.h = (wd->size.oh * (1.0 - t)) + (wd->size.nh * t);
|
|
|
|
|
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &ow, &oh);
|
|
|
|
|
2009-11-15 13:36:44 -08:00
|
|
|
if(wd->center_on.enabled)
|
|
|
|
{
|
|
|
|
elm_map_utils_convert_geo_into_coord(wd->center_on.lon, wd->center_on.lat, wd->size.w, &xx, &yy);
|
|
|
|
xx -= ow / 2;
|
2009-11-17 07:55:59 -08:00
|
|
|
yy -= oh / 2;
|
2009-11-15 13:36:44 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
|
|
|
|
yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
|
|
|
|
}
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
if (xx < 0) xx = 0;
|
|
|
|
else if (xx > (wd->size.w - ow)) xx = wd->size.w - ow;
|
|
|
|
if (yy < 0) yy = 0;
|
|
|
|
else if (yy > (wd->size.h - oh)) yy = wd->size.h - oh;
|
|
|
|
|
2009-11-17 07:44:11 -08:00
|
|
|
wd->show.show = EINA_TRUE;
|
|
|
|
wd->show.x = xx;
|
|
|
|
wd->show.y = yy;
|
|
|
|
wd->show.w = ow;
|
|
|
|
wd->show.h = oh;
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
if (wd->calc_job) ecore_job_del(wd->calc_job);
|
|
|
|
wd->calc_job = ecore_job_add(_calc_job, wd);
|
|
|
|
if (t >= 1.0)
|
2009-11-15 13:36:44 -08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2009-11-13 07:22:23 -08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static int
|
2009-11-13 07:22:23 -08:00
|
|
|
_zoom_anim(void *data)
|
|
|
|
{
|
|
|
|
Evas_Object *obj = data;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
double t;
|
|
|
|
int go;
|
|
|
|
|
|
|
|
t = ecore_loop_time_get();
|
|
|
|
if (t >= wd->t_end)
|
|
|
|
t = 1.0;
|
|
|
|
else if (wd->t_end > wd->t_start)
|
|
|
|
t = (t - wd->t_start) / (wd->t_end - wd->t_start);
|
|
|
|
else
|
|
|
|
t = 1.0;
|
|
|
|
t = 1.0 - t;
|
|
|
|
t = 1.0 - (t * t);
|
|
|
|
go = zoom_do(obj, t);
|
|
|
|
if (!go)
|
|
|
|
{
|
|
|
|
wd->nosmooth--;
|
|
|
|
if (wd->nosmooth == 0) _smooth_update(data);
|
|
|
|
wd->zoom_animator = NULL;
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,stop", NULL);
|
|
|
|
}
|
|
|
|
return go;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static int
|
2009-11-13 07:22:23 -08:00
|
|
|
_long_press(void *data)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
wd->long_timer = NULL;
|
|
|
|
wd->longpressed = EINA_TRUE;
|
|
|
|
evas_object_smart_callback_call(data, "longpressed", NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
Evas_Event_Mouse_Down *ev = event_info;
|
|
|
|
if (ev->button != 1) return;
|
|
|
|
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
|
|
|
|
else wd->on_hold = EINA_FALSE;
|
|
|
|
if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
|
|
|
|
evas_object_smart_callback_call(data, "clicked,double", NULL);
|
|
|
|
else
|
|
|
|
evas_object_smart_callback_call(data, "press", NULL);
|
|
|
|
wd->longpressed = EINA_FALSE;
|
|
|
|
if (wd->long_timer) ecore_timer_del(wd->long_timer);
|
|
|
|
wd->long_timer = ecore_timer_add(1.0, _long_press, data);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
Evas_Event_Mouse_Up *ev = event_info;
|
|
|
|
if (ev->button != 1) return;
|
|
|
|
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
|
|
|
|
else wd->on_hold = EINA_FALSE;
|
|
|
|
if (wd->long_timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(wd->long_timer);
|
|
|
|
wd->long_timer = NULL;
|
|
|
|
}
|
|
|
|
if (!wd->on_hold)
|
|
|
|
evas_object_smart_callback_call(data, "clicked", NULL);
|
|
|
|
wd->on_hold = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-11-13 14:22:05 -08:00
|
|
|
static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_NULL;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_del_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
if (wd->calc_job) ecore_job_del(wd->calc_job);
|
|
|
|
if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
|
|
|
|
if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
|
|
|
|
if (wd->long_timer) ecore_timer_del(wd->long_timer);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
free(wd);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 14:22:05 -08:00
|
|
|
_del_pre_hook(Evas_Object *obj)
|
|
|
|
{
|
2009-11-15 07:53:37 -08:00
|
|
|
Marker_Group *group;
|
|
|
|
Elm_Map_Marker *marker;
|
2009-12-18 06:28:36 -08:00
|
|
|
Eina_Matrixsparse *matrix;
|
2009-11-15 07:53:37 -08:00
|
|
|
int i;
|
|
|
|
Eina_Bool free_marker = EINA_TRUE;
|
2009-12-18 06:28:36 -08:00
|
|
|
Eina_List *l;
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-13 14:22:05 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
grid_clearall(obj);
|
2009-11-15 08:24:02 -08:00
|
|
|
|
2009-12-07 10:05:04 -08:00
|
|
|
for (i=0; i<19; i++)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
if(!wd->markers[i])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Eina_Iterator *it = eina_matrixsparse_iterator_new(wd->markers[i]);
|
|
|
|
Eina_Matrixsparse_Cell *cell;
|
|
|
|
|
|
|
|
EINA_ITERATOR_FOREACH(it, cell)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
l = eina_matrixsparse_cell_data_get(cell);
|
|
|
|
EINA_LIST_FREE(l, group)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
EINA_LIST_FREE(group->markers, marker)
|
|
|
|
{
|
|
|
|
evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
|
|
_bubble_sc_hits_changed_cb, group);
|
|
|
|
if(free_marker)
|
|
|
|
free(marker);
|
|
|
|
}
|
|
|
|
free(group);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
2009-12-18 06:28:36 -08:00
|
|
|
free_marker = EINA_FALSE;
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
2009-12-18 06:28:36 -08:00
|
|
|
eina_iterator_free(it);
|
|
|
|
eina_matrixsparse_free(wd->markers[i]);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
2009-11-13 14:22:05 -08:00
|
|
|
evas_object_del(wd->pan_smart);
|
|
|
|
wd->pan_smart = NULL;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_theme_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_smart_scroller_theme_set(wd->scr, "map", "base", elm_widget_style_get(obj));
|
2009-11-13 07:22:23 -08:00
|
|
|
edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
|
|
|
|
_sizing_eval(obj);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_sizing_eval(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
|
|
|
|
|
|
|
|
evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
|
|
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
|
|
evas_object_size_hint_max_set(obj, maxw, maxh);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_calc_job(void *data)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = data;
|
|
|
|
Evas_Coord minw, minh;
|
|
|
|
|
|
|
|
minw = wd->size.w;
|
|
|
|
minh = wd->size.h;
|
|
|
|
|
|
|
|
if (wd->resized)
|
|
|
|
{
|
|
|
|
wd->resized = 0;
|
2009-11-15 15:10:31 -08:00
|
|
|
if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
double tz = wd->zoom;
|
|
|
|
wd->zoom = 0.0;
|
2009-11-15 15:10:31 -08:00
|
|
|
elm_map_zoom_set(wd->obj, tz);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((minw != wd->minw) || (minh != wd->minh))
|
|
|
|
{
|
|
|
|
wd->minw = minw;
|
|
|
|
wd->minh = minh;
|
|
|
|
evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
|
|
|
|
_sizing_eval(wd->obj);
|
|
|
|
}
|
|
|
|
wd->calc_job = NULL;
|
|
|
|
evas_object_smart_changed(wd->pan_smart);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
|
|
|
|
sd->wd->pan_x = x;
|
|
|
|
sd->wd->pan_y = y;
|
|
|
|
evas_object_smart_changed(obj);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (x) *x = sd->wd->pan_x;
|
|
|
|
if (y) *y = sd->wd->pan_y;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
Evas_Coord ow, oh;
|
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
|
|
|
|
ow = sd->wd->minw - ow;
|
|
|
|
if (ow < 0) ow = 0;
|
|
|
|
oh = sd->wd->minh - oh;
|
|
|
|
if (oh < 0) oh = 0;
|
|
|
|
if (x) *x = ow;
|
|
|
|
if (y) *y = oh;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (w) *w = sd->wd->minw;
|
|
|
|
if (h) *h = sd->wd->minh;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_add(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Pan *sd;
|
|
|
|
Evas_Object_Smart_Clipped_Data *cd;
|
|
|
|
|
|
|
|
_pan_sc.add(obj);
|
|
|
|
cd = evas_object_smart_data_get(obj);
|
|
|
|
sd = calloc(1, sizeof(Pan));
|
|
|
|
if (!sd) return;
|
|
|
|
sd->__clipped_data = *cd;
|
|
|
|
free(cd);
|
|
|
|
evas_object_smart_data_set(obj, sd);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_del(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (!sd) return;
|
|
|
|
_pan_sc.del(obj);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
Evas_Coord ow, oh;
|
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
|
|
|
|
if ((ow == w) && (oh == h)) return;
|
|
|
|
sd->wd->resized = 1;
|
|
|
|
if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
|
|
|
|
sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_pan_calculate(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Pan *sd = evas_object_smart_data_get(obj);
|
|
|
|
Evas_Coord ox, oy, ow, oh;
|
|
|
|
Eina_List *l;
|
|
|
|
Grid *g;
|
|
|
|
|
|
|
|
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
|
|
|
rect_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
|
|
|
|
EINA_LIST_FOREACH(sd->wd->grids, l, g)
|
|
|
|
{
|
|
|
|
grid_load(sd->wd->obj, g);
|
|
|
|
grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
|
2009-11-15 07:53:37 -08:00
|
|
|
marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_hold_on(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
elm_smart_scroller_hold_set(wd->scr, 1);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_hold_off(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
elm_smart_scroller_hold_set(wd->scr, 0);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_freeze_on(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
elm_smart_scroller_freeze_set(wd->scr, 1);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_freeze_off(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
elm_smart_scroller_freeze_set(wd->scr, 0);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_anim_start(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
evas_object_smart_callback_call(data, "scroll,anim,start", NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_anim_stop(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
evas_object_smart_callback_call(data, "scroll,anim,stop", NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_drag_start(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
2009-11-15 13:36:44 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
wd->center_on.enabled = EINA_FALSE;
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_smart_callback_call(data, "scroll,drag,start", NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_drag_stop(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
evas_object_smart_callback_call(data, "scroll,drag,stop", NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-13 07:22:23 -08:00
|
|
|
_scr_scroll(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
evas_object_smart_callback_call(data, "scroll", NULL);
|
|
|
|
}
|
|
|
|
|
2009-11-21 14:38:07 -08:00
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-21 14:38:07 -08:00
|
|
|
_group_object_create(Marker_Group *group)
|
|
|
|
{
|
|
|
|
if(group->obj) return ;
|
|
|
|
|
2009-12-18 09:00:01 -08:00
|
|
|
if(!group->wd->group_objs_notused)
|
|
|
|
{
|
|
|
|
group->obj = edje_object_add(evas_object_evas_get(group->wd->obj));
|
|
|
|
_elm_theme_set(group->obj, "map", "marker", elm_widget_style_get(group->wd->obj));
|
|
|
|
|
|
|
|
evas_object_smart_member_add(group->obj,
|
|
|
|
group->wd->pan_smart);
|
|
|
|
elm_widget_sub_object_add(group->wd->obj, group->obj);
|
2009-11-21 14:38:07 -08:00
|
|
|
|
2009-12-18 09:00:01 -08:00
|
|
|
group->wd->group_objs_used = eina_list_append(group->wd->group_objs_used, group->obj);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
group->obj = eina_list_data_get(group->wd->group_objs_notused);
|
|
|
|
group->wd->group_objs_used = eina_list_append(group->wd->group_objs_used, group->obj);
|
|
|
|
group->wd->group_objs_notused = eina_list_remove(group->wd->group_objs_notused, group->obj);
|
|
|
|
evas_object_show(group->obj);
|
|
|
|
}
|
2009-11-21 14:38:07 -08:00
|
|
|
|
|
|
|
edje_object_signal_callback_add(group->obj, "open", "elm", _group_open_cb, group);
|
|
|
|
edje_object_signal_callback_add(group->obj, "bringin", "elm", _group_bringin_cb, group);
|
2009-12-18 09:00:01 -08:00
|
|
|
|
2009-12-18 12:16:37 -08:00
|
|
|
group->update_nbelems = EINA_TRUE;
|
|
|
|
|
2009-11-21 14:38:07 -08:00
|
|
|
if(group->open)
|
|
|
|
_group_bubble_create(group);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-21 14:38:07 -08:00
|
|
|
_group_object_free(Marker_Group *group)
|
|
|
|
{
|
2009-12-18 09:00:01 -08:00
|
|
|
if(!group->obj) return ;
|
|
|
|
|
|
|
|
group->wd->group_objs_notused = eina_list_append(group->wd->group_objs_notused, group->obj);
|
|
|
|
group->wd->group_objs_used = eina_list_remove(group->wd->group_objs_used, group->obj);
|
|
|
|
evas_object_hide(group->obj);
|
|
|
|
|
|
|
|
edje_object_signal_callback_del(group->obj, "open", "elm", _group_open_cb);
|
|
|
|
edje_object_signal_callback_del(group->obj, "bringin", "elm", _group_bringin_cb);
|
|
|
|
|
2009-11-21 14:38:07 -08:00
|
|
|
group->obj = NULL;
|
|
|
|
_group_bubble_free(group);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 11:52:07 -08:00
|
|
|
_group_bubble_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
2009-11-15 08:24:02 -08:00
|
|
|
{
|
|
|
|
Marker_Group *group = data;
|
2009-11-15 13:36:44 -08:00
|
|
|
|
2009-11-15 08:24:02 -08:00
|
|
|
if(!evas_object_above_get(group->rect))
|
|
|
|
return ;
|
|
|
|
evas_object_raise(group->bubble);
|
|
|
|
evas_object_raise(group->sc);
|
|
|
|
evas_object_raise(group->rect);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_create(Marker_Group *group)
|
|
|
|
{
|
|
|
|
if(group->bubble) return ;
|
|
|
|
|
2009-11-22 02:15:12 -08:00
|
|
|
group->wd->opened_bubbles = eina_list_append(group->wd->opened_bubbles, group);
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
group->bubble = edje_object_add(evas_object_evas_get(group->obj));
|
|
|
|
_elm_theme_set(group->bubble, "map", "marker_bubble",
|
|
|
|
elm_widget_style_get(group->wd->obj));
|
|
|
|
evas_object_smart_member_add(group->bubble,
|
|
|
|
group->wd->obj);
|
|
|
|
elm_widget_sub_object_add(group->wd->obj, group->bubble);
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
_group_bubble_content_free(group);
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_content_update(group);
|
|
|
|
|
2009-11-15 08:24:02 -08:00
|
|
|
group->rect = evas_object_rectangle_add(evas_object_evas_get(group->obj));
|
|
|
|
evas_object_color_set(group->rect, 0, 0, 0, 0);
|
|
|
|
evas_object_repeat_events_set(group->rect, EINA_TRUE);
|
|
|
|
evas_object_smart_member_add(group->rect,
|
|
|
|
group->wd->obj);
|
|
|
|
elm_widget_sub_object_add(group->wd->obj, group->rect);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-11-15 11:52:07 -08:00
|
|
|
evas_object_event_callback_add(group->rect, EVAS_CALLBACK_MOUSE_UP, _group_bubble_mouse_up_cb, group);
|
2009-11-15 08:24:02 -08:00
|
|
|
|
|
|
|
_group_bubble_place(group);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
2009-11-16 13:32:33 -08:00
|
|
|
static void _bubble_sc_hits_changed_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
_group_bubble_place(data);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_content_update(Marker_Group *group)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Elm_Map_Marker *marker;
|
2009-11-18 13:07:01 -08:00
|
|
|
int i = 0;
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
if(!group->bubble) return ;
|
|
|
|
|
|
|
|
if(!group->sc)
|
|
|
|
{
|
|
|
|
group->sc = elm_scroller_add(group->bubble);
|
|
|
|
elm_scroller_content_min_limit(group->sc, EINA_FALSE, EINA_TRUE);
|
|
|
|
elm_scroller_policy_set(group->sc, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
|
|
|
|
elm_scroller_bounce_set(group->sc, EINA_TRUE, EINA_FALSE);
|
|
|
|
edje_object_part_swallow(group->bubble, "elm.swallow.content", group->sc);
|
|
|
|
evas_object_show(group->sc);
|
|
|
|
evas_object_smart_member_add(group->sc,
|
|
|
|
group->wd->obj);
|
|
|
|
elm_widget_sub_object_add(group->wd->obj, group->sc);
|
|
|
|
|
|
|
|
group->bx = elm_box_add(group->bubble);
|
|
|
|
evas_object_size_hint_align_set(group->bx, -1, -1);
|
|
|
|
evas_object_size_hint_weight_set(group->bx, 0.5, 0.5);
|
|
|
|
elm_box_horizontal_set(group->bx, EINA_TRUE);
|
|
|
|
evas_object_show(group->bx);
|
|
|
|
|
|
|
|
elm_scroller_content_set(group->sc, group->bx);
|
2009-11-17 07:55:59 -08:00
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
evas_object_event_callback_add(group->sc, EVAS_CALLBACK_RESIZE,
|
2009-11-16 13:32:33 -08:00
|
|
|
_bubble_sc_hits_changed_cb, group);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(group->markers, l, marker)
|
|
|
|
{
|
2009-11-18 13:07:01 -08:00
|
|
|
if(i>=group->wd->markers_max_num)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if(!marker->content && marker->clas->func.get)
|
2009-11-18 02:59:17 -08:00
|
|
|
marker->content = marker->clas->func.get(group->wd->obj, marker, marker->data);
|
2009-11-18 13:07:01 -08:00
|
|
|
else if(marker->content)
|
|
|
|
elm_box_unpack(group->bx, marker->content);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
if(marker->content)
|
2009-11-17 07:55:59 -08:00
|
|
|
elm_box_pack_end(group->bx, marker->content);
|
2009-11-18 13:07:01 -08:00
|
|
|
i++;
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_content_free(Marker_Group *group)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Elm_Map_Marker *marker;
|
|
|
|
|
|
|
|
if(!group->sc) return ;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(group->markers, l, marker)
|
|
|
|
{
|
2009-11-18 02:59:17 -08:00
|
|
|
if(marker->content && marker->clas->func.del)
|
|
|
|
marker->clas->func.del(group->wd->obj, marker, marker->data, marker->content);
|
2009-11-15 07:53:37 -08:00
|
|
|
else if(marker->content)
|
|
|
|
evas_object_del(marker->content);
|
2009-11-18 13:07:01 -08:00
|
|
|
marker->content = NULL;
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
evas_object_del(group->sc);
|
|
|
|
group->sc = NULL;
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_free(Marker_Group *group)
|
|
|
|
{
|
|
|
|
if(!group->bubble) return ;
|
2009-11-16 13:32:33 -08:00
|
|
|
|
2009-11-22 02:15:12 -08:00
|
|
|
group->wd->opened_bubbles = eina_list_remove(group->wd->opened_bubbles, group);
|
2009-11-18 13:07:01 -08:00
|
|
|
evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
2009-11-16 13:32:33 -08:00
|
|
|
_bubble_sc_hits_changed_cb, group);
|
2009-11-15 07:53:37 -08:00
|
|
|
evas_object_del(group->bubble);
|
2009-11-15 08:24:02 -08:00
|
|
|
evas_object_del(group->rect);
|
2009-11-15 07:53:37 -08:00
|
|
|
group->bubble = NULL;
|
|
|
|
_group_bubble_content_free(group);
|
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_bubble_place(Marker_Group *group)
|
|
|
|
{
|
2009-11-25 12:51:28 -08:00
|
|
|
Evas_Coord x, y, w;
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Coord xx, yy, ww, hh;
|
|
|
|
const char *s;
|
|
|
|
|
2009-11-16 13:32:33 -08:00
|
|
|
if(!group->bubble || !group->obj) return ;
|
|
|
|
|
|
|
|
evas_object_geometry_get(group->obj, &x, &y, &w, NULL);
|
|
|
|
edje_object_size_min_calc(group->bubble, NULL, &hh);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
s = edje_object_data_get(group->bubble, "size_w");
|
|
|
|
ww = atoi(s);
|
|
|
|
xx = x+w/2-ww/2;
|
|
|
|
yy = y-hh;
|
|
|
|
|
|
|
|
evas_object_move(group->bubble, xx, yy);
|
|
|
|
evas_object_resize(group->bubble, ww, hh);
|
|
|
|
evas_object_show(group->bubble);
|
2009-11-15 08:24:02 -08:00
|
|
|
|
|
|
|
evas_object_move(group->rect, xx, yy);
|
|
|
|
evas_object_resize(group->rect, ww, hh);
|
|
|
|
evas_object_show(group->rect);
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 11:52:07 -08:00
|
|
|
_group_bringin_cb(void *data, Evas_Object *obj, const char *emission, const char *soure)
|
2009-11-15 13:36:44 -08:00
|
|
|
{
|
2009-11-15 11:52:07 -08:00
|
|
|
Marker_Group *group = data;
|
2009-11-17 07:44:11 -08:00
|
|
|
Elm_Map_Marker *marker = eina_list_data_get(group->markers);
|
|
|
|
if(!marker) return ;
|
2009-11-15 11:52:07 -08:00
|
|
|
|
|
|
|
group->bringin = EINA_TRUE;
|
2009-11-17 07:44:11 -08:00
|
|
|
elm_map_geo_region_bring_in(group->wd->obj, marker->longitude, marker->latitude);
|
2009-11-15 11:52:07 -08:00
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-18 09:45:47 -08:00
|
|
|
static void
|
2009-11-15 07:53:37 -08:00
|
|
|
_group_open_cb(void *data, Evas_Object *obj, const char *emission, const char *soure)
|
|
|
|
{
|
|
|
|
Marker_Group *group = data;
|
|
|
|
|
2009-11-15 11:52:07 -08:00
|
|
|
if(group->bringin)
|
|
|
|
{
|
|
|
|
group->bringin = EINA_FALSE;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
if(group->bubble)
|
|
|
|
{
|
|
|
|
group->open = EINA_FALSE;
|
|
|
|
_group_bubble_free(group);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
group->open = EINA_TRUE;
|
|
|
|
_group_bubble_create(group);
|
|
|
|
}
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
/**
|
|
|
|
* Add a new Map object
|
|
|
|
*
|
|
|
|
* @param parent The parent object
|
|
|
|
* @return The new object or NULL if it cannot be created
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI Evas_Object *
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_add(Evas_Object *parent)
|
|
|
|
{
|
2009-11-15 07:53:37 -08:00
|
|
|
Evas_Object *obj, *o;
|
2009-11-13 07:22:23 -08:00
|
|
|
Evas *e;
|
|
|
|
Widget_Data *wd;
|
|
|
|
Evas_Coord minw, minh;
|
|
|
|
static Evas_Smart *smart = NULL;
|
2009-11-15 07:53:37 -08:00
|
|
|
const char *s;
|
|
|
|
|
2009-11-13 10:42:58 -08:00
|
|
|
if(!ecore_file_download_protocol_available("http://"))
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
|
|
|
ERR("Ecore must be built with the support of HTTP for the widget map !");
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-11-13 10:42:58 -08:00
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
wd = ELM_NEW(Widget_Data);
|
|
|
|
e = evas_object_evas_get(parent);
|
|
|
|
obj = elm_widget_add(e);
|
|
|
|
elm_widget_type_set(obj, "map");
|
|
|
|
elm_widget_sub_object_add(parent, obj);
|
|
|
|
elm_widget_data_set(obj, wd);
|
|
|
|
elm_widget_del_hook_set(obj, _del_hook);
|
2009-11-13 14:22:05 -08:00
|
|
|
elm_widget_del_pre_hook_set(obj, _del_pre_hook);
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_widget_theme_hook_set(obj, _theme_hook);
|
|
|
|
|
|
|
|
wd->scr = elm_smart_scroller_add(e);
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_smart_scroller_theme_set(wd->scr, "map", "base", "default");
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
|
|
|
|
evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
|
|
|
|
elm_widget_resize_object_set(obj, wd->scr);
|
|
|
|
|
|
|
|
evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
|
|
|
|
evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
|
|
|
|
evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
|
|
|
|
evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
|
|
|
|
evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
|
|
|
|
|
2009-11-17 07:55:59 -08:00
|
|
|
elm_smart_scroller_bounce_allow_set(wd->scr, 1, 1);
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
wd->obj = obj;
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
//load the minimum size of the marker group
|
|
|
|
o = edje_object_add(e);
|
|
|
|
_elm_theme_set(o, "map", "marker", elm_widget_style_get(obj));
|
|
|
|
s = edje_object_data_get(o, "size_w");
|
|
|
|
wd->marker_w = atoi(s);
|
|
|
|
s = edje_object_data_get(o, "size_h");
|
|
|
|
wd->marker_h = atoi(s);
|
|
|
|
s = edje_object_data_get(o, "size_max_w");
|
|
|
|
wd->marker_max_w = atoi(s);
|
|
|
|
s = edje_object_data_get(o, "size_max_h");
|
|
|
|
wd->marker_max_h = atoi(s);
|
|
|
|
evas_object_del(o);
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
wd->markers_max_num = 30;
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
|
|
|
|
evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
|
|
|
|
evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
|
|
|
|
evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
|
|
|
|
|
|
|
|
if (!smart)
|
|
|
|
{
|
|
|
|
static Evas_Smart_Class sc;
|
|
|
|
|
|
|
|
evas_object_smart_clipped_smart_set(&_pan_sc);
|
|
|
|
sc = _pan_sc;
|
|
|
|
sc.name = "elm_map_pan";
|
|
|
|
sc.version = EVAS_SMART_CLASS_VERSION;
|
|
|
|
sc.add = _pan_add;
|
|
|
|
sc.del = _pan_del;
|
|
|
|
sc.resize = _pan_resize;
|
|
|
|
sc.calculate = _pan_calculate;
|
|
|
|
smart = evas_smart_class_new(&sc);
|
|
|
|
}
|
|
|
|
if (smart)
|
|
|
|
{
|
|
|
|
wd->pan_smart = evas_object_smart_add(e, smart);
|
|
|
|
wd->pan = evas_object_smart_data_get(wd->pan_smart);
|
|
|
|
wd->pan->wd = wd;
|
|
|
|
}
|
|
|
|
|
|
|
|
elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
|
|
|
|
_pan_set, _pan_get,
|
|
|
|
_pan_max_get, _pan_child_size_get);
|
|
|
|
|
|
|
|
wd->rect = evas_object_rectangle_add(e);
|
|
|
|
evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_DOWN,
|
|
|
|
_mouse_down, obj);
|
|
|
|
evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_UP,
|
|
|
|
_mouse_up, obj);
|
|
|
|
evas_object_smart_member_add(wd->rect, wd->pan_smart);
|
|
|
|
elm_widget_sub_object_add(obj, wd->rect);
|
|
|
|
evas_object_show(wd->rect);
|
|
|
|
evas_object_color_set(wd->rect, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
wd->zoom = -1;
|
2009-11-15 15:10:31 -08:00
|
|
|
wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
|
2009-11-13 07:22:23 -08:00
|
|
|
|
|
|
|
wd->tsize = 256;
|
|
|
|
|
|
|
|
edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
|
|
|
|
&minw, &minh);
|
|
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
|
|
|
|
|
|
wd->paused = EINA_TRUE;
|
|
|
|
elm_map_zoom_set(obj, 0);
|
|
|
|
wd->paused = EINA_FALSE;
|
|
|
|
|
|
|
|
_sizing_eval(obj);
|
|
|
|
|
|
|
|
wd->calc_job = ecore_job_add(_calc_job, wd);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the zoom level of the map
|
|
|
|
*
|
2009-11-15 07:53:37 -08:00
|
|
|
* This sets the zoom level. 0 is the world map and 18 is the maximum zoom.
|
2009-11-13 07:22:23 -08:00
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param zoom The zoom level to set
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_zoom_set(Evas_Object *obj, int zoom)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Eina_List *l;
|
|
|
|
Grid *g, *g_zoom = NULL;
|
2009-11-25 12:51:28 -08:00
|
|
|
Evas_Coord rx, ry, rw, rh;
|
2009-11-13 07:22:23 -08:00
|
|
|
int z;
|
|
|
|
int zoom_changed = 0, started = 0;
|
|
|
|
|
|
|
|
if (zoom < 0 ) zoom = 0;
|
|
|
|
if (zoom > 18) zoom = 18;
|
|
|
|
if (zoom == wd->zoom) return;
|
|
|
|
|
|
|
|
wd->zoom = zoom;
|
|
|
|
wd->size.ow = wd->size.w;
|
|
|
|
wd->size.oh = wd->size.h;
|
|
|
|
elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
|
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
|
|
|
|
|
|
|
|
if (wd->mode == ELM_MAP_ZOOM_MODE_MANUAL)
|
|
|
|
{
|
|
|
|
wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
}
|
|
|
|
else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
|
|
|
|
{
|
|
|
|
int p2w, p2h;
|
|
|
|
int cumulw, cumulh;
|
|
|
|
|
|
|
|
cumulw = wd->tsize;
|
|
|
|
p2w = 0;
|
|
|
|
while(cumulw <= rw)
|
|
|
|
{
|
|
|
|
p2w++;
|
|
|
|
cumulw*=2;
|
|
|
|
}
|
|
|
|
p2w--;
|
|
|
|
|
|
|
|
cumulh = wd->tsize;
|
|
|
|
p2h = 0;
|
|
|
|
while(cumulh <= rh)
|
|
|
|
{
|
|
|
|
p2h++;
|
|
|
|
cumulh*=2;
|
|
|
|
}
|
|
|
|
p2h--;
|
|
|
|
|
|
|
|
if(p2w < p2h)
|
|
|
|
z = p2w;
|
|
|
|
else
|
|
|
|
z = p2h;
|
|
|
|
|
|
|
|
wd->zoom = z;
|
|
|
|
wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
}
|
|
|
|
else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
|
|
|
|
{
|
|
|
|
int p2w, p2h;
|
|
|
|
int cumulw, cumulh;
|
|
|
|
|
|
|
|
cumulw = wd->tsize;
|
|
|
|
p2w = 0;
|
|
|
|
while(cumulw <= rw)
|
|
|
|
{
|
|
|
|
p2w++;
|
|
|
|
cumulw*=2;
|
|
|
|
}
|
|
|
|
p2w--;
|
|
|
|
|
|
|
|
cumulh = wd->tsize;
|
|
|
|
p2h = 0;
|
|
|
|
while(cumulh <= rh)
|
|
|
|
{
|
|
|
|
p2h++;
|
|
|
|
cumulh*=2;
|
|
|
|
}
|
|
|
|
p2h--;
|
|
|
|
|
|
|
|
if(p2w > p2h)
|
|
|
|
z = p2w;
|
|
|
|
else
|
|
|
|
z = p2h;
|
|
|
|
|
|
|
|
wd->zoom = z;
|
|
|
|
wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(wd->grids, l, g)
|
|
|
|
{
|
|
|
|
if (g->zoom == wd->zoom)
|
|
|
|
{
|
|
|
|
wd->grids = eina_list_remove(wd->grids, g);
|
|
|
|
wd->grids = eina_list_prepend(wd->grids, g);
|
|
|
|
_grid_raise(g);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g = grid_create(obj);
|
|
|
|
if (g)
|
|
|
|
{
|
|
|
|
if (eina_list_count(wd->grids) > 1)
|
|
|
|
{
|
|
|
|
g_zoom = eina_list_last(wd->grids)->data;
|
|
|
|
wd->grids = eina_list_remove(wd->grids, g_zoom);
|
|
|
|
grid_clear(obj, g_zoom);
|
|
|
|
free(g_zoom);
|
|
|
|
}
|
|
|
|
wd->grids = eina_list_prepend(wd->grids, g);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EINA_LIST_FREE(wd->grids, g)
|
|
|
|
{
|
|
|
|
grid_clear(obj, g);
|
|
|
|
free(g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
|
|
|
|
wd->t_start = ecore_loop_time_get();
|
|
|
|
wd->t_end = wd->t_start + _elm_config->zoom_friction;
|
2009-11-15 15:10:31 -08:00
|
|
|
if ((wd->size.w > 0) && (wd->size.h > 0))
|
|
|
|
{
|
2009-11-17 07:44:11 -08:00
|
|
|
wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.ow;
|
|
|
|
wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.oh;
|
2009-11-15 15:10:31 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wd->size.spos.x = 0.5;
|
|
|
|
wd->size.spos.y = 0.5;
|
|
|
|
}
|
2009-11-17 07:44:11 -08:00
|
|
|
if (rw > wd->size.ow) wd->size.spos.x = 0.5;
|
|
|
|
if (rh > wd->size.oh) wd->size.spos.y = 0.5;
|
2009-11-15 15:10:31 -08:00
|
|
|
if (wd->size.spos.x > 1.0) wd->size.spos.x = 1.0;
|
|
|
|
if (wd->size.spos.y > 1.0) wd->size.spos.y = 1.0;
|
2009-11-13 07:22:23 -08:00
|
|
|
if (wd->paused)
|
|
|
|
{
|
|
|
|
zoom_do(obj, 1.0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!wd->zoom_animator)
|
|
|
|
{
|
|
|
|
wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
|
|
|
|
wd->nosmooth++;
|
|
|
|
if (wd->nosmooth == 1) _smooth_update(obj);
|
|
|
|
started = 1;
|
|
|
|
}
|
|
|
|
}
|
2009-11-14 07:30:03 -08:00
|
|
|
if (wd->zoom_animator)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
if (!_zoom_anim(obj))
|
|
|
|
{
|
2009-11-14 07:30:03 -08:00
|
|
|
ecore_animator_del(wd->zoom_animator);
|
|
|
|
wd->zoom_animator = NULL;
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (wd->calc_job) ecore_job_del(wd->calc_job);
|
|
|
|
wd->calc_job = ecore_job_add(_calc_job, wd);
|
|
|
|
if (!wd->paused)
|
|
|
|
{
|
|
|
|
if (started)
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,start", NULL);
|
2009-11-14 07:30:03 -08:00
|
|
|
if (!wd->zoom_animator)
|
2009-11-13 07:22:23 -08:00
|
|
|
evas_object_smart_callback_call(obj, "zoom,stop", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zoom_changed)
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,change", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the zoom level of the photo
|
|
|
|
*
|
|
|
|
* This returns the current zoom level of the map object. Note that if
|
|
|
|
* you set the fill mode to other than ELM_MAP_ZOOM_MODE_MANUAL
|
|
|
|
* (which is the default), the zoom level may be changed at any time by the
|
|
|
|
* map object itself to account for map size and map viewpoer size
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @return The current zoom level
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI double
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_zoom_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
return wd->zoom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the zoom mode
|
|
|
|
*
|
|
|
|
* This sets the zoom mode to manual or one of several automatic levels.
|
|
|
|
* Manual (ELM_MAP_ZOOM_MODE_MANUAL) means that zoom is set manually by
|
|
|
|
* elm_map_zoom_set() and will stay at that level until changed by code
|
|
|
|
* or until zoom mode is changed. This is the default mode.
|
|
|
|
* The Automatic modes will allow the map object to automatically
|
|
|
|
* adjust zoom mode based on properties. ELM_MAP_ZOOM_MODE_AUTO_FIT) will
|
|
|
|
* adjust zoom so the photo fits inside the scroll frame with no pixels
|
|
|
|
* outside this area. ELM_MAP_ZOOM_MODE_AUTO_FILL will be similar but
|
|
|
|
* ensure no pixels within the frame are left unfilled. Do not forget that the valid sizes are 2^zoom, consequently the map may be smaller than the scroller view.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param mode The desired mode
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (wd->mode == mode) return;
|
|
|
|
wd->mode = mode;
|
|
|
|
{
|
|
|
|
double tz = wd->zoom;
|
|
|
|
wd->zoom = 0.0;
|
|
|
|
elm_map_zoom_set(wd->obj, tz);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the zoom mode
|
|
|
|
*
|
|
|
|
* This gets the current zoom mode of the map object
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @return The current zoom mode
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI Elm_Map_Zoom_Mode
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_zoom_mode_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
return wd->mode;
|
|
|
|
}
|
|
|
|
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_utils_convert_geo_into_coord(lon, lat, wd->size.w, &rx, &ry);
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
|
|
|
|
|
|
|
|
rx = rx - rw/2;
|
|
|
|
ry = ry - rh/2;
|
|
|
|
|
|
|
|
if (wd->zoom_animator)
|
|
|
|
{
|
|
|
|
wd->nosmooth--;
|
|
|
|
if (wd->nosmooth == 0) _smooth_update(obj);
|
|
|
|
ecore_animator_del(wd->zoom_animator);
|
|
|
|
wd->zoom_animator = NULL;
|
|
|
|
zoom_do(obj, 1.0);
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,stop", NULL);
|
|
|
|
}
|
|
|
|
elm_smart_scroller_region_bring_in(wd->scr, rx, ry, rw, rh);
|
2009-11-15 13:36:44 -08:00
|
|
|
|
|
|
|
wd->center_on.enabled = EINA_TRUE;
|
|
|
|
wd->center_on.lon = lon;
|
|
|
|
wd->center_on.lat = lat;
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-11-15 07:53:37 -08:00
|
|
|
* Move the map to the current coordinates.
|
2009-11-13 07:22:23 -08:00
|
|
|
*
|
|
|
|
* This move the map to the current coordinates. The map will be centred on these coordinates.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param lat The latitude.
|
|
|
|
* @param lon The longitude.
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_utils_convert_geo_into_coord(lon, lat, wd->size.w, &rx, &ry);
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
|
|
|
|
|
|
|
|
rx = rx - rw/2;
|
|
|
|
ry = ry - rh/2;
|
|
|
|
|
|
|
|
if (wd->zoom_animator)
|
|
|
|
{
|
|
|
|
wd->nosmooth--;
|
|
|
|
ecore_animator_del(wd->zoom_animator);
|
|
|
|
wd->zoom_animator = NULL;
|
|
|
|
zoom_do(obj, 1.0);
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,stop", NULL);
|
|
|
|
}
|
|
|
|
elm_smart_scroller_child_region_show(wd->scr, rx, ry, rw, rh);
|
2009-11-15 13:36:44 -08:00
|
|
|
|
|
|
|
wd->center_on.enabled = EINA_TRUE;
|
|
|
|
wd->center_on.lon = lon;
|
|
|
|
wd->center_on.lat = lat;
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-11-15 07:53:37 -08:00
|
|
|
* Move the map to the current coordinates.
|
2009-11-13 07:22:23 -08:00
|
|
|
*
|
|
|
|
* This move the map to the current coordinates. The map will be centred on these coordinates.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param lat The latitude.
|
|
|
|
* @param lon The longitude.
|
|
|
|
*
|
|
|
|
* @ingroup Map
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_geo_region_get(Evas_Object *obj, double *lon, double *lat)
|
2009-11-13 07:22:23 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord sx, sy, sw, sh;
|
|
|
|
|
|
|
|
elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
|
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
|
|
|
|
sx += sw/2;
|
|
|
|
sy += sh/2;
|
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_utils_convert_coord_into_geo(sx, sy, wd->size.w, lon, lat);
|
2009-11-13 07:22:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the paused state for map
|
|
|
|
*
|
|
|
|
* This sets the paused state to on (1) or off (0) for map. The default
|
|
|
|
* is off. This will stop zooming using animation change zoom levels and
|
|
|
|
* change instantly. This will stop any existing animations that are running.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param paused The pause state to set
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (wd->paused == !!paused) return;
|
|
|
|
wd->paused = paused;
|
|
|
|
if (wd->paused)
|
|
|
|
{
|
|
|
|
if (wd->zoom_animator)
|
|
|
|
{
|
|
|
|
ecore_animator_del(wd->zoom_animator);
|
|
|
|
wd->zoom_animator = NULL;
|
|
|
|
zoom_do(obj, 1.0);
|
|
|
|
evas_object_smart_callback_call(obj, "zoom,stop", NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 13:28:06 -08:00
|
|
|
/**
|
|
|
|
* Set the paused state for the markers
|
|
|
|
*
|
|
|
|
* This sets the paused state to on (1) or off (0) for the markers. The default
|
|
|
|
* is off. This will stop displaying the markers during change zoom levels. Set
|
|
|
|
* to on if you have a large number of markers.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param paused The pause state to set
|
|
|
|
*/
|
|
|
|
EAPI void
|
|
|
|
elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (wd->paused_markers == !!paused) return;
|
|
|
|
wd->paused_markers = paused;
|
|
|
|
}
|
|
|
|
|
2009-11-13 07:22:23 -08:00
|
|
|
/**
|
|
|
|
* Get the paused state for map
|
|
|
|
*
|
|
|
|
* This gets the current paused state for the map object.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @return The current paused state
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI Eina_Bool
|
2009-11-13 07:22:23 -08:00
|
|
|
elm_map_paused_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
return wd->paused;
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-18 13:28:06 -08:00
|
|
|
/**
|
|
|
|
* Get the paused state for the markers
|
|
|
|
*
|
|
|
|
* This gets the current paused state for the markers object.
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @return The current paused state
|
|
|
|
*/
|
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_map_paused_markers_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
return wd->paused_markers;
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a pixel coordinate into a geographic coordinate.
|
|
|
|
*
|
|
|
|
* Convert a pixel coordinate (x,y) into a geographic coordinate (longitude, latitude).
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param x the coordinate
|
|
|
|
* @param y the coordinate
|
|
|
|
* @param size the size in pixels of the map. The map is a square and generally his size is : pow(2.0, zoom)*256.
|
|
|
|
* @param lon the longitude correspond to x
|
|
|
|
* @param lat the latitude correspond to y
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_utils_convert_coord_into_geo(int x, int y, int size, double *lon, double *lat)
|
|
|
|
{
|
|
|
|
if (lon)
|
|
|
|
{
|
|
|
|
*lon = x / (double)size * 360.0 - 180;
|
|
|
|
}
|
|
|
|
if (lat)
|
|
|
|
{
|
|
|
|
double n = ELM_PI - 2.0 * ELM_PI * y / size;
|
|
|
|
*lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a geographic coordinate into a pixel coordinate.
|
|
|
|
*
|
|
|
|
* Convert a geographic coordinate (longitude, latitude) into a pixel coordinate (x, y).
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param lon the longitude
|
|
|
|
* @param lat the latitude
|
|
|
|
* @param size the size in pixels of the map. The map is a square and generally his size is : pow(2.0, zoom)*256.
|
|
|
|
* @param x the coordinate correspond to the longitude
|
|
|
|
* @param y the coordinate correspond to the latitude
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-15 07:53:37 -08:00
|
|
|
elm_map_utils_convert_geo_into_coord(double lon, double lat, int size, int *x, int *y)
|
|
|
|
{
|
|
|
|
if(x)
|
|
|
|
*x = floor((lon + 180.0) / 360.0 * size);
|
|
|
|
if(y)
|
|
|
|
*y = floor((1.0 - log( tan(lat * ELM_PI/180.0) + 1.0 / cos(lat * ELM_PI/180.0)) / ELM_PI) / 2.0 * size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a marker on the map
|
|
|
|
*
|
|
|
|
* Add a marker on the map
|
|
|
|
*
|
|
|
|
* @param obj The map object
|
|
|
|
* @param lon the longitude
|
|
|
|
* @param lat the latitude
|
2009-11-18 02:59:17 -08:00
|
|
|
* @param clas the class to use
|
2009-11-15 07:53:37 -08:00
|
|
|
* @param data the data passed to the callbacks
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI Elm_Map_Marker *
|
2009-11-18 02:59:17 -08:00
|
|
|
elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, void *data)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
int i, j;
|
2009-11-17 07:44:11 -08:00
|
|
|
Eina_List *l;
|
2009-11-15 07:53:37 -08:00
|
|
|
Marker_Group *group;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-12-18 06:28:36 -08:00
|
|
|
int mpi, mpj;
|
|
|
|
int tabi[9];
|
|
|
|
int tabj[9];
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-07 10:05:04 -08:00
|
|
|
Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
|
2009-11-15 07:53:37 -08:00
|
|
|
|
|
|
|
marker->wd = wd;
|
2009-11-18 02:59:17 -08:00
|
|
|
marker->clas = clas;
|
2009-11-15 07:53:37 -08:00
|
|
|
marker->longitude = lon;
|
|
|
|
marker->latitude = lat;
|
|
|
|
marker->data = data;
|
|
|
|
|
2009-12-18 09:00:01 -08:00
|
|
|
tabi[1] = tabi[4] = tabi[6] = -1;
|
|
|
|
tabi[2] = tabi[0] = tabi[7] = 0;
|
|
|
|
tabi[3] = tabi[5] = tabi[8] = 1;
|
2009-12-18 09:45:47 -08:00
|
|
|
|
2009-12-18 09:00:01 -08:00
|
|
|
tabj[1] = tabj[2] = tabj[3] = -1;
|
|
|
|
tabj[4] = tabj[0] = tabj[5] = 0;
|
2009-12-18 06:28:36 -08:00
|
|
|
tabj[6] = tabj[7] = tabj[8] = 1;
|
|
|
|
|
2009-12-07 10:05:04 -08:00
|
|
|
for (i=0; i<=18; i++)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 10:24:56 -08:00
|
|
|
int sizew = wd->marker_w;
|
|
|
|
int sizeh = wd->marker_h;
|
2009-11-15 07:53:37 -08:00
|
|
|
if(sizew<=0) sizew = 2;
|
|
|
|
if(sizeh<=0) sizeh = 2;
|
|
|
|
if(sizew > wd->marker_max_w) sizew = wd->marker_max_w;
|
|
|
|
if(sizeh > wd->marker_max_h) sizeh = wd->marker_max_h;
|
|
|
|
|
|
|
|
elm_map_utils_convert_geo_into_coord(lon, lat, pow(2.0, i)*wd->tsize,
|
|
|
|
&(marker->x[i]), &(marker->y[i]));
|
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
//search in the matrixsparse the region where the marker will be
|
|
|
|
mpi = marker->x[i] / wd->tsize;
|
|
|
|
mpj = marker->y[i] / wd->tsize;
|
|
|
|
|
|
|
|
if(!wd->markers[i])
|
|
|
|
{
|
|
|
|
int size = pow(2.0, i);
|
|
|
|
wd->markers[i] = eina_matrixsparse_new(size, size, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(j=0, group=NULL; j<9 && !group; j++)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 09:45:47 -08:00
|
|
|
EINA_LIST_FOREACH(eina_matrixsparse_data_idx_get(wd->markers[i], mpj + tabj[j], mpi + tabi[j]),
|
2009-12-18 06:28:36 -08:00
|
|
|
l, group)
|
2009-11-15 07:53:37 -08:00
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
if(ELM_RECTS_INTERSECT( marker->x[i]-sizew/4, marker->y[i]-sizeh/4, sizew, sizeh,
|
|
|
|
group->x-group->w/4, group->y-group->h/4, group->w, group->h))
|
|
|
|
{
|
|
|
|
group->markers = eina_list_append(group->markers, marker);
|
2009-12-18 12:16:37 -08:00
|
|
|
group->update_nbelems = EINA_TRUE;
|
2009-11-17 07:55:59 -08:00
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
group->sum_x += marker->x[i];
|
|
|
|
group->sum_y += marker->y[i];
|
|
|
|
group->x = group->sum_x / eina_list_count(group->markers);
|
|
|
|
group->y = group->sum_y / eina_list_count(group->markers);
|
2009-11-17 07:55:59 -08:00
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
group->w = sizew + sizew/8. * eina_list_count(group->markers);
|
|
|
|
group->h = sizeh + sizew/8. * eina_list_count(group->markers);
|
|
|
|
if(group->w > wd->marker_max_w) group->w = wd->marker_max_w;
|
|
|
|
if(group->h > wd->marker_max_h) group->h = wd->marker_max_h;
|
2009-11-15 07:53:37 -08:00
|
|
|
|
2009-12-18 10:24:56 -08:00
|
|
|
if(group->bubble)
|
|
|
|
_group_bubble_content_update(group);
|
|
|
|
|
2009-12-18 06:28:36 -08:00
|
|
|
break;
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!group)
|
|
|
|
{
|
|
|
|
group = calloc(1, sizeof(Marker_Group));
|
|
|
|
group->wd = wd;
|
2009-11-17 07:44:11 -08:00
|
|
|
group->sum_x = marker->x[i];
|
|
|
|
group->sum_y = marker->y[i];
|
2009-11-15 07:53:37 -08:00
|
|
|
group->x = marker->x[i];
|
|
|
|
group->y = marker->y[i];
|
|
|
|
group->w = sizew;
|
|
|
|
group->h = sizeh;
|
2009-12-18 06:28:36 -08:00
|
|
|
|
2009-11-15 07:53:37 -08:00
|
|
|
group->markers = eina_list_append(group->markers, marker);
|
2009-12-18 12:16:37 -08:00
|
|
|
group->update_nbelems = EINA_TRUE;
|
2009-12-18 06:28:36 -08:00
|
|
|
|
|
|
|
eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
|
2009-12-18 13:28:06 -08:00
|
|
|
|
|
|
|
if(!group->cell)
|
|
|
|
{
|
|
|
|
Eina_List *l = eina_list_append(NULL, group);
|
|
|
|
eina_matrixsparse_data_idx_set(wd->markers[i], mpj, mpi, l);
|
|
|
|
eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_List *l = eina_matrixsparse_cell_data_get(group->cell);
|
|
|
|
l = eina_list_append(l, group);
|
|
|
|
eina_matrixsparse_cell_data_set(group->cell, l);
|
|
|
|
}
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
2009-11-18 13:07:01 -08:00
|
|
|
marker->groups[i] = group;
|
2009-11-15 07:53:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if(wd->grids)
|
|
|
|
{
|
|
|
|
Evas_Coord ox, oy, ow, oh;
|
|
|
|
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
|
|
|
marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
|
|
|
|
}
|
|
|
|
|
|
|
|
return marker;
|
|
|
|
}
|
|
|
|
|
2009-11-18 13:07:01 -08:00
|
|
|
/**
|
|
|
|
* Remove a marker from the map
|
|
|
|
*
|
|
|
|
* Remove a marker from the map
|
|
|
|
*
|
|
|
|
* @param marker The marker to remove
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_marker_remove(Elm_Map_Marker *marker)
|
|
|
|
{
|
|
|
|
int i;
|
2009-12-18 06:28:36 -08:00
|
|
|
Eina_List *groups;
|
2009-11-18 13:07:01 -08:00
|
|
|
Widget_Data *wd = marker->wd;
|
|
|
|
|
2009-12-07 10:05:04 -08:00
|
|
|
for (i=0; i<=18; i++)
|
2009-11-25 05:21:02 -08:00
|
|
|
{
|
|
|
|
marker->groups[i]->markers = eina_list_remove(marker->groups[i]->markers, marker);
|
|
|
|
if(eina_list_count(marker->groups[i]->markers) == 0)
|
|
|
|
{
|
2009-12-18 06:28:36 -08:00
|
|
|
groups = eina_matrixsparse_cell_data_get(marker->groups[i]->cell);
|
|
|
|
groups = eina_list_remove(groups, marker->groups[i]);
|
|
|
|
eina_matrixsparse_cell_data_set(marker->groups[i]->cell, groups);
|
|
|
|
|
2009-11-25 05:21:02 -08:00
|
|
|
_group_object_free(marker->groups[i]);
|
2009-11-25 12:37:53 -08:00
|
|
|
_group_bubble_free(marker->groups[i]);
|
2009-11-25 05:21:02 -08:00
|
|
|
free(marker->groups[i]);
|
|
|
|
}
|
2009-12-18 10:24:56 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int sizew = wd->marker_w;
|
|
|
|
int sizeh = wd->marker_h;
|
|
|
|
if(sizew<=0) sizew = 2;
|
|
|
|
if(sizeh<=0) sizeh = 2;
|
|
|
|
if(sizew > wd->marker_max_w) sizew = wd->marker_max_w;
|
|
|
|
if(sizeh > wd->marker_max_h) sizeh = wd->marker_max_h;
|
|
|
|
|
|
|
|
marker->groups[i]->sum_x -= marker->x[i];
|
|
|
|
marker->groups[i]->sum_y -= marker->y[i];
|
|
|
|
|
|
|
|
marker->groups[i]->x = marker->groups[i]->sum_x / eina_list_count(marker->groups[i]->markers);
|
|
|
|
marker->groups[i]->y = marker->groups[i]->sum_y / eina_list_count(marker->groups[i]->markers);
|
|
|
|
|
|
|
|
marker->groups[i]->w = sizew + sizew/8. * eina_list_count(marker->groups[i]->markers);
|
|
|
|
marker->groups[i]->h = sizeh + sizew/8. * eina_list_count(marker->groups[i]->markers);
|
|
|
|
if(marker->groups[i]->w > wd->marker_max_w) marker->groups[i]->w = wd->marker_max_w;
|
|
|
|
if(marker->groups[i]->h > wd->marker_max_h) marker->groups[i]->h = wd->marker_max_h;
|
|
|
|
}
|
2009-11-25 05:21:02 -08:00
|
|
|
}
|
2009-11-18 13:07:01 -08:00
|
|
|
|
|
|
|
if(marker->content && marker->clas->func.del)
|
|
|
|
marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
|
|
|
|
else if(marker->content)
|
|
|
|
evas_object_del(marker->content);
|
|
|
|
|
|
|
|
free(marker);
|
|
|
|
|
|
|
|
if(wd->grids)
|
|
|
|
{
|
|
|
|
Evas_Coord ox, oy, ow, oh;
|
|
|
|
evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
|
|
|
|
marker_place(wd->obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bring in the marker to the center
|
|
|
|
*
|
|
|
|
* Move the map to the coordinate of the marker.
|
|
|
|
*
|
|
|
|
* @param marker The marker where the map will be center.
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_marker_bring_in(Elm_Map_Marker *marker)
|
|
|
|
{
|
|
|
|
elm_map_geo_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show the marker to the center
|
|
|
|
*
|
|
|
|
* Move the map to the coordinate of the marker.
|
|
|
|
*
|
|
|
|
* @param marker The marker where the map will be center.
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_marker_show(Elm_Map_Marker *marker)
|
|
|
|
{
|
|
|
|
elm_map_geo_region_show(marker->wd->obj, marker->longitude, marker->latitude);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Move and zoom the map to display a list of marker.
|
|
|
|
*
|
|
|
|
* The map will be center on the center point of the markers in the list. Then the map will be zoom in order to fit the markers, the maximum zoom which allows to display all the markers is used.
|
|
|
|
*
|
|
|
|
* @param markers The list of markers (list of Elm_Map_Marker *)
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_markers_list_show(Eina_List *markers)
|
|
|
|
{
|
|
|
|
int zoom;
|
|
|
|
double lon, lat;
|
|
|
|
Eina_List *l;
|
|
|
|
Elm_Map_Marker *marker, *m_max_lon = NULL, *m_max_lat = NULL, *m_min_lon = NULL, *m_min_lat = NULL;
|
|
|
|
Evas_Coord rw, rh, xc, yc;
|
|
|
|
Widget_Data *wd;
|
|
|
|
|
|
|
|
if(!markers)
|
|
|
|
return;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(markers, l, marker)
|
|
|
|
{
|
|
|
|
wd = marker->wd;
|
|
|
|
|
|
|
|
if(!m_min_lon || marker->longitude < m_min_lon->longitude)
|
|
|
|
m_min_lon = marker;
|
|
|
|
|
|
|
|
if(!m_max_lon || marker->longitude > m_max_lon->longitude)
|
|
|
|
m_max_lon = marker;
|
|
|
|
|
|
|
|
if(!m_min_lat || marker->latitude > m_min_lat->latitude)
|
|
|
|
m_min_lat = marker;
|
|
|
|
|
|
|
|
if(!m_max_lat || marker->latitude < m_max_lat->latitude)
|
|
|
|
m_max_lat = marker;
|
|
|
|
}
|
|
|
|
|
|
|
|
lon = (m_max_lon->longitude - m_min_lon->longitude) / 2. + m_min_lon->longitude;
|
|
|
|
lat = (m_max_lat->latitude - m_min_lat->latitude) / 2. + m_min_lat->latitude;
|
|
|
|
|
|
|
|
elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
|
2009-12-07 10:05:04 -08:00
|
|
|
for (zoom = 18; zoom>=0; zoom--)
|
2009-11-18 13:07:01 -08:00
|
|
|
{
|
|
|
|
Evas_Coord size = pow(2.0, zoom)*wd->tsize;
|
|
|
|
elm_map_utils_convert_geo_into_coord(lon, lat, size, &xc, &yc);
|
|
|
|
|
|
|
|
if(m_min_lon->x[zoom] - wd->marker_max_w > xc-rw/2
|
|
|
|
&& m_min_lat->y[zoom] - wd->marker_max_h > yc-rh/2
|
|
|
|
&& m_max_lon->x[zoom] + wd->marker_max_w < xc+rw/2
|
|
|
|
&& m_max_lat->y[zoom] + wd->marker_max_h < yc+rh/2)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(zoom<0)
|
|
|
|
zoom = 0;
|
|
|
|
|
|
|
|
elm_map_geo_region_show(wd->obj, lon, lat);
|
|
|
|
elm_map_zoom_set(wd->obj, zoom);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the maximum numbers of markers display in a group.
|
|
|
|
*
|
|
|
|
* A group can have a long list of markers, consequently the creation of the content of the bubble can be very slow. In order to avoid this, a maximum number of items is displayed in a bubble. By default this number is 30.
|
|
|
|
*
|
|
|
|
* @param obj The map object.
|
|
|
|
* @param max The maximum numbers of items displayed in a bubble.
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
wd->markers_max_num = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the evas object getting from the ElmMapMarkerGetFunc callback
|
|
|
|
*
|
|
|
|
* @param marker The marker.
|
|
|
|
* @return Return the evas object if it exists, else NULL.
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI Evas_Object *
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_marker_object_get(Elm_Map_Marker *marker)
|
|
|
|
{
|
|
|
|
return marker->content;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the marker
|
|
|
|
*
|
|
|
|
* @param marker The marker.
|
|
|
|
*/
|
2009-12-18 09:45:47 -08:00
|
|
|
EAPI void
|
2009-11-18 13:07:01 -08:00
|
|
|
elm_map_marker_update(Elm_Map_Marker *marker)
|
|
|
|
{
|
|
|
|
if(marker->content)
|
|
|
|
{
|
|
|
|
if(marker->clas->func.del)
|
|
|
|
marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
|
|
|
|
else
|
|
|
|
evas_object_del(marker->content);
|
|
|
|
marker->content = NULL;
|
|
|
|
_group_bubble_content_update(marker->groups[marker->wd->zoom]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-21 14:38:07 -08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Close all opened bubbles
|
|
|
|
*
|
|
|
|
* @param The map object
|
|
|
|
*/
|
2009-12-07 10:05:04 -08:00
|
|
|
EAPI void
|
2009-11-21 14:38:07 -08:00
|
|
|
elm_map_bubbles_close(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Marker_Group *group;
|
|
|
|
Eina_List *l, *l_next;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH_SAFE(wd->opened_bubbles, l, l_next, group)
|
|
|
|
{
|
2009-11-22 02:15:12 -08:00
|
|
|
_group_bubble_free(group);
|
2009-11-21 14:38:07 -08:00
|
|
|
}
|
|
|
|
}
|
2009-11-18 13:07:01 -08:00
|
|
|
|